diff --git a/Gopkg.lock b/Gopkg.lock index 7486e5f27..416617ae1 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -18,10 +18,12 @@ version = "2020.01.04" [[projects]] - digest = "1:d89b022b7e25578e238f7e4683a29e4e8c7ae3845fc87f3a1a24e80ef9df0eeb" + branch = "CLOUDTRUST-2109_2_authorizationManagement" + digest = "1:e4d43bb60043e30360021c935023de833c33aa8ca6f50db17442117c9bb416e3" name = "github.com/cloudtrust/common-service" packages = [ ".", + "configuration", "database", "database/sqltypes", "errors", @@ -36,16 +38,15 @@ "tracking", ] pruneopts = "UT" - revision = "a378b70b4d40f96407e066b6d4fb17d70f29074c" - version = "v1.2.4" + revision = "87ee56cefd79af64f22a62473cbc2dd2cb8e9ed5" [[projects]] - digest = "1:d5e16a9936cbe85b7da69f39b28f3bce4a9cbc76c54b0cbd81bff38e0512b4c7" + branch = "CLOUDTRUST-2109_2_branch" + digest = "1:2da4d1d6434742a7d39c67d9b54705e2236ca8ed510648882331b2b51903d431" name = "github.com/cloudtrust/keycloak-client" packages = ["."] pruneopts = "UT" - revision = "ca765a03b1663c649927cdf982fdb4b4dac3be5a" - version = "v1.2.7" + revision = "323aac823c30bcf7af315ce139bc5c9d5741ad8e" [[projects]] digest = "1:910c5b111ca13127693df80a59be2c952ad97313626116c0c9895e7b588f2a29" @@ -138,7 +139,7 @@ version = "v1.3.3" [[projects]] - digest = "1:debcbc62c53851dab1fc881438a65449dd5ffa12f64f059fd6e32b938799513d" + digest = "1:e02b687ade0c19c038ecce3ea326d756519adc4bba1203a9e76d620b12354892" name = "github.com/google/flatbuffers" packages = ["go"] pruneopts = "UT" @@ -173,7 +174,7 @@ version = "v1.0.0" [[projects]] - digest = "1:c266355b17e65dc0128f4a9df906567b28e135b774e0b395aab3d748af0871e2" + digest = "1:9b73396bc7a21f88702fe3d314ca7860843c08f9c787bb47f008075f840df23d" name = "github.com/influxdata/influxdb" packages = [ "client/v2", @@ -181,8 +182,8 @@ "pkg/escape", ] pruneopts = "UT" - revision = "23bc63d43a8dc05f53afa46e3526ebb5578f3d88" - version = "v1.7.9" + revision = "f46f63d4e2d9684a2dd716594ab609ccd32f0a5b" + version = "v1.7.10" [[projects]] digest = "1:9ff22c26414baf7deaf74f2a788fe7b97666048bcbe346c52cfe823442abbdfb" @@ -311,12 +312,12 @@ version = "v1.0.5" [[projects]] - digest = "1:83d0e0f3f46dc86daf27e4d7c834c8c492db787c53c09d94183de7478db92142" + digest = "1:11118bd196646c6515fea3d6c43f66162833c6ae4939bfb229b9956d91c6cf17" name = "github.com/spf13/viper" packages = ["."] pruneopts = "UT" - revision = "4525543ce4fe90f7970f5e2cdc300b8ffc8c0582" - version = "v1.6.2" + revision = "b5bf975e5823809fb22c7644d008757f78a4259e" + version = "v1.4.0" [[projects]] digest = "1:8548c309c65a85933a625be5e7d52b6ac927ca30c56869fae58123b8a77a75e1" @@ -326,14 +327,6 @@ revision = "221dbe5ed46703ee255b1da0dec05086f5035f62" version = "v1.4.0" -[[projects]] - digest = "1:f4b32291cad5efac2bfdba89ccde6aa04618b62ce06c1a571da2dc4f3f2677fb" - name = "github.com/subosito/gotenv" - packages = ["."] - pruneopts = "UT" - revision = "2ef7124db659d49edac6aa459693a15ae36c671a" - version = "v1.2.0" - [[projects]] digest = "1:54bf58828a4074c2304fcc52f018eb19fc02d5853ebd5121817330792c776734" name = "github.com/uber/jaeger-client-go" @@ -387,7 +380,7 @@ "pbkdf2", ] pruneopts = "UT" - revision = "69ecbb4d6d5dab05e49161c6e77ea40a030884e1" + revision = "6ca56c2f2e2b26dc733347707d0e75d8eb050ee1" [[projects]] branch = "master" @@ -411,7 +404,7 @@ "publicsuffix", ] pruneopts = "UT" - revision = "6afb5195e5aab057fda82e27171243402346b0ad" + revision = "16171245cfb220d5317888b716d69c1fb4e7992b" [[projects]] branch = "master" @@ -426,11 +419,11 @@ [[projects]] branch = "master" - digest = "1:fea09edda033799f8e99ab9042bda910bf1e3bf088c03eaf2ba8aba3adbbc8bf" + digest = "1:72b7c210f8cfe1431d2f300fbf37f25e52aa77324b05ab6b698483054033803e" name = "golang.org/x/sys" packages = ["unix"] pruneopts = "UT" - revision = "9fbb57f87de9ccfe3a99d4e3270ce8a926ebba4f" + revision = "d101bd2416d505c0448a6ce8a282482678040a89" [[projects]] digest = "1:8d8faad6b12a3a4c819a3f9618cb6ee1fa1cfc33253abeeea8b55336721e3405" @@ -476,7 +469,7 @@ "go/types/typeutil", ] pruneopts = "UT" - revision = "b4207ef4930765bb7d8205504a8e9217f20be1dd" + revision = "1ace956b0e17ff85a6f9bdf6973af28a26234113" [[projects]] digest = "1:e0a1881f9e0564bebdeac98c75e59f07acdde6ed3a5396e0e613eaad31194866" @@ -517,14 +510,6 @@ revision = "e0f81be2f4064ea7aa7470e9daddd2dc8e8152c7" version = "v2.0.3" -[[projects]] - digest = "1:c4b5592c342f273e18de68e16957f536f6648f2e90c9d7ece653ac90c22079a9" - name = "gopkg.in/ini.v1" - packages = ["."] - pruneopts = "UT" - revision = "94291fffe2b14f4632ec0e67c1bfecfc1287a168" - version = "v1.51.1" - [[projects]] digest = "1:3c4aaca5a82adc021322f239e0cf3f46852bb0b18ae050d0feab2e9e4c527462" name = "gopkg.in/square/go-jose.v2" @@ -550,6 +535,7 @@ analyzer-version = 1 input-imports = [ "github.com/cloudtrust/common-service", + "github.com/cloudtrust/common-service/configuration", "github.com/cloudtrust/common-service/database", "github.com/cloudtrust/common-service/database/sqltypes", "github.com/cloudtrust/common-service/errors", diff --git a/Gopkg.toml b/Gopkg.toml index d3f35b2d5..f8c1249d8 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -27,11 +27,11 @@ [[constraint]] name = "github.com/cloudtrust/common-service" - version = "v1.2.4" + branch = "CLOUDTRUST-2109_2_authorizationManagement" [[constraint]] name = "github.com/cloudtrust/keycloak-client" - version = "v1.2.7" + branch = "CLOUDTRUST-2109_2_branch" [[constraint]] name = "github.com/go-kit/kit" diff --git a/api/event/fb/AdminEvent.go b/api/event/fb/AdminEvent.go index 8c9e24236..bc2ae9ce6 100644 --- a/api/event/fb/AdminEvent.go +++ b/api/event/fb/AdminEvent.go @@ -91,7 +91,7 @@ func (rcv *AdminEvent) DetailsLength() int { return 0 } -func (rcv *AdminEvent) ResourceType() ResourceType { +func (rcv *AdminEvent) ResourceType() int8 { o := flatbuffers.UOffsetT(rcv._tab.Offset(14)) if o != 0 { return rcv._tab.GetInt8(o + rcv._tab.Pos) @@ -99,11 +99,11 @@ func (rcv *AdminEvent) ResourceType() ResourceType { return 0 } -func (rcv *AdminEvent) MutateResourceType(n ResourceType) bool { +func (rcv *AdminEvent) MutateResourceType(n int8) bool { return rcv._tab.MutateInt8Slot(14, n) } -func (rcv *AdminEvent) OperationType() OperationType { +func (rcv *AdminEvent) OperationType() int8 { o := flatbuffers.UOffsetT(rcv._tab.Offset(16)) if o != 0 { return rcv._tab.GetInt8(o + rcv._tab.Pos) @@ -111,7 +111,7 @@ func (rcv *AdminEvent) OperationType() OperationType { return 0 } -func (rcv *AdminEvent) MutateOperationType(n OperationType) bool { +func (rcv *AdminEvent) MutateOperationType(n int8) bool { return rcv._tab.MutateInt8Slot(16, n) } diff --git a/api/management/api.go b/api/management/api.go index ccc752ead..79e9868df 100644 --- a/api/management/api.go +++ b/api/management/api.go @@ -5,7 +5,7 @@ import ( "regexp" "strconv" - "github.com/cloudtrust/keycloak-bridge/internal/dto" + "github.com/cloudtrust/common-service/configuration" internal "github.com/cloudtrust/keycloak-bridge/internal/messages" kc "github.com/cloudtrust/keycloak-client" ) @@ -277,7 +277,7 @@ func ConvertToKCGroup(group GroupRepresentation) kc.GroupRepresentation { } // ConvertToAPIAuthorizations creates a API authorization representation from an array of DB Authorization -func ConvertToAPIAuthorizations(authorizations []dto.Authorization) AuthorizationsRepresentation { +func ConvertToAPIAuthorizations(authorizations []configuration.Authorization) AuthorizationsRepresentation { var matrix = make(map[string]map[string]map[string]struct{}) for _, authz := range authorizations { @@ -309,8 +309,8 @@ func ConvertToAPIAuthorizations(authorizations []dto.Authorization) Authorizatio } // ConvertToDBAuthorizations creates an array of DB Authorization from an API AuthorizationsRepresentation -func ConvertToDBAuthorizations(realmID, groupID string, apiAuthorizations AuthorizationsRepresentation) []dto.Authorization { - var authorizations = []dto.Authorization{} +func ConvertToDBAuthorizations(realmID, groupName string, apiAuthorizations AuthorizationsRepresentation) []configuration.Authorization { + var authorizations = []configuration.Authorization{} if apiAuthorizations.Matrix == nil { return authorizations @@ -319,9 +319,9 @@ func ConvertToDBAuthorizations(realmID, groupID string, apiAuthorizations Author for action, u := range *apiAuthorizations.Matrix { if len(u) == 0 { var act = string(action) - authorizations = append(authorizations, dto.Authorization{ + authorizations = append(authorizations, configuration.Authorization{ RealmID: &realmID, - GroupName: &groupID, + GroupName: &groupName, Action: &act, }) continue @@ -331,9 +331,9 @@ func ConvertToDBAuthorizations(realmID, groupID string, apiAuthorizations Author if len(v) == 0 { var act = string(action) var targetRealm = string(targetRealmID) - authorizations = append(authorizations, dto.Authorization{ + authorizations = append(authorizations, configuration.Authorization{ RealmID: &realmID, - GroupName: &groupID, + GroupName: &groupName, Action: &act, TargetRealmID: &targetRealm, }) @@ -344,9 +344,9 @@ func ConvertToDBAuthorizations(realmID, groupID string, apiAuthorizations Author var act = string(action) var targetRealm = string(targetRealmID) var targetGroup = string(targetGroupName) - authorizations = append(authorizations, dto.Authorization{ + authorizations = append(authorizations, configuration.Authorization{ RealmID: &realmID, - GroupName: &groupID, + GroupName: &groupName, Action: &act, TargetRealmID: &targetRealm, TargetGroupName: &targetGroup, diff --git a/api/management/api_test.go b/api/management/api_test.go index a39769152..85dbb4793 100644 --- a/api/management/api_test.go +++ b/api/management/api_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/cloudtrust/keycloak-bridge/internal/dto" + "github.com/cloudtrust/common-service/configuration" kc "github.com/cloudtrust/keycloak-client" "github.com/stretchr/testify/assert" ) @@ -211,22 +211,22 @@ func TestConvertToAPIAuthorizations(t *testing.T) { var action2 = "action2" var any = "*" - var authorizations = []dto.Authorization{} + var authorizations = []configuration.Authorization{} - var authz1 = dto.Authorization{ + var authz1 = configuration.Authorization{ RealmID: &master, GroupName: &groupName2, Action: &action2, } - var authz2 = dto.Authorization{ + var authz2 = configuration.Authorization{ RealmID: &master, GroupName: &groupName2, Action: &action2, TargetRealmID: &any, } - var authz3 = dto.Authorization{ + var authz3 = configuration.Authorization{ RealmID: &master, GroupName: &groupName1, Action: &action, diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index f9a0968ca..63f0efe9d 100644 --- a/cmd/keycloakb/keycloak_bridge.go +++ b/cmd/keycloakb/keycloak_bridge.go @@ -14,6 +14,7 @@ import ( "syscall" "time" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database/sqltypes" "github.com/cloudtrust/common-service/healthcheck" @@ -101,9 +102,6 @@ func main() { // Configurations. var c = config(ctx, log.With(logger, "unit", "config")) var ( - // Component - authorizationConfigFile = c.GetString("authorization-file") - // Publishing httpAddrInternal = c.GetString("internal-http-host-port") httpAddrManagement = c.GetString("management-http-host-port") @@ -262,18 +260,6 @@ func main() { keycloakPublicURL = urls[0] } - // Authorization Manager - var authorizationManager security.AuthorizationManager - { - var err error - authorizationManager, err = security.NewAuthorizationManagerFromFile(commonKcAdaptor, logger, authorizationConfigFile) - - if err != nil { - logger.Error(ctx, "msg", "could not load authorizations", "error", err) - return - } - } - var sentryClient tracking.SentryTracking { var logger = log.With(logger, "unit", "sentry") @@ -382,6 +368,25 @@ func main() { healthChecker.AddDatabase("Users R/W", usersRwDBConn, healthCheckCacheDuration) healthChecker.AddHTTPEndpoint("Keycloak", keycloakConfig.AddrAPI, httpTimeout, 200, healthCheckCacheDuration) + // Authorization Manager + var authorizationManager security.AuthorizationManager + { + var authorizationLogger = log.With(logger, "svc", "authorization") + + var configurationReaderDBModule *configuration.ConfigurationReaderDBModule + { + configurationReaderDBModule = configuration.NewConfigurationReaderDBModule(configurationRoDBConn, authorizationLogger) + } + + var err error + authorizationManager, err = security.NewAuthorizationManager(configurationReaderDBModule, commonKcAdaptor, authorizationLogger) + + if err != nil { + logger.Error(ctx, "msg", "could not load authorizations", "error", err) + return + } + } + // Event service. var eventEndpoints = event.Endpoints{} { @@ -1010,7 +1015,6 @@ func config(ctx context.Context, logger log.Logger) *viper.Viper { // Component default. v.SetDefault("config-file", "./configs/keycloak_bridge.yml") - v.SetDefault("authorization-file", "./configs/authorization.json") // Log level v.SetDefault("log-level", "info") @@ -1132,9 +1136,7 @@ func config(ctx context.Context, logger log.Logger) *viper.Viper { // First level of override. pflag.String("config-file", v.GetString("config-file"), "The configuration file path can be relative or absolute.") - pflag.String("authorization-file", v.GetString("authorization-file"), "The authorization file path can be relative or absolute.") v.BindPFlag("config-file", pflag.Lookup("config-file")) - v.BindPFlag("authorization-file", pflag.Lookup("authorization-file")) pflag.Parse() // Bind ENV variables diff --git a/internal/dto/authorization.go b/internal/dto/authorization.go deleted file mode 100644 index 0ce0d628a..000000000 --- a/internal/dto/authorization.go +++ /dev/null @@ -1,10 +0,0 @@ -package dto - -// Authorization struct -type Authorization struct { - RealmID *string `json:"realm_id"` - GroupName *string `json:"group_id"` - Action *string `json:"action"` - TargetRealmID *string `json:"target_realm_id,omitempty"` - TargetGroupName *string `json:"target_group_name,omitempty"` -} diff --git a/internal/dto/configuration.go b/internal/dto/configuration.go deleted file mode 100644 index e7c3c3925..000000000 --- a/internal/dto/configuration.go +++ /dev/null @@ -1,18 +0,0 @@ -package dto - -// RealmConfiguration struct -type RealmConfiguration struct { - DefaultClientID *string `json:"default_client_id,omitempty"` - DefaultRedirectURI *string `json:"default_redirect_uri,omitempty"` - APISelfAuthenticatorDeletionEnabled *bool `json:"api_self_authenticator_deletion_enabled,omitempty"` - APISelfPasswordChangeEnabled *bool `json:"api_self_password_change_enabled,omitempty"` - APISelfMailEditingEnabled *bool `json:"api_self_mail_editing_enabled,omitempty"` - APISelfAccountDeletionEnabled *bool `json:"api_self_account_deletion_enabled,omitempty"` - ShowAuthenticatorsTab *bool `json:"show_authenticators_tab,omitempty"` - ShowPasswordTab *bool `json:"show_password_tab,omitempty"` - ShowMailEditing *bool `json:"show_mail_editing,omitempty"` - ShowAccountDeletionButton *bool `json:"show_account_deletion_button,omitempty"` - RegisterExecuteActions *[]string `json:"register_execute_actions,omitempty"` - RedirectCancelledRegistrationURL *string `json:"redirect_cancelled_registration_url,omitempty"` - RedirectSuccessfulRegistrationURL *string `json:"redirect_successful_registration_url,omitempty"` -} diff --git a/internal/keycloakb/authorizationutil.go b/internal/keycloakb/authorizationutil.go index ae16d7e38..962339961 100644 --- a/internal/keycloakb/authorizationutil.go +++ b/internal/keycloakb/authorizationutil.go @@ -3,12 +3,12 @@ package keycloakb import ( "errors" + "github.com/cloudtrust/common-service/configuration" api "github.com/cloudtrust/keycloak-bridge/api/management" - "github.com/cloudtrust/keycloak-bridge/internal/dto" ) // Validate the content of the provided array. Returns an error if any issue is detected -func Validate(authorizations []dto.Authorization, allowedTargetRealmsAndGroupNames map[string]map[string]struct{}) error { +func Validate(authorizations []configuration.Authorization, allowedTargetRealmsAndGroupNames map[string]map[string]struct{}) error { for _, auth := range authorizations { // Check TargetRealm if auth.TargetRealmID != nil { diff --git a/internal/keycloakb/authorizationutil_test.go b/internal/keycloakb/authorizationutil_test.go index 172ba49a6..927262e9c 100644 --- a/internal/keycloakb/authorizationutil_test.go +++ b/internal/keycloakb/authorizationutil_test.go @@ -3,7 +3,7 @@ package keycloakb import ( "testing" - "github.com/cloudtrust/keycloak-bridge/internal/dto" + "github.com/cloudtrust/common-service/configuration" "github.com/stretchr/testify/assert" ) @@ -24,12 +24,12 @@ func TestValidate(t *testing.T) { allowedTargetRealmsAndGroupNames[realmName][groupName2] = struct{}{} allowedTargetRealmsAndGroupNames[realmName]["*"] = struct{}{} - var authorizations = []dto.Authorization{} + var authorizations = []configuration.Authorization{} // Invalid targetRealm { - authorizations = []dto.Authorization{ - dto.Authorization{ + authorizations = []configuration.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action2, @@ -43,8 +43,8 @@ func TestValidate(t *testing.T) { // Invalid targetGroupName { - authorizations = []dto.Authorization{ - dto.Authorization{ + authorizations = []configuration.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action2, @@ -59,14 +59,14 @@ func TestValidate(t *testing.T) { // Incompatible rules due to * in targetRealm { - authorizations = []dto.Authorization{ - dto.Authorization{ + authorizations = []configuration.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action2, TargetRealmID: &star, }, - dto.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action2, @@ -80,15 +80,15 @@ func TestValidate(t *testing.T) { // Incompatible rules due to * in targetGroupName { - authorizations = []dto.Authorization{ - dto.Authorization{ + authorizations = []configuration.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action2, TargetRealmID: &realmName, TargetGroupName: &star, }, - dto.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action2, @@ -103,15 +103,15 @@ func TestValidate(t *testing.T) { // Valid set of authorizations { - authorizations = []dto.Authorization{ - dto.Authorization{ + authorizations = []configuration.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action2, TargetRealmID: &realmName, TargetGroupName: &star, }, - dto.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName1, Action: &action1, diff --git a/internal/keycloakb/configdbinstrumenting.go b/internal/keycloakb/configdbinstrumenting.go index 7e2ca38ce..e417b97c6 100644 --- a/internal/keycloakb/configdbinstrumenting.go +++ b/internal/keycloakb/configdbinstrumenting.go @@ -5,9 +5,9 @@ import ( "time" cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database" cm "github.com/cloudtrust/common-service/metrics" - "github.com/cloudtrust/keycloak-bridge/internal/dto" ) // Instrumenting middleware at module level. @@ -19,10 +19,10 @@ type configDBModuleInstrumentingMW struct { // ConfigurationDBModule is the interface of the configuration module. type ConfigurationDBModule interface { NewTransaction(context context.Context) (database.Transaction, error) - StoreOrUpdate(context.Context, string, dto.RealmConfiguration) error - GetConfiguration(context.Context, string) (dto.RealmConfiguration, error) - GetAuthorizations(context context.Context, realmID string, groupName string) ([]dto.Authorization, error) - CreateAuthorization(context context.Context, authz dto.Authorization) error + StoreOrUpdate(context.Context, string, configuration.RealmConfiguration) error + GetConfiguration(context.Context, string) (configuration.RealmConfiguration, error) + GetAuthorizations(context context.Context, realmID string, groupName string) ([]configuration.Authorization, error) + CreateAuthorization(context context.Context, authz configuration.Authorization) error DeleteAuthorizations(context context.Context, realmID string, groupName string) error DeleteAllAuthorizationsWithGroup(context context.Context, realmName, groupName string) error } @@ -46,7 +46,7 @@ func (m *configDBModuleInstrumentingMW) NewTransaction(ctx context.Context) (dat } // configDBModuleInstrumentingMW implements Module. -func (m *configDBModuleInstrumentingMW) StoreOrUpdate(ctx context.Context, realmName string, config dto.RealmConfiguration) error { +func (m *configDBModuleInstrumentingMW) StoreOrUpdate(ctx context.Context, realmName string, config configuration.RealmConfiguration) error { defer func(begin time.Time) { m.h.With("correlation_id", ctx.Value(cs.CtContextCorrelationID).(string)).Observe(time.Since(begin).Seconds()) }(time.Now()) @@ -54,7 +54,7 @@ func (m *configDBModuleInstrumentingMW) StoreOrUpdate(ctx context.Context, realm } // configDBModuleInstrumentingMW implements Module. -func (m *configDBModuleInstrumentingMW) GetConfiguration(ctx context.Context, realmName string) (dto.RealmConfiguration, error) { +func (m *configDBModuleInstrumentingMW) GetConfiguration(ctx context.Context, realmName string) (configuration.RealmConfiguration, error) { defer func(begin time.Time) { m.h.With("correlation_id", ctx.Value(cs.CtContextCorrelationID).(string)).Observe(time.Since(begin).Seconds()) }(time.Now()) @@ -62,7 +62,7 @@ func (m *configDBModuleInstrumentingMW) GetConfiguration(ctx context.Context, re } // configDBModuleInstrumentingMW implements Module. -func (m *configDBModuleInstrumentingMW) GetAuthorizations(ctx context.Context, realmID string, groupID string) ([]dto.Authorization, error) { +func (m *configDBModuleInstrumentingMW) GetAuthorizations(ctx context.Context, realmID string, groupID string) ([]configuration.Authorization, error) { defer func(begin time.Time) { m.h.With("correlation_id", ctx.Value(cs.CtContextCorrelationID).(string)).Observe(time.Since(begin).Seconds()) }(time.Now()) @@ -70,7 +70,7 @@ func (m *configDBModuleInstrumentingMW) GetAuthorizations(ctx context.Context, r } // configDBModuleInstrumentingMW implements Module. -func (m *configDBModuleInstrumentingMW) CreateAuthorization(ctx context.Context, auth dto.Authorization) error { +func (m *configDBModuleInstrumentingMW) CreateAuthorization(ctx context.Context, auth configuration.Authorization) error { defer func(begin time.Time) { m.h.With("correlation_id", ctx.Value(cs.CtContextCorrelationID).(string)).Observe(time.Since(begin).Seconds()) }(time.Now()) diff --git a/internal/keycloakb/configdbinstrumenting_test.go b/internal/keycloakb/configdbinstrumenting_test.go index 26bc65eff..472fc0eca 100644 --- a/internal/keycloakb/configdbinstrumenting_test.go +++ b/internal/keycloakb/configdbinstrumenting_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" - "github.com/cloudtrust/keycloak-bridge/internal/dto" - cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" + "github.com/cloudtrust/keycloak-bridge/internal/keycloakb/mock" "github.com/golang/mock/gomock" @@ -29,28 +29,28 @@ func TestComponentInstrumentingMW(t *testing.T) { var ctx = context.WithValue(context.Background(), cs.CtContextCorrelationID, corrID) // Get configuration. - mockComponent.EXPECT().GetConfiguration(ctx, "realmID").Return(dto.RealmConfiguration{}, nil).Times(1) + mockComponent.EXPECT().GetConfiguration(ctx, "realmID").Return(configuration.RealmConfiguration{}, nil).Times(1) mockHistogram.EXPECT().With("correlation_id", corrID).Return(mockHistogram).Times(1) mockHistogram.EXPECT().Observe(gomock.Any()).Return().Times(1) m.GetConfiguration(ctx, "realmID") // Get configuration without correlation ID. - mockComponent.EXPECT().GetConfiguration(context.Background(), "realmID").Return(dto.RealmConfiguration{}, nil).Times(1) + mockComponent.EXPECT().GetConfiguration(context.Background(), "realmID").Return(configuration.RealmConfiguration{}, nil).Times(1) var f = func() { m.GetConfiguration(context.Background(), "realmID") } assert.Panics(t, f) // Update configuration. - mockComponent.EXPECT().StoreOrUpdate(ctx, "realmID", dto.RealmConfiguration{}).Return(nil).Times(1) + mockComponent.EXPECT().StoreOrUpdate(ctx, "realmID", configuration.RealmConfiguration{}).Return(nil).Times(1) mockHistogram.EXPECT().With("correlation_id", corrID).Return(mockHistogram).Times(1) mockHistogram.EXPECT().Observe(gomock.Any()).Return().Times(1) - m.StoreOrUpdate(ctx, "realmID", dto.RealmConfiguration{}) + m.StoreOrUpdate(ctx, "realmID", configuration.RealmConfiguration{}) // Update configuration without correlation ID. - mockComponent.EXPECT().StoreOrUpdate(context.Background(), "realmID", dto.RealmConfiguration{}).Return(nil).Times(1) + mockComponent.EXPECT().StoreOrUpdate(context.Background(), "realmID", configuration.RealmConfiguration{}).Return(nil).Times(1) f = func() { - m.StoreOrUpdate(context.Background(), "realmID", dto.RealmConfiguration{}) + m.StoreOrUpdate(context.Background(), "realmID", configuration.RealmConfiguration{}) } assert.Panics(t, f) } diff --git a/internal/keycloakb/configdbmodule.go b/internal/keycloakb/configdbmodule.go index 47f1464e7..e624c4119 100644 --- a/internal/keycloakb/configdbmodule.go +++ b/internal/keycloakb/configdbmodule.go @@ -5,11 +5,11 @@ import ( "database/sql" "encoding/json" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database" "github.com/cloudtrust/common-service/database/sqltypes" errorhandler "github.com/cloudtrust/common-service/errors" "github.com/cloudtrust/common-service/log" - "github.com/cloudtrust/keycloak-bridge/internal/dto" msg "github.com/cloudtrust/keycloak-bridge/internal/messages" ) @@ -17,9 +17,8 @@ const ( updateConfigStmt = `INSERT INTO realm_configuration (realm_id, configuration) VALUES (?, ?) ON DUPLICATE KEY UPDATE configuration = ?;` - selectConfigStmt = `SELECT configuration FROM realm_configuration WHERE (realm_id = ?)` - selectAuthzStmt = `SELECT realm_id, group_name, action, target_realm_id, target_group_name FROM authorizations WHERE realm_id = ? AND group_name = ?;` - createAuthzStmt = `INSERT INTO authorizations (realm_id, group_name, action, target_realm_id, target_group_name) + selectAuthzStmt = `SELECT realm_id, group_name, action, target_realm_id, target_group_name FROM authorizations WHERE realm_id = ? AND group_name = ?;` + createAuthzStmt = `INSERT INTO authorizations (realm_id, group_name, action, target_realm_id, target_group_name) VALUES (?, ?, ?, ?, ?);` deleteAuthzStmt = `DELETE FROM authorizations WHERE realm_id = ? AND group_name = ?;` deleteAllAuthzWithGroupStmt = `DELETE FROM authorizations WHERE (realm_id = ? AND group_name = ?) OR (target_realm_id = ? AND target_group_name = ?);` @@ -31,6 +30,7 @@ type Scanner interface { } type configurationDBModule struct { + configuration.ConfigurationReaderDBModule db sqltypes.CloudtrustDB logger log.Logger } @@ -38,12 +38,13 @@ type configurationDBModule struct { // NewConfigurationDBModule returns a ConfigurationDB module. func NewConfigurationDBModule(db sqltypes.CloudtrustDB, logger log.Logger) ConfigurationDBModule { return &configurationDBModule{ - db: db, - logger: logger, + ConfigurationReaderDBModule: *configuration.NewConfigurationReaderDBModule(db, logger), + db: db, + logger: logger, } } -func (c *configurationDBModule) StoreOrUpdate(context context.Context, realmID string, config dto.RealmConfiguration) error { +func (c *configurationDBModule) StoreOrUpdate(context context.Context, realmID string, config configuration.RealmConfiguration) error { // transform customConfig object into JSON string configJSON, err := json.Marshal(config) if err != nil { @@ -55,29 +56,19 @@ func (c *configurationDBModule) StoreOrUpdate(context context.Context, realmID s return err } -func (c *configurationDBModule) GetConfiguration(context context.Context, realmID string) (dto.RealmConfiguration, error) { - var configJSON string - var config = dto.RealmConfiguration{} - row := c.db.QueryRow(selectConfigStmt, realmID) +func (c *configurationDBModule) GetConfiguration(ctx context.Context, realmID string) (configuration.RealmConfiguration, error) { + config, err := c.ConfigurationReaderDBModule.GetConfiguration(ctx, realmID) - switch err := row.Scan(&configJSON); err { - case sql.ErrNoRows: + if err == sql.ErrNoRows { return config, errorhandler.Error{ Status: 404, Message: ComponentName + "." + msg.MsgErrNotConfigured + "." + msg.RealmConfiguration + "." + realmID, } - - default: - if err != nil { - return config, err - } - - err = json.Unmarshal([]byte(configJSON), &config) - return config, err } + return config, err } -func (c *configurationDBModule) GetAuthorizations(ctx context.Context, realmID string, groupName string) ([]dto.Authorization, error) { +func (c *configurationDBModule) GetAuthorizations(ctx context.Context, realmID string, groupName string) ([]configuration.Authorization, error) { // Get Authorizations from DB rows, err := c.db.Query(selectAuthzStmt, realmID, groupName) if err != nil { @@ -86,8 +77,8 @@ func (c *configurationDBModule) GetAuthorizations(ctx context.Context, realmID s } defer rows.Close() - var authz dto.Authorization - var res = make([]dto.Authorization, 0) + var authz configuration.Authorization + var res = make([]configuration.Authorization, 0) for rows.Next() { authz, err = c.scanAuthorization(rows) if err != nil { @@ -100,7 +91,7 @@ func (c *configurationDBModule) GetAuthorizations(ctx context.Context, realmID s return res, nil } -func (c *configurationDBModule) CreateAuthorization(context context.Context, auth dto.Authorization) error { +func (c *configurationDBModule) CreateAuthorization(context context.Context, auth configuration.Authorization) error { _, err := c.db.Exec(createAuthzStmt, nullableString(auth.RealmID), nullableString(auth.GroupName), nullableString(auth.Action), nullableString(auth.TargetRealmID), nullableString(auth.TargetGroupName)) return err @@ -120,7 +111,7 @@ func (c *configurationDBModule) NewTransaction(context context.Context) (databas return database.NewTransaction(c.db) } -func (c *configurationDBModule) scanAuthorization(scanner Scanner) (dto.Authorization, error) { +func (c *configurationDBModule) scanAuthorization(scanner Scanner) (configuration.Authorization, error) { var ( realmID string groupName string @@ -131,10 +122,10 @@ func (c *configurationDBModule) scanAuthorization(scanner Scanner) (dto.Authoriz err := scanner.Scan(&realmID, &groupName, &action, &targetRealmID, &targetGroupName) if err != nil { - return dto.Authorization{}, err + return configuration.Authorization{}, err } - var authz = dto.Authorization{ + var authz = configuration.Authorization{ RealmID: &realmID, GroupName: &groupName, Action: &action, diff --git a/internal/keycloakb/configdbmodule_test.go b/internal/keycloakb/configdbmodule_test.go index 1e4b442d9..c4243628f 100644 --- a/internal/keycloakb/configdbmodule_test.go +++ b/internal/keycloakb/configdbmodule_test.go @@ -8,8 +8,9 @@ import ( "strings" "testing" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/log" - "github.com/cloudtrust/keycloak-bridge/internal/dto" + "github.com/cloudtrust/keycloak-bridge/internal/keycloakb/mock" msg "github.com/cloudtrust/keycloak-bridge/internal/messages" "github.com/golang/mock/gomock" @@ -24,7 +25,7 @@ func TestConfigurationDBModule(t *testing.T) { mockDB.EXPECT().Exec(gomock.Any(), "realmId", gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) var configDBModule = NewConfigurationDBModule(mockDB, mockLogger) - var err = configDBModule.StoreOrUpdate(context.Background(), "realmId", dto.RealmConfiguration{}) + var err = configDBModule.StoreOrUpdate(context.Background(), "realmId", configuration.RealmConfiguration{}) assert.Nil(t, err) } @@ -43,7 +44,7 @@ func TestGetConfiguration(t *testing.T) { { // No error var dummyURL = "dummy://path/to/nothing" - var expectedResult = dto.RealmConfiguration{DefaultRedirectURI: &dummyURL} + var expectedResult = configuration.RealmConfiguration{DefaultRedirectURI: &dummyURL} var jsonBytes, _ = json.Marshal(expectedResult) var json = string(jsonBytes) mockDB.EXPECT().QueryRow(gomock.Any(), realmID).Return(mockSQLRow) diff --git a/pkg/account/authorization.go b/pkg/account/authorization.go index 27b81c5b0..ec1de0d17 100644 --- a/pkg/account/authorization.go +++ b/pkg/account/authorization.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - "github.com/cloudtrust/keycloak-bridge/internal/dto" + "github.com/cloudtrust/common-service/configuration" cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/security" @@ -50,7 +50,7 @@ func (c *authorizationComponentMW) UpdatePassword(ctx context.Context, currentPa var action = UpdatePassword var currentRealm = ctx.Value(cs.CtContextRealm).(string) - var config = dto.RealmConfiguration{} + var config = configuration.RealmConfiguration{} var err error if config, err = c.configDBModule.GetConfiguration(ctx, currentRealm); err != nil { @@ -98,7 +98,7 @@ func (c *authorizationComponentMW) DeleteCredential(ctx context.Context, credent var action = DeleteCredential var currentRealm = ctx.Value(cs.CtContextRealm).(string) - var config = dto.RealmConfiguration{} + var config = configuration.RealmConfiguration{} var err error if config, err = c.configDBModule.GetConfiguration(ctx, currentRealm); err != nil { @@ -130,7 +130,7 @@ func (c *authorizationComponentMW) UpdateAccount(ctx context.Context, account ap var action = UpdateAccount var currentRealm = ctx.Value(cs.CtContextRealm).(string) - var config = dto.RealmConfiguration{} + var config = configuration.RealmConfiguration{} var err error if config, err = c.configDBModule.GetConfiguration(ctx, currentRealm); err != nil { @@ -158,7 +158,7 @@ func (c *authorizationComponentMW) DeleteAccount(ctx context.Context) error { var currentRealm = ctx.Value(cs.CtContextRealm).(string) var err error - var config = dto.RealmConfiguration{} + var config = configuration.RealmConfiguration{} if config, err = c.configDBModule.GetConfiguration(ctx, currentRealm); err != nil { infos, _ := json.Marshal(map[string]string{ diff --git a/pkg/account/authorization_test.go b/pkg/account/authorization_test.go index c323af2b4..9583d3143 100644 --- a/pkg/account/authorization_test.go +++ b/pkg/account/authorization_test.go @@ -6,10 +6,11 @@ import ( "testing" cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/log" "github.com/cloudtrust/common-service/security" api "github.com/cloudtrust/keycloak-bridge/api/account" - "github.com/cloudtrust/keycloak-bridge/internal/dto" + "github.com/cloudtrust/keycloak-bridge/pkg/account/mock" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" @@ -76,7 +77,7 @@ func TestDeny(t *testing.T) { var falseBool = false var credentialID = "786-5684-6464" - var realmConfig = dto.RealmConfiguration{ + var realmConfig = configuration.RealmConfiguration{ DefaultClientID: new(string), DefaultRedirectURI: new(string), APISelfAuthenticatorDeletionEnabled: &falseBool, @@ -124,7 +125,7 @@ func TestAllowed(t *testing.T) { var trueBool = true var credentialID = "786-5684-6464" - var realmConfig = dto.RealmConfiguration{ + var realmConfig = configuration.RealmConfiguration{ DefaultClientID: new(string), DefaultRedirectURI: new(string), APISelfAuthenticatorDeletionEnabled: &trueBool, @@ -176,7 +177,7 @@ func TestError(t *testing.T) { var credentialID = "786-5684-6464" - var realmConfig = dto.RealmConfiguration{} + var realmConfig = configuration.RealmConfiguration{} mockConfigurationDBModule.EXPECT().GetConfiguration(gomock.Any(), realmName).Return(realmConfig, errors.New("unexpected error")).AnyTimes() diff --git a/pkg/account/component.go b/pkg/account/component.go index f9ffaf5ce..9664154d3 100644 --- a/pkg/account/component.go +++ b/pkg/account/component.go @@ -7,6 +7,7 @@ import ( "strconv" cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database" errorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/account" @@ -46,10 +47,10 @@ type Component interface { // ConfigurationDBModule is the interface of the configuration module. type ConfigurationDBModule interface { NewTransaction(context context.Context) (database.Transaction, error) - StoreOrUpdate(context.Context, string, dto.RealmConfiguration) error - GetConfiguration(context.Context, string) (dto.RealmConfiguration, error) - GetAuthorizations(context context.Context, realmID string, groupID string) ([]dto.Authorization, error) - CreateAuthorization(context context.Context, authz dto.Authorization) error + StoreOrUpdate(context.Context, string, configuration.RealmConfiguration) error + GetConfiguration(context.Context, string) (configuration.RealmConfiguration, error) + GetAuthorizations(context context.Context, realmID string, groupID string) ([]configuration.Authorization, error) + CreateAuthorization(context context.Context, authz configuration.Authorization) error DeleteAuthorizations(context context.Context, realmID string, groupID string) error DeleteAllAuthorizationsWithGroup(context context.Context, realmID, groupName string) error } diff --git a/pkg/account/component_test.go b/pkg/account/component_test.go index 5511b4557..4466a548c 100644 --- a/pkg/account/component_test.go +++ b/pkg/account/component_test.go @@ -9,9 +9,8 @@ import ( "testing" "time" - "github.com/cloudtrust/keycloak-bridge/internal/dto" - cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database" "github.com/cloudtrust/common-service/log" account_api "github.com/cloudtrust/keycloak-bridge/api/account" @@ -20,6 +19,8 @@ import ( kc "github.com/cloudtrust/keycloak-client" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" + + "github.com/cloudtrust/keycloak-bridge/internal/dto" ) func TestUpdatePassword(t *testing.T) { @@ -718,7 +719,7 @@ func TestGetConfiguration(t *testing.T) { { var falseBool = false var trueBool = true - var config = dto.RealmConfiguration{ + var config = configuration.RealmConfiguration{ APISelfAuthenticatorDeletionEnabled: &falseBool, APISelfAccountDeletionEnabled: &falseBool, APISelfMailEditingEnabled: &falseBool, @@ -752,7 +753,7 @@ func TestGetConfiguration(t *testing.T) { var successURL = "https://success.io" var falseBool = false var trueBool = true - var config = dto.RealmConfiguration{ + var config = configuration.RealmConfiguration{ APISelfAuthenticatorDeletionEnabled: &falseBool, APISelfAccountDeletionEnabled: &falseBool, APISelfMailEditingEnabled: &falseBool, @@ -770,7 +771,7 @@ func TestGetConfiguration(t *testing.T) { ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, currentRealm).Return(config, nil).Times(1) - mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, overrideRealm).Return(dto.RealmConfiguration{ + mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, overrideRealm).Return(configuration.RealmConfiguration{ RedirectSuccessfulRegistrationURL: &successURL, }, nil).Times(1) @@ -790,7 +791,7 @@ func TestGetConfiguration(t *testing.T) { ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) - mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, currentRealm).Return(dto.RealmConfiguration{}, fmt.Errorf("Unexpected error")).Times(1) + mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, currentRealm).Return(configuration.RealmConfiguration{}, fmt.Errorf("Unexpected error")).Times(1) _, err := component.GetConfiguration(ctx, "") diff --git a/pkg/events/authorization_test.go b/pkg/events/authorization_test.go index f946af032..e41767c09 100644 --- a/pkg/events/authorization_test.go +++ b/pkg/events/authorization_test.go @@ -5,6 +5,7 @@ import ( "testing" cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/log" "github.com/cloudtrust/common-service/security" api "github.com/cloudtrust/keycloak-bridge/api/events" @@ -13,27 +14,40 @@ import ( "github.com/stretchr/testify/assert" ) -const ( - WithoutAuthorization = `{}` - WithAuthorization = `{ - "master": { - "toe": { - "EV_GetActions": {"*": {}}, - "EV_GetEvents": {"*": {"*": {} }}, - "EV_GetEventsSummary": {"*": {"*": {} }}, - "EV_GetUserEvents": {"*": {"*": {} }} - } - } - }` +var ( + WithoutAuthorization = []configuration.Authorization{} ) -func testAuthorization(t *testing.T, jsonAuthz string, tester func(Component, *mock.Component, context.Context, map[string]string)) { +func WithAuthorization() []configuration.Authorization { + var realmName = "master" + var toe = "toe" + var any = "*" + + var authorizations = []configuration.Authorization{} + for _, action := range actions { + var action = string(action.Name) + authorizations = append(authorizations, configuration.Authorization{ + RealmID: &realmName, + GroupName: &toe, + Action: &action, + TargetRealmID: &any, + TargetGroupName: &any, + }) + } + + return authorizations +} + +func testAuthorization(t *testing.T, authz []configuration.Authorization, tester func(Component, *mock.Component, context.Context, map[string]string)) { var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() var mockLogger = log.NewNopLogger() mockKeycloakClient := mock.NewKeycloakClient(mockCtrl) - var authorizations, err = security.NewAuthorizationManager(mockKeycloakClient, mockLogger, jsonAuthz) + var mockAuthorizationDBReader = mock.NewAuthorizationDBReader(mockCtrl) + mockAuthorizationDBReader.EXPECT().GetAuthorizations(gomock.Any()).Return(authz, nil) + + var authorizations, err = security.NewAuthorizationManager(mockAuthorizationDBReader, mockKeycloakClient, mockLogger) assert.Nil(t, err) mockEventsComponent := mock.NewComponent(mockCtrl) @@ -60,7 +74,7 @@ func testAuthorization(t *testing.T, jsonAuthz string, tester func(Component, *m } func TestGetActionsAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetActions(ctx).Return([]api.ActionRepresentation{}, nil).Times(1) _, err := auth.GetActions(ctx) assert.Nil(t, err) @@ -68,7 +82,7 @@ func TestGetActionsAllow(t *testing.T) { } func TestGetEventsAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetEvents(ctx, mp).Return(api.AuditEventsRepresentation{}, nil).Times(1) _, err := auth.GetEvents(ctx, mp) assert.Nil(t, err) @@ -83,7 +97,7 @@ func TestGetEventsDeny(t *testing.T) { } func TestGetEventsSummaryAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetEventsSummary(ctx).Return(api.EventSummaryRepresentation{}, nil).Times(1) _, err := auth.GetEventsSummary(ctx) assert.Nil(t, err) @@ -105,7 +119,7 @@ func TestGetEventsSummaryDeny(t *testing.T) { } func TestGetUserEventsAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetUserEvents(ctx, mp).Return(api.AuditEventsRepresentation{}, nil).Times(1) _, err := auth.GetUserEvents(ctx, mp) assert.Nil(t, err) diff --git a/pkg/events/mock_test.go b/pkg/events/mock_test.go index fed0b7db8..f0b4d5514 100644 --- a/pkg/events/mock_test.go +++ b/pkg/events/mock_test.go @@ -6,3 +6,4 @@ package events //go:generate mockgen -destination=./mock/dbevents.go -package=mock -mock_names=CloudtrustDB=DBEvents github.com/cloudtrust/common-service/database/sqltypes CloudtrustDB //go:generate mockgen -destination=./mock/writedb.go -package=mock -mock_names=EventsDBModule=WriteDBModule github.com/cloudtrust/common-service/database EventsDBModule //go:generate mockgen -destination=./mock/logger.go -package=mock -mock_names=Logger=Logger github.com/cloudtrust/keycloak-bridge/internal/keycloakb Logger +//go:generate mockgen -destination=./mock/authentication_db_reader.go -package=mock -mock_names=AuthorizationDBReader=AuthorizationDBReader github.com/cloudtrust/common-service/security AuthorizationDBReader diff --git a/pkg/management/authorization_test.go b/pkg/management/authorization_test.go index 3c66cbf6b..1058957b3 100644 --- a/pkg/management/authorization_test.go +++ b/pkg/management/authorization_test.go @@ -4,6 +4,8 @@ import ( "context" "testing" + "github.com/cloudtrust/common-service/configuration" + cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/log" "github.com/cloudtrust/common-service/security" @@ -20,6 +22,7 @@ func TestDeny(t *testing.T) { var mockLogger = log.NewNopLogger() var mockKeycloakClient = mock.NewKcClientAuth(mockCtrl) var mockManagementComponent = mock.NewManagementComponent(mockCtrl) + var mockAuthorizationDBReader = mock.NewAuthorizationDBReader(mockCtrl) var accessToken = "TOKEN==" var realmName = "master" @@ -44,6 +47,7 @@ func TestDeny(t *testing.T) { var clientURI = "https://wwww.cloudtrust.io" var provider = "provider" + mockAuthorizationDBReader.EXPECT().GetAuthorizations(gomock.Any()).Return([]configuration.Authorization{}, nil) mockKeycloakClient.EXPECT().GetGroupNamesOfUser(gomock.Any(), accessToken, realmName, userID).Return([]string{ groupName, @@ -86,7 +90,7 @@ func TestDeny(t *testing.T) { // Nothing allowed { - var authorizations, err = security.NewAuthorizationManager(mockKeycloakClient, log.NewNopLogger(), `{}`) + var authorizations, err = security.NewAuthorizationManager(mockAuthorizationDBReader, mockKeycloakClient, log.NewNopLogger()) assert.Nil(t, err) var authorizationMW = MakeAuthorizationManagementComponentMW(mockLogger, authorizations)(mockManagementComponent) @@ -219,6 +223,7 @@ func TestAllowed(t *testing.T) { var mockLogger = log.NewNopLogger() var mockKeycloakClient = mock.NewKcClientAuth(mockCtrl) var mockManagementComponent = mock.NewManagementComponent(mockCtrl) + var mockAuthorizationDBReader = mock.NewAuthorizationDBReader(mockCtrl) var accessToken = "TOKEN==" var realmName = "master" @@ -231,6 +236,8 @@ func TestAllowed(t *testing.T) { var userUsername = "toto" var roleName = "role" + var toe = "toe" + var any = "*" var groupID = "123-789-454" var groupIDs = []string{groupID} @@ -281,54 +288,25 @@ func TestAllowed(t *testing.T) { Username: &userUsername, } + var authorizations = []configuration.Authorization{} + for _, action := range actions { + var action = string(action.Name) + authorizations = append(authorizations, configuration.Authorization{ + RealmID: &realmName, + GroupName: &toe, + Action: &action, + TargetRealmID: &any, + TargetGroupName: &any, + }) + } + mockAuthorizationDBReader.EXPECT().GetAuthorizations(gomock.Any()).Return(authorizations, nil) + // Anything allowed { - var authorizations, err = security.NewAuthorizationManager(mockKeycloakClient, log.NewNopLogger(), `{"master": - { - "toe": { - "MGMT_GetActions": {"*": {}}, - "MGMT_GetRealms": {"*": {}}, - "MGMT_GetRealm": {"*": {"*": {} }}, - "MGMT_GetClient": {"*": {"*": {} }}, - "MGMT_GetClients": {"*": {"*": {} }}, - "MGMT_GetRequiredActions": {"*": {"*": {} }}, - "MGMT_DeleteUser": {"*": {"*": {} }}, - "MGMT_GetUser": {"*": {"*": {} }}, - "MGMT_UpdateUser": {"*": {"*": {} }}, - "MGMT_GetUsers": {"*": {"*": {} }}, - "MGMT_CreateUser": {"*": {"*": {} }}, - "MGMT_GetUserAccountStatus": {"*": {"*": {} }}, - "MGMT_GetRolesOfUser": {"*": {"*": {} }}, - "MGMT_GetGroupsOfUser": {"*": {"*": {} }}, - "MGMT_SetTrustIDGroups": {"*": {"*": {} }}, - "MGMT_GetClientRolesForUser": {"*": {"*": {} }}, - "MGMT_AddClientRolesToUser": {"*": {"*": {} }}, - "MGMT_ResetPassword": {"*": {"*": {} }}, - "MGMT_ExecuteActionsEmail": {"*": {"*": {} }}, - "MGMT_SendNewEnrolmentCode": {"*": {"*": {} }}, - "MGMT_SendReminderEmail": {"*": {"*": {} }}, - "MGMT_ResetSmsCounter": {"*": {"*": {} }}, - "MGMT_CreateRecoveryCode": {"*": {"*": {} }}, - "MGMT_GetCredentialsForUser": {"*": {"*": {} }}, - "MGMT_DeleteCredentialsForUser": {"*": {"*": {} }}, - "MGMT_GetRoles": {"*": {"*": {} }}, - "MGMT_GetRole": {"*": {"*": {} }}, - "MGMT_GetGroups": {"*": {"*": {} }}, - "MGMT_CreateGroup": {"*": {"*": {} }}, - "MGMT_DeleteGroup": {"*": {"*": {} }}, - "MGMT_GetAuthorizations": {"*": {"*": {} }}, - "MGMT_UpdateAuthorizations": {"*": {"*": {} }}, - "MGMT_GetClientRoles": {"*": {"*": {} }}, - "MGMT_CreateClientRole": {"*": {"*": {} }}, - "MGMT_GetRealmCustomConfiguration": {"*": {"*": {} }}, - "MGMT_UpdateRealmCustomConfiguration": {"*": {"*": {} }}, - "MGMT_CreateShadowUser": {"*": {"*": {} }} - } - } - }`) + var authorizationManager, err = security.NewAuthorizationManager(mockAuthorizationDBReader, mockKeycloakClient, log.NewNopLogger()) assert.Nil(t, err) - var authorizationMW = MakeAuthorizationManagementComponentMW(mockLogger, authorizations)(mockManagementComponent) + var authorizationMW = MakeAuthorizationManagementComponentMW(mockLogger, authorizationManager)(mockManagementComponent) var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) ctx = context.WithValue(ctx, cs.CtContextGroups, groups) diff --git a/pkg/management/component.go b/pkg/management/component.go index 25d96369f..e78a48e71 100644 --- a/pkg/management/component.go +++ b/pkg/management/component.go @@ -7,10 +7,10 @@ import ( "strings" cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database" errorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/management" - "github.com/cloudtrust/keycloak-bridge/internal/dto" "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" msg "github.com/cloudtrust/keycloak-bridge/internal/messages" kc "github.com/cloudtrust/keycloak-client" @@ -63,10 +63,10 @@ type KeycloakClient interface { // ConfigurationDBModule is the interface of the configuration module. type ConfigurationDBModule interface { NewTransaction(context context.Context) (database.Transaction, error) - StoreOrUpdate(context.Context, string, dto.RealmConfiguration) error - GetConfiguration(context.Context, string) (dto.RealmConfiguration, error) - GetAuthorizations(context context.Context, realmID string, groupID string) ([]dto.Authorization, error) - CreateAuthorization(context context.Context, authz dto.Authorization) error + StoreOrUpdate(context.Context, string, configuration.RealmConfiguration) error + GetConfiguration(context.Context, string) (configuration.RealmConfiguration, error) + GetAuthorizations(context context.Context, realmID string, groupID string) ([]configuration.Authorization, error) + CreateAuthorization(context context.Context, authz configuration.Authorization) error DeleteAuthorizations(context context.Context, realmID string, groupID string) error DeleteAllAuthorizationsWithGroup(context context.Context, realmID, groupName string) error } @@ -1261,7 +1261,7 @@ func (c *component) UpdateRealmCustomConfiguration(ctx context.Context, realmNam } // transform customConfig object into DTO - var config = dto.RealmConfiguration{ + var config = configuration.RealmConfiguration{ DefaultClientID: customConfig.DefaultClientID, DefaultRedirectURI: customConfig.DefaultRedirectURI, APISelfAuthenticatorDeletionEnabled: customConfig.APISelfAuthenticatorDeletionEnabled, diff --git a/pkg/management/component_test.go b/pkg/management/component_test.go index e6b9dbbbb..543ced32b 100644 --- a/pkg/management/component_test.go +++ b/pkg/management/component_test.go @@ -10,12 +10,13 @@ import ( "time" cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database" commonhttp "github.com/cloudtrust/common-service/errors" errorhandler "github.com/cloudtrust/common-service/errors" "github.com/cloudtrust/common-service/log" api "github.com/cloudtrust/keycloak-bridge/api/management" - "github.com/cloudtrust/keycloak-bridge/internal/dto" + "github.com/cloudtrust/keycloak-bridge/pkg/management/mock" kc "github.com/cloudtrust/keycloak-client" "github.com/golang/mock/gomock" @@ -2505,8 +2506,8 @@ func TestGetAuthorizations(t *testing.T) { // Get authorizations with succces { - var dtoAuthz = []dto.Authorization{ - dto.Authorization{ + var configurationAuthz = []configuration.Authorization{ + configuration.Authorization{ RealmID: &realmName, GroupName: &groupName, Action: &action, @@ -2517,7 +2518,7 @@ func TestGetAuthorizations(t *testing.T) { ctx = context.WithValue(ctx, cs.CtContextRealm, realmName) ctx = context.WithValue(ctx, cs.CtContextUsername, username) - mockConfigurationDBModule.EXPECT().GetAuthorizations(ctx, targetRealmname, groupName).Return(dtoAuthz, nil).Times(1) + mockConfigurationDBModule.EXPECT().GetAuthorizations(ctx, targetRealmname, groupName).Return(configurationAuthz, nil).Times(1) mockKeycloakClient.EXPECT().GetGroup(accessToken, targetRealmname, groupID).Return(group, nil).Times(1) apiAuthorizationRep, err := managementComponent.GetAuthorizations(ctx, targetRealmname, groupID) @@ -2537,7 +2538,7 @@ func TestGetAuthorizations(t *testing.T) { //Error when retrieving authorizations from DB { mockKeycloakClient.EXPECT().GetGroup(accessToken, targetRealmname, groupID).Return(group, nil).Times(1) - mockConfigurationDBModule.EXPECT().GetAuthorizations(gomock.Any(), targetRealmname, groupName).Return([]dto.Authorization{}, fmt.Errorf("Error")).Times(1) + mockConfigurationDBModule.EXPECT().GetAuthorizations(gomock.Any(), targetRealmname, groupName).Return([]configuration.Authorization{}, fmt.Errorf("Error")).Times(1) var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) mockLogger.EXPECT().Warn(ctx, "err", "Error") @@ -3107,7 +3108,7 @@ func TestGetRealmCustomConfiguration(t *testing.T) { var clientID = "ClientID" var redirectURI = "http://redirect.url.com/test" - var realmConfig = dto.RealmConfiguration{ + var realmConfig = configuration.RealmConfiguration{ DefaultClientID: &clientID, DefaultRedirectURI: &redirectURI, } @@ -3141,7 +3142,7 @@ func TestGetRealmCustomConfiguration(t *testing.T) { mockKeycloakClient.EXPECT().GetRealm(accessToken, realmID).Return(kcRealmRep, nil).Times(1) var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, realmID).Return(dto.RealmConfiguration{}, errorhandler.Error{}).Times(1) + mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, realmID).Return(configuration.RealmConfiguration{}, errorhandler.Error{}).Times(1) configJSON, err := managementComponent.GetRealmCustomConfiguration(ctx, realmID) @@ -3194,7 +3195,7 @@ func TestGetRealmCustomConfiguration(t *testing.T) { mockKeycloakClient.EXPECT().GetRealm(accessToken, realmID).Return(kcRealmRep, nil).Times(1) var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, realmID).Return(dto.RealmConfiguration{}, errors.New("error")).Times(1) + mockConfigurationDBModule.EXPECT().GetConfiguration(ctx, realmID).Return(configuration.RealmConfiguration{}, errors.New("error")).Times(1) _, err := managementComponent.GetRealmCustomConfiguration(ctx, realmID) diff --git a/pkg/management/mock_test.go b/pkg/management/mock_test.go index 4c2a59072..990d52f8b 100644 --- a/pkg/management/mock_test.go +++ b/pkg/management/mock_test.go @@ -8,3 +8,4 @@ package management //go:generate mockgen -destination=./mock/tracing.go -package=mock -mock_names=OpentracingClient=OpentracingClient,Finisher=Finisher github.com/cloudtrust/common-service/tracing OpentracingClient,Finisher //go:generate mockgen -destination=./mock/keycloak_client.go -package=mock -mock_names=KeycloakClient=KeycloakClient github.com/cloudtrust/keycloak-bridge/pkg/management KeycloakClient //go:generate mockgen -destination=./mock/database.go -package=mock -mock_names=Transaction=Transaction github.com/cloudtrust/common-service/database Transaction +//go:generate mockgen -destination=./mock/authentication_db_reader.go -package=mock -mock_names=AuthorizationDBReader=AuthorizationDBReader github.com/cloudtrust/common-service/security AuthorizationDBReader diff --git a/pkg/register/component.go b/pkg/register/component.go index 73ff05773..b7d9d700f 100644 --- a/pkg/register/component.go +++ b/pkg/register/component.go @@ -12,6 +12,7 @@ import ( "github.com/cloudtrust/keycloak-client" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/database" errorhandler "github.com/cloudtrust/common-service/errors" apiregister "github.com/cloudtrust/keycloak-bridge/api/register" @@ -31,7 +32,7 @@ type KeycloakClient interface { // ConfigurationDBModule is the interface of the configuration module. type ConfigurationDBModule interface { - GetConfiguration(context.Context, string) (dto.RealmConfiguration, error) + GetConfiguration(context.Context, string) (configuration.RealmConfiguration, error) } // Component is the register component interface. @@ -89,7 +90,7 @@ func (c *component) RegisterUser(ctx context.Context, clientRealmName string, us } // Get Realm configuration from database - var realmConf dto.RealmConfiguration + var realmConf configuration.RealmConfiguration realmConf, err = c.configDBModule.GetConfiguration(ctx, clientRealmName) if err != nil { c.logger.Info(ctx, "msg", "Can't get realm configuration from database", "err", err.Error()) @@ -124,7 +125,7 @@ func (c *component) RegisterUser(ctx context.Context, clientRealmName string, us return "", nil } -func (c *component) storeUser(ctx context.Context, accessToken string, user apiregister.UserRepresentation, existingKcUser *kc.UserRepresentation, realmConf dto.RealmConfiguration) (string, string, error) { +func (c *component) storeUser(ctx context.Context, accessToken string, user apiregister.UserRepresentation, existingKcUser *kc.UserRepresentation, realmConf configuration.RealmConfiguration) (string, string, error) { authToken, err := c.generateAuthToken() var userID string @@ -242,7 +243,7 @@ func (c *component) checkExistingUser(ctx context.Context, accessToken string, u func (c *component) GetConfiguration(ctx context.Context, realmName string) (apiregister.ConfigurationRepresentation, error) { // Get Realm configuration from database - var realmConf dto.RealmConfiguration + var realmConf configuration.RealmConfiguration realmConf, err := c.configDBModule.GetConfiguration(ctx, realmName) if err != nil { c.logger.Info(ctx, "msg", "Can't get realm configuration from database", "err", err.Error()) diff --git a/pkg/register/component_test.go b/pkg/register/component_test.go index 01c5e2783..f6bb35472 100644 --- a/pkg/register/component_test.go +++ b/pkg/register/component_test.go @@ -6,10 +6,10 @@ import ( "net/http" "testing" + "github.com/cloudtrust/common-service/configuration" errorhandler "github.com/cloudtrust/common-service/errors" log "github.com/cloudtrust/common-service/log" apiregister "github.com/cloudtrust/keycloak-bridge/api/register" - "github.com/cloudtrust/keycloak-bridge/internal/dto" "github.com/cloudtrust/keycloak-bridge/pkg/register/mock" kc "github.com/cloudtrust/keycloak-client" "github.com/golang/mock/gomock" @@ -74,7 +74,7 @@ func TestRegisterUser(t *testing.T) { t.Run("Can't get realm configuration from DB", func(t *testing.T) { var dbError = errors.New("db error") - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, dbError) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, dbError) var _, err = component.RegisterUser(ctx, confRealm, createValidUser()) assert.Equal(t, dbError, err) @@ -82,7 +82,7 @@ func TestRegisterUser(t *testing.T) { t.Run("Can't get access token", func(t *testing.T) { var tokenError = errors.New("token error") - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return("", tokenError) var _, err = component.RegisterUser(ctx, confRealm, createValidUser()) @@ -91,7 +91,7 @@ func TestRegisterUser(t *testing.T) { t.Run("checkExistingUser fails", func(t *testing.T) { var kcError = errors.New("kc GetUsers error") - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(accessToken, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(kc.UsersPageRepresentation{}, kcError) @@ -100,7 +100,7 @@ func TestRegisterUser(t *testing.T) { }) t.Run("Can't generate unused username", func(t *testing.T) { - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(accessToken, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(usersSearchResult, nil) mockKeycloakClient.EXPECT().CreateUser(accessToken, targetRealm, targetRealm, gomock.Any()). @@ -113,7 +113,7 @@ func TestRegisterUser(t *testing.T) { t.Run("Create user in Keycloak fails", func(t *testing.T) { var keycloakError = errors.New("keycloak create error") - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(accessToken, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(usersSearchResult, nil) mockKeycloakClient.EXPECT().CreateUser(accessToken, targetRealm, targetRealm, gomock.Any()).Return("", keycloakError) @@ -132,7 +132,7 @@ func TestRegisterUser(t *testing.T) { Count: &one, Users: []kc.UserRepresentation{user}, } - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(accessToken, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(userExistsSearch, nil) mockKeycloakClient.EXPECT().UpdateUser(accessToken, targetRealm, userID, gomock.Any()).Return(updateError) @@ -145,7 +145,7 @@ func TestRegisterUser(t *testing.T) { var insertError = errors.New("insert error") var token = "abcdef" var userID = "abc789def" - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(token, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(usersSearchResult, nil) mockKeycloakClient.EXPECT().CreateUser(token, targetRealm, targetRealm, gomock.Any()).Return(userID, nil) @@ -158,7 +158,7 @@ func TestRegisterUser(t *testing.T) { t.Run("No required actions. RegisterUser is successful", func(t *testing.T) { var token = "abcdef" var userID = "abc789def" - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(token, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(usersSearchResult, nil) mockKeycloakClient.EXPECT().CreateUser(token, targetRealm, targetRealm, gomock.Any()).Return(userID, nil) @@ -172,7 +172,7 @@ func TestRegisterUser(t *testing.T) { t.Run("Everything is ok but report event fails", func(t *testing.T) { var token = "abcdef" var userID = "abc789def" - mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(configuration.RealmConfiguration{}, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(token, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(usersSearchResult, nil) mockKeycloakClient.EXPECT().CreateUser(token, targetRealm, targetRealm, gomock.Any()).Return(userID, nil) @@ -188,7 +188,7 @@ func TestRegisterUser(t *testing.T) { var userID = "abc789def" var requiredActions = []string{"execute", "actions"} var successURL = "http://couldtrust.ch" - var realmConfiguration = dto.RealmConfiguration{RegisterExecuteActions: &requiredActions, RedirectSuccessfulRegistrationURL: &successURL} + var realmConfiguration = configuration.RealmConfiguration{RegisterExecuteActions: &requiredActions, RedirectSuccessfulRegistrationURL: &successURL} var component = NewComponent("not\nvalid\nURL", targetRealm, "", "", mockKeycloakClient, mockTokenProvider, mockUsersDB, mockConfigDB, mockEventsDB, log.NewNopLogger()) mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(realmConfiguration, nil) @@ -207,7 +207,7 @@ func TestRegisterUser(t *testing.T) { var userID = "abc789def" var requiredActions = []string{"execute", "actions"} var successURL = "http://couldtrust.ch" - var realmConfiguration = dto.RealmConfiguration{RegisterExecuteActions: &requiredActions, RedirectSuccessfulRegistrationURL: &successURL} + var realmConfiguration = configuration.RealmConfiguration{RegisterExecuteActions: &requiredActions, RedirectSuccessfulRegistrationURL: &successURL} mockConfigDB.EXPECT().GetConfiguration(ctx, confRealm).Return(realmConfiguration, nil) mockTokenProvider.EXPECT().ProvideToken(ctx).Return(token, nil) mockKeycloakClient.EXPECT().GetUsers(accessToken, targetRealm, targetRealm, "email", *validUser.EmailAddress).Return(usersSearchResult, nil) @@ -303,14 +303,14 @@ func TestGetConfiguration(t *testing.T) { t.Run("Retrieve configuration successfully", func(t *testing.T) { // Retrieve configuration successfully - mockConfigDB.EXPECT().GetConfiguration(gomock.Any(), gomock.Any()).Return(dto.RealmConfiguration{}, nil) + mockConfigDB.EXPECT().GetConfiguration(gomock.Any(), gomock.Any()).Return(configuration.RealmConfiguration{}, nil) var _, err = component.GetConfiguration(ctx, confRealm) assert.Nil(t, err) }) t.Run("Retrieve configuration in DB fails", func(t *testing.T) { // Retrieve configuration in DB fails - mockConfigDB.EXPECT().GetConfiguration(gomock.Any(), gomock.Any()).Return(dto.RealmConfiguration{}, errors.New("GetConfiguration fails")) + mockConfigDB.EXPECT().GetConfiguration(gomock.Any(), gomock.Any()).Return(configuration.RealmConfiguration{}, errors.New("GetConfiguration fails")) var _, err = component.GetConfiguration(ctx, confRealm) assert.NotNil(t, err) }) diff --git a/pkg/statistics/authorization_test.go b/pkg/statistics/authorization_test.go index dd1cfea5d..10e6c2632 100644 --- a/pkg/statistics/authorization_test.go +++ b/pkg/statistics/authorization_test.go @@ -5,6 +5,7 @@ import ( "testing" cs "github.com/cloudtrust/common-service" + "github.com/cloudtrust/common-service/configuration" "github.com/cloudtrust/common-service/log" "github.com/cloudtrust/common-service/security" api "github.com/cloudtrust/keycloak-bridge/api/statistics" @@ -13,29 +14,40 @@ import ( "github.com/stretchr/testify/assert" ) -const ( - WithoutAuthorization = `{}` - WithAuthorization = `{ - "master": { - "toe": { - "ST_GetActions": {"*": {}}, - "ST_GetStatistics": {"*": {"*": {} }}, - "ST_GetStatisticsUsers": {"*": {"*": {} }}, - "ST_GetStatisticsAuthenticators": {"*": {"*": {} }}, - "ST_GetStatisticsAuthentications": {"*": {"*": {} }}, - "ST_GetStatisticsAuthenticationsLog": {"*": {"*": {} }} - } - } - }` +var ( + WithoutAuthorization = []configuration.Authorization{} ) -func testAuthorization(t *testing.T, jsonAuthz string, tester func(Component, *mock.Component, context.Context, map[string]string)) { +func WithAuthorization() []configuration.Authorization { + var realmName = "master" + var toe = "toe" + var any = "*" + + var authorizations = []configuration.Authorization{} + for _, action := range actions { + var action = string(action.Name) + authorizations = append(authorizations, configuration.Authorization{ + RealmID: &realmName, + GroupName: &toe, + Action: &action, + TargetRealmID: &any, + TargetGroupName: &any, + }) + } + + return authorizations +} + +func testAuthorization(t *testing.T, authz []configuration.Authorization, tester func(Component, *mock.Component, context.Context, map[string]string)) { var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() var mockLogger = log.NewNopLogger() mockKeycloakClient := mock.NewKeycloakClient(mockCtrl) - var authorizations, err = security.NewAuthorizationManager(mockKeycloakClient, mockLogger, jsonAuthz) + var mockAuthorizationDBReader = mock.NewAuthorizationDBReader(mockCtrl) + mockAuthorizationDBReader.EXPECT().GetAuthorizations(gomock.Any()).Return(authz, nil) + + var authorizations, err = security.NewAuthorizationManager(mockAuthorizationDBReader, mockKeycloakClient, mockLogger) assert.Nil(t, err) mockComponent := mock.NewComponent(mockCtrl) @@ -62,7 +74,7 @@ func testAuthorization(t *testing.T, jsonAuthz string, tester func(Component, *m } func TestGetActionsAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetActions(ctx).Return([]api.ActionRepresentation{}, nil).Times(1) _, err := auth.GetActions(ctx) assert.Nil(t, err) @@ -70,14 +82,14 @@ func TestGetActionsAllow(t *testing.T) { } func TestGetStatisticsAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetStatistics(ctx, mp["realm"]).Return(api.StatisticsRepresentation{}, nil).Times(1) _, err := auth.GetStatistics(ctx, mp["realm"]) assert.Nil(t, err) }) } func TestGetStatisticsUsersAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetStatisticsUsers(ctx, mp["realm"]).Return(api.StatisticsUsersRepresentation{}, nil).Times(1) _, err := auth.GetStatisticsUsers(ctx, mp["realm"]) assert.Nil(t, err) @@ -85,7 +97,7 @@ func TestGetStatisticsUsersAllow(t *testing.T) { } func TestGetStatisticsAuthenticatorsAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetStatisticsAuthenticators(ctx, mp["realm"]).Return(map[string]int64{}, nil).Times(1) _, err := auth.GetStatisticsAuthenticators(ctx, mp["realm"]) assert.Nil(t, err) @@ -93,7 +105,7 @@ func TestGetStatisticsAuthenticatorsAllow(t *testing.T) { } func TestGetStatisticsAuthenticationsAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetStatisticsAuthentications(ctx, mp["realm"], mp["unit"], nil).Return([][]int64{}, nil).Times(1) _, err := auth.GetStatisticsAuthentications(ctx, mp["realm"], mp["unit"], nil) assert.Nil(t, err) @@ -101,7 +113,7 @@ func TestGetStatisticsAuthenticationsAllow(t *testing.T) { } func TestGetStatisticsAuthenticationsLogAllow(t *testing.T) { - testAuthorization(t, WithAuthorization, func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { + testAuthorization(t, WithAuthorization(), func(auth Component, mockComponent *mock.Component, ctx context.Context, mp map[string]string) { mockComponent.EXPECT().GetStatisticsAuthenticationsLog(ctx, mp["realm"], mp["max"]).Return([]api.StatisticsConnectionRepresentation{}, nil).Times(1) _, err := auth.GetStatisticsAuthenticationsLog(ctx, mp["realm"], mp["max"]) assert.Nil(t, err) diff --git a/pkg/statistics/mock_test.go b/pkg/statistics/mock_test.go index b09c9ab39..64ca6faaa 100644 --- a/pkg/statistics/mock_test.go +++ b/pkg/statistics/mock_test.go @@ -5,3 +5,4 @@ package statistics //go:generate mockgen -destination=./mock/dbmodule.go -package=mock -mock_names=EventsDBModule=EventsDBModule github.com/cloudtrust/keycloak-bridge/internal/keycloakb EventsDBModule //go:generate mockgen -destination=./mock/keycloak_client.go -package=mock -mock_names=KeycloakClient=KeycloakClient github.com/cloudtrust/common-service/security KeycloakClient //go:generate mockgen -destination=./mock/dbmodule.go -package=mock -mock_names=EventsDBModule=EventsDBModule github.com/cloudtrust/keycloak-bridge/internal/keycloakb EventsDBModule +//go:generate mockgen -destination=./mock/authentication_db_reader.go -package=mock -mock_names=AuthorizationDBReader=AuthorizationDBReader github.com/cloudtrust/common-service/security AuthorizationDBReader