diff --git a/Gopkg.lock b/Gopkg.lock index 77430be10..20ba08837 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -135,7 +135,7 @@ version = "v1.3.2" [[projects]] - digest = "1:e02b687ade0c19c038ecce3ea326d756519adc4bba1203a9e76d620b12354892" + digest = "1:debcbc62c53851dab1fc881438a65449dd5ffa12f64f059fd6e32b938799513d" name = "github.com/google/flatbuffers" packages = ["go"] pruneopts = "UT" diff --git a/Gopkg.toml b/Gopkg.toml index 68922fbce..0cde17682 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -27,11 +27,11 @@ [[constraint]] name = "github.com/cloudtrust/common-service" - version = "v1.0-rc6" + branch = "error-handling" [[constraint]] name = "github.com/cloudtrust/keycloak-client" - version = "v1.0-rc5" + branch = "error-handling" [[constraint]] name = "github.com/go-kit/kit" diff --git a/api/management/api.go b/api/management/api.go index c798fca2d..b5b9c1150 100644 --- a/api/management/api.go +++ b/api/management/api.go @@ -5,6 +5,7 @@ import ( "regexp" "strconv" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" kc "github.com/cloudtrust/keycloak-client" ) @@ -231,45 +232,45 @@ func ConvertToKCUser(user UserRepresentation) kc.UserRepresentation { // Validate is a validator for UserRepresentation func (user UserRepresentation) Validate() error { if user.Id != nil && !matchesRegExp(*user.Id, RegExpID) { - return errors.New("Invalid user ID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.UserId) } if user.Username != nil && !matchesRegExp(*user.Username, RegExpUsername) { - return errors.New("Invalid username") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Username) } if user.Email != nil && !matchesRegExp(*user.Email, RegExpEmail) { - return errors.New("Invalid email") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Email) } if user.FirstName != nil && !matchesRegExp(*user.FirstName, RegExpFirstName) { - return errors.New("Invalid firstname") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Firstname) } if user.LastName != nil && !matchesRegExp(*user.LastName, RegExpLastName) { - return errors.New("Invalid lastname") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Lastname) } if user.PhoneNumber != nil && !matchesRegExp(*user.PhoneNumber, RegExpPhoneNumber) { - return errors.New("Invalid phone number") + return errors.New(internal.MsgErrInvalidParam + "." + internal.PhoneNumber) } if user.Label != nil && !matchesRegExp(*user.Label, RegExpLabel) { - return errors.New("Invalid label") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Label) } if user.Gender != nil && !matchesRegExp(*user.Gender, RegExpGender) { - return errors.New("Invalid gender") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Gender) } if user.BirthDate != nil && !matchesRegExp(*user.BirthDate, RegExpBirthDate) { - return errors.New("Invalid birthdate") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Birthdate) } if user.Groups != nil { for _, groupID := range *(user.Groups) { if !matchesRegExp(groupID, RegExpID) { - return errors.New("Invalid group ID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.GroudId) } } } @@ -277,13 +278,13 @@ func (user UserRepresentation) Validate() error { if user.Roles != nil { for _, roleID := range *(user.Roles) { if !matchesRegExp(roleID, RegExpID) { - return errors.New("Invalid role ID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.RoleId) } } } if user.Locale != nil && !matchesRegExp(*user.Locale, RegExpLocale) { - return errors.New("Invalid locale") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Locale) } return nil @@ -292,19 +293,19 @@ func (user UserRepresentation) Validate() error { // Validate is a validator for RoleRepresentation func (role RoleRepresentation) Validate() error { if role.Id != nil && !matchesRegExp(*role.Id, RegExpID) { - return errors.New("Invalid role ID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.RoleId) } if role.Name != nil && !matchesRegExp(*role.Name, RegExpName) { - return errors.New("Invalid username") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Username) } if role.Description != nil && !matchesRegExp(*role.Description, RegExpDescription) { - return errors.New("Invalid description") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Description) } if role.ContainerId != nil && !matchesRegExp(*role.ContainerId, RegExpID) { - return errors.New("Invalid container ID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.ContainerId) } return nil @@ -313,7 +314,7 @@ func (role RoleRepresentation) Validate() error { // Validate is a validator for PasswordRepresentation func (password PasswordRepresentation) Validate() error { if password.Value != nil && !matchesRegExp(*password.Value, RegExpPassword) { - return errors.New("Invalid password") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Password) } return nil @@ -322,11 +323,11 @@ func (password PasswordRepresentation) Validate() error { // Validate is a validator for RealmCustomConfiguration func (config RealmCustomConfiguration) Validate() error { if config.DefaultClientId != nil && !matchesRegExp(*config.DefaultClientId, RegExpClientID) { - return errors.New("Invalid default client ID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.DefaultClientID) } if config.DefaultRedirectUri != nil && !matchesRegExp(*config.DefaultRedirectUri, RegExpRedirectURI) { - return errors.New("Invalid default redirect uri") + return errors.New(internal.MsgErrInvalidParam + "." + internal.DefaultRedirectURI) } return nil @@ -335,7 +336,7 @@ func (config RealmCustomConfiguration) Validate() error { // Validate is a validator for RequiredAction func (requiredAction RequiredAction) Validate() error { if requiredAction != "" && !matchesRegExp(string(requiredAction), RegExpRequiredAction) { - return errors.New("Invalid required action") + return errors.New(internal.MsgErrInvalidParam + "." + internal.RequiredAction) } return nil diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index 197e689a5..1d77b4c35 100644 --- a/cmd/keycloakb/keycloak_bridge.go +++ b/cmd/keycloakb/keycloak_bridge.go @@ -15,6 +15,7 @@ import ( cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/database" + errorhandler "github.com/cloudtrust/common-service/errors" commonhttp "github.com/cloudtrust/common-service/http" "github.com/cloudtrust/common-service/idgenerator" "github.com/cloudtrust/common-service/log" @@ -43,12 +44,8 @@ import ( ) var ( - // ComponentName is the name of the component. - ComponentName = "keycloak-bridge" // ComponentID is an unique ID generated at component startup. ComponentID = "unknown" - // Version of the component. - Version = "1.1" // Environment is filled by the compiler. Environment = "unknown" // GitCommit is filled by the compiler. @@ -60,7 +57,7 @@ func init() { } func main() { - ComponentID = strconv.FormatUint(rand.Uint64(), 10) + ComponentID := strconv.FormatUint(rand.Uint64(), 10) // Logger. var logger = log.NewLeveledLogger(kit_log.NewJSONLogger(os.Stdout)) @@ -72,7 +69,7 @@ func main() { logger = log.With(logger, "caller", kit_log.Caller(6)) // Add component name, component ID and version to the logger tags. - logger = log.With(logger, "component_name", ComponentName, "component_id", ComponentID, "component_version", Version) + logger = log.With(logger, "component_name", keycloakb.ComponentName, "component_id", ComponentID, "component_version", keycloakb.Version) } defer logger.Info("msg", "Shutdown") @@ -135,7 +132,7 @@ func main() { ) // Unique ID generator - var idGenerator = idgenerator.New(ComponentName, ComponentID) + var idGenerator = idgenerator.New(keycloakb.ComponentName, ComponentID) // Critical errors channel. var errc = make(chan error) @@ -237,7 +234,7 @@ func main() { var logger = log.With(logger, "unit", "jaeger") var err error - tracer, err = tracing.CreateJaegerClient(c, "jaeger", ComponentName) + tracer, err = tracing.CreateJaegerClient(c, "jaeger", keycloakb.ComponentName) if err != nil { logger.Error("msg", "could not create Jaeger tracer", "error", err) return @@ -462,10 +459,12 @@ func main() { var exportModule = export.NewModule(keycloakClient, logger) var cfgStorageModue = export.NewConfigStorageModule(eventsDBConn) - var exportComponent = export.NewComponent(ComponentName, Version, logger, exportModule, cfgStorageModue) + var exportComponent = export.NewComponent(keycloakb.ComponentName, keycloakb.Version, logger, exportModule, cfgStorageModue) var exportEndpoint = export.MakeExportEndpoint(exportComponent) var exportSaveAndExportEndpoint = export.MakeStoreAndExportEndpoint(exportComponent) + errorhandler.SetEmitter(keycloakb.ComponentName) + // HTTP Internal Call Server (Event reception from Keycloak & Export API). go func() { var logger = log.With(logger, "transport", "http") @@ -474,7 +473,7 @@ func main() { var route = mux.NewRouter() // Version. - route.Handle("/", commonhttp.MakeVersionHandler(ComponentName, ComponentID, Version, Environment, GitCommit)) + route.Handle("/", commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit)) // Event. var eventSubroute = route.PathPrefix("/event").Subrouter() @@ -482,8 +481,8 @@ func main() { var eventHandler http.Handler { eventHandler = event.MakeHTTPEventHandler(eventEndpoints.Endpoint, logger) - eventHandler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(eventHandler) - eventHandler = tracer.MakeHTTPTracingMW(ComponentName, "http_server_event")(eventHandler) + eventHandler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(eventHandler) + eventHandler = tracer.MakeHTTPTracingMW(keycloakb.ComponentName, "http_server_event")(eventHandler) eventHandler = middleware.MakeHTTPBasicAuthenticationMW(eventExpectedAuthToken, logger)(eventHandler) } eventSubroute.Handle("/receiver", eventHandler) @@ -513,22 +512,22 @@ func main() { var route = mux.NewRouter() // Version. - route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(ComponentName, ComponentID, Version, Environment, GitCommit))) + route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit))) // Rights - var rightsHandler = configureRightsHandler(ComponentName, ComponentID, idGenerator, authorizationManager, keycloakClient, audienceRequired, tracer, logger) + var rightsHandler = configureRightsHandler(keycloakb.ComponentName, ComponentID, idGenerator, authorizationManager, keycloakClient, audienceRequired, tracer, logger) route.Path("/rights").Methods("GET").Handler(rightsHandler) // Statistics - var getStatisticsHandler = configureStatisiticsHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(statisticsEndpoints.GetStatistics) - var getMigrationReportHandler = configureStatisiticsHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(statisticsEndpoints.GetMigrationReport) + var getStatisticsHandler = configureStatisiticsHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(statisticsEndpoints.GetStatistics) + var getMigrationReportHandler = configureStatisiticsHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(statisticsEndpoints.GetMigrationReport) route.Path("/statistics/realms/{realm}").Methods("GET").Handler(getStatisticsHandler) route.Path("/statistics/realms/{realm}/migration").Methods("GET").Handler(getMigrationReportHandler) // Events - var getEventsHandler = configureEventsHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(eventsEndpoints.GetEvents) - var getEventsSummaryHandler = configureEventsHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(eventsEndpoints.GetEventsSummary) - var getUserEventsHandler = configureEventsHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(eventsEndpoints.GetUserEvents) + var getEventsHandler = configureEventsHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(eventsEndpoints.GetEvents) + var getEventsSummaryHandler = configureEventsHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(eventsEndpoints.GetEventsSummary) + var getUserEventsHandler = configureEventsHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(eventsEndpoints.GetUserEvents) route.Path("/events").Methods("GET").Handler(getEventsHandler) route.Path("/events/summary").Methods("GET").Handler(getEventsSummaryHandler) @@ -537,42 +536,42 @@ func main() { // Management var managementSubroute = route.PathPrefix("/management").Subrouter() - var getRealmsHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRealms) - var getRealmHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRealm) + var getRealmsHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRealms) + var getRealmHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRealm) - var getClientsHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClients) - var getClientHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClient) + var getClientsHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClients) + var getClientHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClient) - var createUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.CreateUser) - var getUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetUser) - var updateUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.UpdateUser) - var deleteUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.DeleteUser) - var getUsersHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetUsers) - var getRolesForUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRolesOfUser) - var getGroupsForUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetGroupsOfUser) - var getUserAccountStatusHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetUserAccountStatus) + var createUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.CreateUser) + var getUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetUser) + var updateUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.UpdateUser) + var deleteUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.DeleteUser) + var getUsersHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetUsers) + var getRolesForUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRolesOfUser) + var getGroupsForUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetGroupsOfUser) + var getUserAccountStatusHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetUserAccountStatus) - var getClientRoleForUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClientRoleForUser) - var addClientRoleToUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.AddClientRoleToUser) + var getClientRoleForUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClientRoleForUser) + var addClientRoleToUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.AddClientRoleToUser) - var getRolesHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRoles) - var getRoleHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRole) - var getClientRolesHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClientRoles) - var createClientRolesHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.CreateClientRole) + var getRolesHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRoles) + var getRoleHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRole) + var getClientRolesHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetClientRoles) + var createClientRolesHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.CreateClientRole) - var getGroupsHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetGroups) + var getGroupsHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetGroups) - var resetPasswordHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.ResetPassword) - var sendVerifyEmailHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.SendVerifyEmail) - var executeActionsEmailHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.ExecuteActionsEmail) - var sendNewEnrolmentCodeHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.SendNewEnrolmentCode) - var sendReminderEmailHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.SendReminderEmail) + var resetPasswordHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.ResetPassword) + var sendVerifyEmailHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.SendVerifyEmail) + var executeActionsEmailHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.ExecuteActionsEmail) + var sendNewEnrolmentCodeHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.SendNewEnrolmentCode) + var sendReminderEmailHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.SendReminderEmail) - var getCredentialsForUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetCredentialsForUser) - var deleteCredentialsForUserHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.DeleteCredentialsForUser) + var getCredentialsForUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetCredentialsForUser) + var deleteCredentialsForUserHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.DeleteCredentialsForUser) - var getRealmCustomConfigurationHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRealmCustomConfiguration) - var updateRealmCustomConfigurationHandler = configureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.UpdateRealmCustomConfiguration) + var getRealmCustomConfigurationHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.GetRealmCustomConfiguration) + var updateRealmCustomConfigurationHandler = configureManagementHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(managementEndpoints.UpdateRealmCustomConfiguration) //realms managementSubroute.Path("/realms").Methods("GET").Handler(getRealmsHandler) @@ -632,13 +631,13 @@ func main() { var route = mux.NewRouter() // Version. - route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(ComponentName, ComponentID, Version, Environment, GitCommit))) + route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit))) // Account - var updatePasswordHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.UpdatePassword) - var getAccountHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.GetAccount) - var updateAccountHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.UpdateAccount) - var deleteAccountHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.DeleteAccount) + var updatePasswordHandler = configureAccountHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.UpdatePassword) + var getAccountHandler = configureAccountHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.GetAccount) + var updateAccountHandler = configureAccountHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.UpdateAccount) + var deleteAccountHandler = configureAccountHandler(keycloakb.ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.DeleteAccount) route.Path("/account/credentials/password").Methods("POST").Handler(updatePasswordHandler) route.Path("/account").Methods("GET").Handler(getAccountHandler) diff --git a/internal/keycloakb/errormessages.go b/internal/keycloakb/errormessages.go new file mode 100644 index 000000000..b3ebfe413 --- /dev/null +++ b/internal/keycloakb/errormessages.go @@ -0,0 +1,52 @@ +package keycloakb + +const ( + MsgErrInvalidParam = "invalidParameter" + MsgErrMissingParam = "missingParameter" + MsgErrWrongTypeRequest = "wrongTypeRequest" + MsgErrInvalidJSONRequest = "invalidJSONRequest" + MsgErrInvalidBase64Object = "invalidBase64Object" + MsgErrInvalidLength = "invalidLength" + MsgErrCannotObtain = "cannotObtain" + MsgErrCannotMarshal = "cannotMarshal" + MsgErrCannotSaveConfigInDB = "cannotSaveConfigInDB" + MsgErrCannotUpdate = "cannotUpdate" + MsgErrUnknown = "unknowError" + + CurrentPassword = "currentPassword" + NewPassword = "newPassword" + ConfirmPassword = "confirmPassword" + Password = "password" + Type = "type" + Id = "id" + Label = "label" + UserId = "userID" + Username = "username" + User = "user" + Email = "email" + Firstname = "firstname" + Lastname = "lastname" + PhoneNumber = "phoneNumber" + Gender = "gender" + Birthdate = "birthdate" + GroudId = "groupId" + GroudIds = "groupIds" + RoleId = "roleId" + Locale = "locale" + Description = "description" + ContainerId = "containerId" + DefaultClientID = "defaultClientID" + DefaultRedirectURI = "defaultRedirectURI" + RequiredAction = "requiredAction" + DurationLabel = "durationLabel" + Body = "body" + Flatbuffer = "flatbuffer" + Realm = "realm" + KeycloakRealms = "keycloakRealms" + Config = "config" + Response = "response" + ListOfRealms = "listOfRealms" + Groups = "groups" + ClientId = "clientId" + RedirectURI = "redirectURI" +) diff --git a/internal/keycloakb/eventsdbmodule.go b/internal/keycloakb/eventsdbmodule.go index e4c838898..9291e3f1c 100644 --- a/internal/keycloakb/eventsdbmodule.go +++ b/internal/keycloakb/eventsdbmodule.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/cloudtrust/common-service/database" - api "github.com/cloudtrust/keycloak-bridge/api/events" ) @@ -146,7 +145,7 @@ func (cm *eventsDBModule) GetLastConnection(_ context.Context, realmName string) func (cm *eventsDBModule) GetTotalConnectionsCount(_ context.Context, realmName string, durationLabel string) (int64, error) { var matched, err = regexp.MatchString(`^\d+ [A-Za-z]+$`, durationLabel) if !matched || err != nil { - return 0, errors.New("Invalid duration label") + return 0, errors.New(MsgErrInvalidParam + "." + DurationLabel) } var res = int64(0) var row = cm.db.QueryRow(strings.ReplaceAll(selectConnectionsCount, "##INTERVAL##", durationLabel), realmName) diff --git a/internal/keycloakb/eventsdbmodule_test.go b/internal/keycloakb/eventsdbmodule_test.go index 8ba72cd0d..c6da9edc9 100644 --- a/internal/keycloakb/eventsdbmodule_test.go +++ b/internal/keycloakb/eventsdbmodule_test.go @@ -5,7 +5,7 @@ import ( "database/sql" "testing" - "github.com/cloudtrust/common-service/http" + errorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/events" "github.com/cloudtrust/keycloak-bridge/pkg/events/mock" "github.com/golang/mock/gomock" @@ -22,7 +22,7 @@ func TestModuleGetEvents(t *testing.T) { params := map[string]string{"origin": "origin-1", "max": "5"} var empty [0]api.AuditRepresentation var expectedResult = empty[:] - var expectedError error = http.CreateMissingParameterError("") + var expectedError error = errorhandler.CreateMissingParameterError("") var rows sql.Rows dbEvents.EXPECT().Query(gomock.Any(), params["origin"], nil, nil, nil, nil, nil, 0, params["max"]).Return(&rows, expectedError).Times(1) res, err := module.GetEvents(context.Background(), params) @@ -39,7 +39,7 @@ func TestModuleGetEventsSummary(t *testing.T) { module := NewEventsDBModule(dbEvents) var expectedResult api.EventSummaryRepresentation - var expectedError error = http.CreateMissingParameterError("") + var expectedError error = errorhandler.CreateMissingParameterError("") var rows sql.Rows dbEvents.EXPECT().Query(gomock.Any()).Return(&rows, expectedError).Times(1) res, err := module.GetEventsSummary(context.Background()) diff --git a/internal/keycloakb/variables.go b/internal/keycloakb/variables.go new file mode 100644 index 000000000..518aefbf2 --- /dev/null +++ b/internal/keycloakb/variables.go @@ -0,0 +1,8 @@ +package keycloakb + +var ( + // ComponentName is the name of the component. + ComponentName = "keycloak-bridge" + // Version of the component. + Version = "1.1" +) diff --git a/pkg/account/component.go b/pkg/account/component.go index fd9c3e463..1fae38b8b 100644 --- a/pkg/account/component.go +++ b/pkg/account/component.go @@ -8,7 +8,7 @@ import ( cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/database" - commonhttp "github.com/cloudtrust/common-service/http" + errorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/account" internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" kc "github.com/cloudtrust/keycloak-client" @@ -57,40 +57,29 @@ func (c *component) UpdatePassword(ctx context.Context, currentPassword, newPass var username = ctx.Value(cs.CtContextUsername).(string) if currentPassword == newPassword || newPassword != confirmPassword { - return commonhttp.Error{ - Status: http.StatusBadRequest, + return errorhandler.Error{ + Status: http.StatusBadRequest, + Message: internal.ComponentName + "." + "invalidValues", } } _, err := c.keycloakClient.UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword) - var updateError error = nil - if err != nil { - switch err.Error() { - case "invalidPasswordExistingMessage": - updateError = commonhttp.Error{ - Status: http.StatusBadRequest, - Message: err.Error()} - default: - updateError = err - } - } - //store the API call into the DB - err = c.reportEvent(ctx, "PASSWORD_RESET", database.CtEventRealmName, realm, database.CtEventUserID, userID, database.CtEventUsername, username) - if err != nil { + errEvent := c.reportEvent(ctx, "PASSWORD_RESET", database.CtEventRealmName, realm, database.CtEventUserID, userID, database.CtEventUsername, username) + if errEvent != nil { //store in the logs also the event that failed to be stored in the DB m := map[string]interface{}{"event_name": "PASSWORD_RESET", database.CtEventRealmName: realm, database.CtEventUserID: userID, database.CtEventUsername: username} eventJSON, errMarshal := json.Marshal(m) if errMarshal == nil { - c.logger.Error("err", err.Error(), "event", string(eventJSON)) + c.logger.Error("err", errEvent.Error(), "event", string(eventJSON)) } else { - c.logger.Error("err", err.Error()) + c.logger.Error("err", errEvent.Error()) } } - return updateError + return err } func (c *component) GetAccount(ctx context.Context) (api.AccountRepresentation, error) { diff --git a/pkg/account/endpoint.go b/pkg/account/endpoint.go index d6f1c767b..58bb58f2f 100644 --- a/pkg/account/endpoint.go +++ b/pkg/account/endpoint.go @@ -5,8 +5,9 @@ import ( "encoding/json" cs "github.com/cloudtrust/common-service" - "github.com/cloudtrust/common-service/http" + errrorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/account" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/go-kit/kit/endpoint" ) @@ -41,7 +42,7 @@ func MakeUpdatePasswordEndpoint(component AccountComponent) cs.Endpoint { err := json.Unmarshal([]byte(m["body"]), &body) if err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errrorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } return nil, component.UpdatePassword(ctx, body.CurrentPassword, body.NewPassword, body.ConfirmPassword) @@ -63,11 +64,11 @@ func MakeUpdateAccountEndpoint(component AccountComponent) cs.Endpoint { err := json.Unmarshal([]byte(m["body"]), &body) if err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errrorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = body.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errrorhandler.CreateBadRequestError(err.Error()) } return nil, component.UpdateAccount(ctx, body) diff --git a/pkg/event/endpoint.go b/pkg/event/endpoint.go index a4161d733..acf86a326 100755 --- a/pkg/event/endpoint.go +++ b/pkg/event/endpoint.go @@ -5,6 +5,7 @@ import ( "fmt" cs "github.com/cloudtrust/common-service" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/go-kit/kit/endpoint" ) @@ -20,7 +21,7 @@ func MakeEventEndpoint(c MuxComponent) cs.Endpoint { case Request: return nil, c.Event(ctx, r.Type, r.Object) default: - return nil, fmt.Errorf("request has wrong type: %T", req) + return nil, fmt.Errorf(internal.MsgErrWrongTypeRequest+".%T", req) } } } diff --git a/pkg/event/http.go b/pkg/event/http.go index 9aa3b5f2a..29c540908 100755 --- a/pkg/event/http.go +++ b/pkg/event/http.go @@ -9,6 +9,7 @@ import ( cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/log" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/go-kit/kit/endpoint" http_transport "github.com/go-kit/kit/transport/http" "github.com/pkg/errors" @@ -52,7 +53,7 @@ func decodeHTTPRequest(_ context.Context, r *http.Request) (res interface{}, err { var err = json.NewDecoder(r.Body).Decode(&request) if err != nil { - return nil, errors.Wrap(err, "could not decode JSON request") + return nil, errors.Wrap(err, internal.MsgErrInvalidJSONRequest) } } @@ -62,7 +63,7 @@ func decodeHTTPRequest(_ context.Context, r *http.Request) (res interface{}, err bEvent, err = base64.StdEncoding.DecodeString(request.Object) if err != nil { - return nil, errors.Wrap(err, "could not decode Base64 object from request") + return nil, errors.Wrap(err, internal.MsgErrInvalidBase64Object) } } @@ -70,14 +71,14 @@ func decodeHTTPRequest(_ context.Context, r *http.Request) (res interface{}, err { if !(objType == "AdminEvent" || objType == "Event") { var err = ErrInvalidArgument{InvalidParam: "type"} - return nil, errors.Wrap(err, "could not decode Base64 object from request") + return nil, errors.Wrap(err, internal.MsgErrInvalidBase64Object) } } // Check valid buffer (at least 4 bytes) if len(bEvent) < 4 { var err = ErrInvalidArgument{InvalidParam: "obj"} - return nil, errors.Wrap(err, "invalid flatbuffer length") + return nil, errors.Wrap(err, internal.MsgErrInvalidLength+"."+internal.Flatbuffer) } return Request{ @@ -98,7 +99,7 @@ type ErrInvalidArgument struct { } func (e ErrInvalidArgument) Error() string { - return fmt.Sprintf("Invalid argument: %s", e.InvalidParam) + return fmt.Sprintf("invalidArgument.%s", e.InvalidParam) } // errorHandler encodes the reply when there is an error. diff --git a/pkg/events/component.go b/pkg/events/component.go index c7e4d4452..bfd48f411 100644 --- a/pkg/events/component.go +++ b/pkg/events/component.go @@ -5,7 +5,7 @@ import ( "encoding/json" "github.com/cloudtrust/common-service/database" - "github.com/cloudtrust/common-service/http" + errorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/events" app "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" ) @@ -59,10 +59,10 @@ func (ec *component) GetEventsSummary(ctx context.Context) (api.EventSummaryRepr // Get all events related to a given realm and a given user func (ec *component) GetUserEvents(ctx context.Context, params map[string]string) (api.AuditEventsRepresentation, error) { if val, ok := params["realm"]; !ok || len(val) == 0 { - return api.AuditEventsRepresentation{}, http.CreateMissingParameterError("realm") + return api.AuditEventsRepresentation{}, errorhandler.CreateMissingParameterError(app.Realm) } if val, ok := params["userID"]; !ok || len(val) == 0 { - return api.AuditEventsRepresentation{}, http.CreateMissingParameterError("userID") + return api.AuditEventsRepresentation{}, errorhandler.CreateMissingParameterError(app.UserId) } err := ec.reportEvent(ctx, "GET_ACTIVITY", database.CtEventRealmName, params["realm"], database.CtEventUserID, params["userID"]) diff --git a/pkg/export/component.go b/pkg/export/component.go index 1400ac800..a631ca8e4 100644 --- a/pkg/export/component.go +++ b/pkg/export/component.go @@ -65,7 +65,7 @@ func (c *component) StoreAndExport(ctx context.Context) (map[string]interface{}, realms, err = c.re.GetRealms(ctx) if err != nil { c.logger.Warn("err", err.Error()) - return nil, errors.Wrap(err, "export failed, could not get keycloak realms") + return nil, errors.Wrap(err, internal.MsgErrCannotObtain+"."+internal.KeycloakRealms) } } @@ -83,13 +83,13 @@ func (c *component) StoreAndExport(ctx context.Context) (map[string]interface{}, // Store var data, err = json.Marshal(realmsMap) if err != nil { - return nil, errors.Wrapf(err, "component %s with version %s, could not marshal config", c.componentName, c.componentVersion) + return nil, errors.Wrapf(err, internal.MsgErrCannotMarshal+"."+internal.Config+"."+c.componentName+"."+c.componentVersion) } err = c.s.Save(c.componentName, c.componentVersion, data) if err != nil { - return nil, errors.Wrapf(err, "component %s with version %s, could not save config in db", c.componentName, c.componentVersion) + return nil, errors.Wrapf(err, internal.MsgErrCannotSaveConfigInDB+"."+c.componentName+"."+c.componentVersion) } return realmsMap, nil diff --git a/pkg/export/http.go b/pkg/export/http.go index 86556ead6..13350a3b4 100755 --- a/pkg/export/http.go +++ b/pkg/export/http.go @@ -6,6 +6,7 @@ import ( "net/http" cs "github.com/cloudtrust/common-service" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/go-kit/kit/endpoint" http_transport "github.com/go-kit/kit/transport/http" "github.com/pkg/errors" @@ -43,7 +44,7 @@ func encodeHTTPReply(_ context.Context, w http.ResponseWriter, res interface{}) var reply = res.(map[string]interface{}) var data, err = json.MarshalIndent(reply, "", " ") if err != nil { - return errors.Wrap(err, "could not marshal response") + return errors.Wrap(err, internal.MsgErrCannotMarshal+internal.Response) } w.WriteHeader(http.StatusOK) @@ -55,5 +56,5 @@ func encodeHTTPReply(_ context.Context, w http.ResponseWriter, res interface{}) func errorHandler(ctx context.Context, err error, w http.ResponseWriter) { w.Header().Set("Content-Type", "application/octet-stream") w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) + w.Write([]byte(internal.ComponentName + "." + err.Error())) } diff --git a/pkg/export/module.go b/pkg/export/module.go index 48dbbed11..a79e76bcb 100644 --- a/pkg/export/module.go +++ b/pkg/export/module.go @@ -35,7 +35,7 @@ func (m *Module) GetRealms(ctx context.Context) ([]string, error) { var realms, err = m.kc.GetRealms(accessToken) if err != nil { m.logger.Warn("err", err.Error()) - return res, errors.Wrap(err, "could not get list of realms") + return res, errors.Wrap(err, internal.MsgErrCannotObtain+internal.ListOfRealms) } for _, realm := range realms { diff --git a/pkg/export/storage.go b/pkg/export/storage.go index 940b0354b..9e07c7763 100644 --- a/pkg/export/storage.go +++ b/pkg/export/storage.go @@ -3,6 +3,7 @@ package export import ( "database/sql" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/pkg/errors" ) @@ -38,7 +39,7 @@ func (c *StorageModule) Save(componentName, version string, config []byte) error var _, err = c.db.Exec(upsertConfigStmt, componentName, version, config) if err != nil { - return errors.Wrapf(err, "component '%s' with version '%s' could not update config", componentName, version) + return errors.Wrapf(err, internal.MsgErrCannotUpdate+"."+internal.Config+"."+componentName+"."+version) } return nil @@ -53,7 +54,7 @@ func (c *StorageModule) Read(componentName, version string) ([]byte, error) { var err = row.Scan(&cName, &v, &config) if err != nil { - return nil, errors.Wrapf(err, "component '%s' with version '%s' could not update config", componentName, version) + return nil, errors.Wrapf(err, internal.MsgErrCannotUpdate+"."+internal.Config+"."+componentName+"."+version) } return config, nil diff --git a/pkg/management/component.go b/pkg/management/component.go index 6b8034947..6285c3ce9 100644 --- a/pkg/management/component.go +++ b/pkg/management/component.go @@ -8,7 +8,7 @@ import ( cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/database" - "github.com/cloudtrust/common-service/http" + errorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/management" internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" kc "github.com/cloudtrust/keycloak-client" @@ -873,9 +873,9 @@ func (c *component) UpdateRealmCustomConfiguration(ctx context.Context, realmNam } } if !match { - return http.Error{ + return errorhandler.Error{ Status: 400, - Message: "Invalid client ID or redirect URI", + Message: internal.MsgErrInvalidParam + "." + internal.ClientId + "Or" + internal.RedirectURI, } } // transform customConfig object into JSON string diff --git a/pkg/management/component_test.go b/pkg/management/component_test.go index c374e3da9..7e40aef87 100644 --- a/pkg/management/component_test.go +++ b/pkg/management/component_test.go @@ -11,7 +11,7 @@ import ( cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/database" - commonhttp "github.com/cloudtrust/common-service/http" + commonhttp "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/pkg/management/mock" diff --git a/pkg/management/endpoint.go b/pkg/management/endpoint.go index 7a74e9404..fe10d2d76 100644 --- a/pkg/management/endpoint.go +++ b/pkg/management/endpoint.go @@ -8,8 +8,9 @@ import ( "strings" cs "github.com/cloudtrust/common-service" - "github.com/cloudtrust/common-service/http" + errorhandler "github.com/cloudtrust/common-service/errors" api "github.com/cloudtrust/keycloak-bridge/api/management" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/go-kit/kit/endpoint" ) @@ -120,15 +121,15 @@ func MakeCreateUserEndpoint(managementComponent ManagementComponent) cs.Endpoint var user api.UserRepresentation if err = json.Unmarshal([]byte(m["body"]), &user); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = user.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errorhandler.CreateBadRequestError(err.Error()) } if user.Groups == nil || len(*user.Groups) == 0 { - return nil, http.CreateMissingParameterError("groups") + return nil, errorhandler.CreateMissingParameterError(internal.Groups) } var keycloakLocation string @@ -139,10 +140,11 @@ func MakeCreateUserEndpoint(managementComponent ManagementComponent) cs.Endpoint } url, err := convertLocationURL(keycloakLocation, m["scheme"], m["host"]) + // TODO: log the error and the unhappy url return LocationHeader{ URL: url, - }, err + }, nil } } @@ -173,11 +175,11 @@ func MakeUpdateUserEndpoint(managementComponent ManagementComponent) cs.Endpoint var user api.UserRepresentation if err = json.Unmarshal([]byte(m["body"]), &user); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + internal.Body) } if err = user.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errorhandler.CreateBadRequestError(err.Error()) } return nil, managementComponent.UpdateUser(ctx, m["realm"], m["userID"], user) @@ -198,7 +200,7 @@ func MakeGetUsersEndpoint(managementComponent ManagementComponent) cs.Endpoint { _, ok := m["groupIds"] if !ok { - return nil, http.CreateMissingParameterError("groupIds") + return nil, errorhandler.CreateMissingParameterError(internal.GroudIds) } groupIDs := strings.Split(m["groupIds"], ",") @@ -252,12 +254,12 @@ func MakeAddClientRolesToUserEndpoint(managementComponent ManagementComponent) c var roles []api.RoleRepresentation if err = json.Unmarshal([]byte(m["body"]), &roles); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } for _, role := range roles { if err = role.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errorhandler.CreateBadRequestError(err.Error()) } } @@ -274,11 +276,11 @@ func MakeResetPasswordEndpoint(managementComponent ManagementComponent) cs.Endpo var password api.PasswordRepresentation if err = json.Unmarshal([]byte(m["body"]), &password); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = password.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errorhandler.CreateBadRequestError(err.Error()) } pwd, err := managementComponent.ResetPassword(ctx, m["realm"], m["userID"], password) @@ -322,12 +324,12 @@ func MakeExecuteActionsEmailEndpoint(managementComponent ManagementComponent) cs var actions []api.RequiredAction if err = json.Unmarshal([]byte(m["body"]), &actions); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } for _, action := range actions { if err = action.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errorhandler.CreateBadRequestError(err.Error()) } } @@ -424,11 +426,11 @@ func MakeCreateClientRoleEndpoint(managementComponent ManagementComponent) cs.En var role api.RoleRepresentation if err = json.Unmarshal([]byte(m["body"]), &role); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = role.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errorhandler.CreateBadRequestError(err.Error()) } var keycloakLocation string @@ -439,10 +441,11 @@ func MakeCreateClientRoleEndpoint(managementComponent ManagementComponent) cs.En } url, err := convertLocationURL(keycloakLocation, m["scheme"], m["host"]) + // TODO: log the error and the unhappy url return LocationHeader{ URL: url, - }, err + }, nil } } @@ -466,11 +469,11 @@ func MakeUpdateRealmCustomConfigurationEndpoint(managementComponent ManagementCo var customConfig api.RealmCustomConfiguration if err = json.Unmarshal(configJSON, &customConfig); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, errorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = customConfig.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errorhandler.CreateBadRequestError(err.Error()) } return nil, managementComponent.UpdateRealmCustomConfiguration(ctx, m["realm"], customConfig) @@ -488,7 +491,7 @@ type ConvertLocationError struct { } func (e ConvertLocationError) Error() string { - return fmt.Sprintf("Location received from Keycloak do not match regexp: %s", e.Location) + return fmt.Sprintf("locationReceivedFromKeycloakDoesNotMatchRegexp.%s", e.Location) } // We are currently using a mapping 1:1 for REST API of Bridge and Keycloak, thus we take a shortcut to convert the location of the resource diff --git a/pkg/management/http.go b/pkg/management/http.go index 03d626393..860793e8f 100644 --- a/pkg/management/http.go +++ b/pkg/management/http.go @@ -7,6 +7,7 @@ import ( commonhttp "github.com/cloudtrust/common-service/http" "github.com/cloudtrust/common-service/log" management_api "github.com/cloudtrust/keycloak-bridge/api/management" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" kc_client "github.com/cloudtrust/keycloak-client" "github.com/go-kit/kit/endpoint" http_transport "github.com/go-kit/kit/transport/http" @@ -69,11 +70,10 @@ func managementErrorHandler(logger log.Logger) func(context.Context, error, http switch e := errors.Cause(err).(type) { case kc_client.HTTPError: w.WriteHeader(e.HTTPStatus) - case ConvertLocationError: - // 201-Created, even if ConvertLocationError occurs, the creation was a success - w.WriteHeader(http.StatusCreated) + w.Write([]byte(internal.ComponentName + "." + internal.MsgErrUnknown)) default: defaultHandler(ctx, err, w) + } } } diff --git a/pkg/management/http_test.go b/pkg/management/http_test.go index 075638015..11b7610fc 100644 --- a/pkg/management/http_test.go +++ b/pkg/management/http_test.go @@ -10,7 +10,7 @@ import ( "strings" "testing" - commonhttp "github.com/cloudtrust/common-service/http" + commonhttp "github.com/cloudtrust/common-service/errors" "github.com/cloudtrust/common-service/log" "github.com/cloudtrust/common-service/security" api "github.com/cloudtrust/keycloak-bridge/api/management" @@ -157,7 +157,7 @@ func TestHTTPErrorHandler(t *testing.T) { assert.Nil(t, err) assert.Equal(t, http.StatusForbidden, res.StatusCode) - assert.Equal(t, http.NoBody, res.Body) + } // Bad request. @@ -201,7 +201,6 @@ func TestHTTPErrorHandler(t *testing.T) { assert.Nil(t, err) assert.Equal(t, http.StatusNotFound, res.StatusCode) - assert.Equal(t, http.NoBody, res.Body) } // HTTPResponse Error