Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix linter errors #501

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
78 changes: 78 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4507,3 +4507,81 @@ func (g *GoCloak) GetUsersManagementPermissions(ctx context.Context, accessToken

return &result, nil
}

// CreateOrganization creates a new Organization
func (g *GoCloak) CreateOrganization(ctx context.Context, token, realm string, organization OrganizationRepresentation) (string, error) {
const errMessage = "could not create organization"

resp, err := g.GetRequestWithBearerAuth(ctx, token).
SetBody(organization).
Post(g.getAdminRealmURL(realm, "organizations"))

if err := checkForError(resp, err, errMessage); err != nil {
return "", err
}

return getID(resp), nil
}

// GetOrganizations returns a paginated list of organizations filtered according to the specified parameters
func (g *GoCloak) GetOrganizations(ctx context.Context, token, realm string, params GetOrganizationsParams) ([]*OrganizationRepresentation, error) {
const errMessage = "could not get organizations"

queryParams, err := GetQueryParams(params)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}

var result []*OrganizationRepresentation

resp, err := g.GetRequestWithBearerAuth(ctx, token).
SetQueryParams(queryParams).
SetResult(&result).
Get(g.getAdminRealmURL(realm, "organizations"))
if err := checkForError(resp, err, errMessage); err != nil {
return nil, err
}

return result, nil
}

// DeleteOrganization deletes the organization
func (g *GoCloak) DeleteOrganization(ctx context.Context, token, realm, idOfOrganization string) error {
const errMessage = "could not delete organization"

resp, err := g.GetRequestWithBearerAuth(ctx, token).
Delete(g.getAdminRealmURL(realm, "organizations", idOfOrganization))

return checkForError(resp, err, errMessage)
}

// GetOrganizationByID returns the organization representation of the organization with provided ID
func (g *GoCloak) GetOrganizationByID(ctx context.Context, token, realm, idOfOrganization string) (*OrganizationRepresentation, error) {
const errMessage = "could not find organization"
var result *OrganizationRepresentation

resp, err := g.GetRequestWithBearerAuth(ctx, token).
SetResult(&result).
Get(g.getAdminRealmURL(realm, "organizations", idOfOrganization))

if err := checkForError(resp, err, errMessage); err != nil {
return nil, err
}

return result, nil
}

// UpdateOrganization updates the given organization
func (g *GoCloak) UpdateOrganization(ctx context.Context, token, realm string, organization OrganizationRepresentation) error {
const errMessage = "could not update organization"

if NilOrEmpty(organization.ID) {
return errors.Wrap(errors.New("ID of an organization required"), errMessage)
}

resp, err := g.GetRequestWithBearerAuth(ctx, token).
SetBody(organization).
Put(g.getAdminRealmURL(realm, "organizations", PString(organization.ID)))

return checkForError(resp, err, errMessage)
}
158 changes: 158 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7112,3 +7112,161 @@ func Test_RevokeToken(t *testing.T) {
)
require.NoError(t, err, "Revoke failed")
}

// -----------
// Organizations
// -----------

func CreateOrganization(t *testing.T, client gocloak.GoCloakIface, name, alias, domain string) (func(), string) {
cfg := GetConfig(t)
token := GetAdminToken(t, client)

org := gocloak.OrganizationRepresentation{
Name: gocloak.StringP(name),
Alias: gocloak.StringP(alias),
Enable: gocloak.BoolP(true),
Description: gocloak.StringP("Just a test organization"),
Domains: &[]gocloak.OrganizationDomainRepresentation{
{
Name: gocloak.StringP(domain),
Verified: gocloak.BoolP(true),
},
},
}

orgID, err := client.CreateOrganization(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
org)

require.NoError(t, err, "CreateOrganization failed")

org.ID = &orgID
t.Logf("Created Organization: %+v", org)
tearDown := func() {
err := client.DeleteOrganization(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
orgID)
require.NoError(t, err, "DeleteOrganization")
}

return tearDown, orgID
}

func Test_CreateOrganization(t *testing.T) {
t.Parallel()
client := NewClientWithDebug(t)

tearDown, _ := CreateOrganization(t, client, "Test Inc", "test-inc", "test.com")
defer tearDown()
}

func Test_GetOrganizations(t *testing.T) {
t.Parallel()
cfg := GetConfig(t)
client := NewClientWithDebug(t)
token := GetAdminToken(t, client)

// Create two organizations
tearDown1, _ := CreateOrganization(t, client, "Test Inc", "test-inc", "test.com")
defer tearDown1()

tearDown2, _ := CreateOrganization(t, client, "Another Inc", "another-inc", "another.com")
defer tearDown2()

organizations, err := client.GetOrganizations(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloak.GetOrganizationsParams{})
require.NoError(t, err, "GetOrganizations failed")
t.Log(organizations)
}

