98 lines
2.3 KiB
Go
98 lines
2.3 KiB
Go
|
package supplier
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"github.com/Nerzal/gocloak/v11"
|
||
|
"github.com/google/uuid"
|
||
|
)
|
||
|
|
||
|
type KeycloakSupplier struct {
|
||
|
host string
|
||
|
realm string
|
||
|
username string
|
||
|
password string
|
||
|
}
|
||
|
|
||
|
func NewKeycloakSupplier(host, realm, username, password string) KeycloakSupplier {
|
||
|
return KeycloakSupplier{
|
||
|
host: host,
|
||
|
realm: realm,
|
||
|
username: username,
|
||
|
password: password,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type ScimClient struct {
|
||
|
Name string
|
||
|
Endpoint string
|
||
|
Username string
|
||
|
Password string
|
||
|
}
|
||
|
|
||
|
func (r *KeycloakSupplier) login(ctx context.Context) (gocloak.GoCloak, *gocloak.JWT, error) {
|
||
|
client := gocloak.NewClient(r.host, gocloak.SetAuthAdminRealms("admin/realms"), gocloak.SetAuthRealms("realms"))
|
||
|
token, err := client.LoginAdmin(ctx, r.username, r.password, r.realm)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
return client, token, nil
|
||
|
}
|
||
|
|
||
|
func (r *KeycloakSupplier) Reconcile(ctx context.Context, scim ScimClient) error {
|
||
|
client, token, err := r.login(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
var providerId string
|
||
|
components, err := client.GetComponents(ctx, token.AccessToken, r.realm)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
for _, v := range components {
|
||
|
if *v.ProviderType == "org.keycloak.storage.UserStorageProvider" && *v.ProviderID == "scim" && *v.Name == scim.Name {
|
||
|
providerId = *v.ID
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
realm, err := client.GetRealm(ctx, token.AccessToken, r.realm)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
pId := "scim"
|
||
|
pType := "org.keycloak.storage.UserStorageProvider"
|
||
|
component := gocloak.Component{
|
||
|
ID: &providerId,
|
||
|
ParentID: realm.ID,
|
||
|
Name: &scim.Name,
|
||
|
ProviderID: &pId,
|
||
|
ProviderType: &pType,
|
||
|
ComponentConfig: &map[string][]string{
|
||
|
"priority": {"0"},
|
||
|
"endpoint": {scim.Endpoint},
|
||
|
"content-type": {"application/json"},
|
||
|
"auth-mode": {"BASIC_AUTH"},
|
||
|
"auth-user": {scim.Username},
|
||
|
"auth-pass": {scim.Password},
|
||
|
"sync-import": {"false"},
|
||
|
"sync-import-action": {"CREATE_LOCAL"},
|
||
|
"propagation-user": {"true"},
|
||
|
"propagation-group": {"true"},
|
||
|
},
|
||
|
}
|
||
|
if providerId == "" {
|
||
|
providerId = uuid.NewString()
|
||
|
_, err = client.CreateComponent(ctx, token.AccessToken, r.realm, component)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
} else {
|
||
|
_, err = client.UpdateComponent(ctx, token.AccessToken, r.realm, component)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|