func Test_GetOrganizationsByName(t *testing.T) {
t.Parallel()
cfg := GetConfig(t)
client := NewClientWithDebug(t)
token := GetAdminToken(t, client)

tearDown, _ := CreateOrganization(t, client, "Test Inc", "test-inc", "test.com")
defer tearDown()

organization, err := client.GetOrganizations(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloak.GetOrganizationsParams{
Search: gocloak.StringP("Test Inc"),
})
require.NoError(t, err, "GetOrganizationByName failed")
t.Log(organization)
}

func Test_GetOrganizationsByDomain(t *testing.T) {
t.Parallel()
cfg := GetConfig(t)
client := NewClientWithDebug(t)
token := GetAdminToken(t, client)

tearDown, _ := CreateOrganization(t, client, "Test Inc", "test-inc", "test.com")
defer tearDown()

organization, err := client.GetOrganizations(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloak.GetOrganizationsParams{
Search: gocloak.StringP("test-inc.org"),
})
require.NoError(t, err, "GetOrganizationByDomain failed")
t.Log(organization)
}

func Test_GetOrganizationByID(t *testing.T) {
t.Parallel()
cfg := GetConfig(t)
client := NewClientWithDebug(t)
token := GetAdminToken(t, client)

tearDown, orgID := CreateOrganization(t, client, "Test Inc", "test-inc", "test.com")
defer tearDown()

organization, err := client.GetOrganizationByID(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
orgID)
require.NoError(t, err, "GetOrganization failed")
t.Log(organization)
}

func Test_UpdateOrganization(t *testing.T) {
t.Parallel()
cfg := GetConfig(t)
client := NewClientWithDebug(t)
token := GetAdminToken(t, client)

tearDown, orgID := CreateOrganization(t, client, "Test Inc", "test-inc", "test.com")
defer tearDown()

organization, err := client.GetOrganizationByID(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
orgID)
require.NoError(t, err, "GetOrganizationByID failed")

organization.Enable = gocloak.BoolP(false)

err = client.UpdateOrganization(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
*organization)
require.NoError(t, err, "UpdateOrganization failed")
t.Log(organization)
}
10 changes: 10 additions & 0 deletions gocloak_iface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,9 @@ func TestStringerOmitEmpty(t *testing.T) {
&gocloak.RequestingPartyTokenOptions{},
&gocloak.RequestingPartyPermission{},
&gocloak.GetClientUserSessionsParams{},
&gocloak.GetOrganizationsParams{},
&gocloak.OrganizationDomainRepresentation{},
&gocloak.OrganizationRepresentation{},
}

for _, custom := range customs {
Expand Down
35 changes: 35 additions & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,38 @@ type GetClientUserSessionsParams struct {
Max *int `json:"max,string,omitempty"`
}

// GetOrganizationsParams represents the optional parameters for getting organizations
type GetOrganizationsParams struct {
BriefRepresentation *bool `json:"briefRepresentation,string,omitempty"`
Exact *bool `json:"exact,string,omitempty"`
First *int `json:"first,string,omitempty"`
Max *int `json:"max,string,omitempty"`
Q *string `json:"q,omitempty"`
Search *string `json:"search,omitempty"`
}

// OrganizationDomainRepresentation is a representation of an organization's domain
// v26: https://www.keycloak.org/docs-api/latest/rest-api/index.html#OrganizationOrganizationDomainRepresentation
type OrganizationDomainRepresentation struct {
Name *string `json:"name,omitempty"`
Verified *bool `json:"verified,omitempty"`
}

// OrganizationRepresentation is a representation of an organization
// v26: https://www.keycloak.org/docs-api/latest/rest-api/index.html#OrganizationRepresentation
type OrganizationRepresentation struct {
ID *string `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Alias *string `json:"alias,omitempty"`
Enable *bool `json:"enabled,omitempty"`
Description *string `json:"description,omitempty"`
RedirectURL *string `json:"redirectUrl,omitempty"`
Attributes *map[string][]string `json:"attributes,omitempty"`
Domains *[]OrganizationDomainRepresentation `json:"domains,omitempty"`
Members *[]string `json:"members,omitempty"`
IdentityProviders *[]string `json:"identityProviders,omitempty"`
}

// prettyStringStruct returns struct formatted into pretty string
func prettyStringStruct(t interface{}) string {
json, err := json.MarshalIndent(t, "", "\t")
Expand Down Expand Up @@ -1539,3 +1571,6 @@ func (v *CredentialRepresentation) String() string { return pre
func (v *RequiredActionProviderRepresentation) String() string { return prettyStringStruct(v) }
func (v *BruteForceStatus) String() string { return prettyStringStruct(v) }
func (v *GetClientUserSessionsParams) String() string { return prettyStringStruct(v) }
func (v *GetOrganizationsParams) String() string { return prettyStringStruct(v) }
func (v *OrganizationDomainRepresentation) String() string { return prettyStringStruct(v) }
func (v *OrganizationRepresentation) String() string { return prettyStringStruct(v) }