From 321ac91a4a9c321c89307f07815bc7e1f1ac0263 Mon Sep 17 00:00:00 2001 From: harture <31417989+harture@users.noreply.github.com> Date: Fri, 16 Aug 2019 08:47:10 +0200 Subject: [PATCH 01/24] [CLOUDTRUST-1502] Self service API (cherry picked from commit 10f6d2b1559a051a30c6a9aa193b6cc4c92bcb7d) --- api/account/api_test.go | 107 ++++++++++++ api/account/swagger-api_account.yaml | 9 +- api/management/api.go | 35 ++-- api/management/api_test.go | 15 +- configs/keycloak_bridge.yml | 4 +- pkg/account/component.go | 6 +- pkg/account/component_test.go | 241 ++++++++++++++++++++++++++- pkg/account/endpoint.go | 6 +- pkg/account/endpoint_test.go | 4 +- pkg/account/http.go | 14 +- pkg/account/http_test.go | 9 +- pkg/account/mock_test.go | 2 +- 12 files changed, 396 insertions(+), 56 deletions(-) create mode 100644 api/account/api_test.go diff --git a/api/account/api_test.go b/api/account/api_test.go new file mode 100644 index 000000000..6bda05b7c --- /dev/null +++ b/api/account/api_test.go @@ -0,0 +1,107 @@ +package account_api + +import ( + "testing" + + kc "github.com/cloudtrust/keycloak-client" + "github.com/stretchr/testify/assert" +) + +func TestConvertCredential(t *testing.T) { + var credKc kc.CredentialRepresentation + var credType = "password" + var credID = "123456" + var configKc = "{}" + + credKc.Type = &credType + credKc.Id = &credID + credKc.CredentialData = nil + + assert.Equal(t, credKc.Type, ConvertCredential(&credKc).Type) + assert.Equal(t, credKc.Id, ConvertCredential(&credKc).Id) + assert.Nil(t, ConvertCredential(&credKc).CredentialData) + + credKc.CredentialData = &configKc + assert.NotNil(t, ConvertCredential(&credKc).CredentialData) + assert.Equal(t, "{}", *ConvertCredential(&credKc).CredentialData) +} + +func TestValidateUpdatePasswordRepresentation(t *testing.T) { + { + password := createValidUpdatePasswordBody() + assert.Nil(t, password.Validate()) + } + + value := "" + + { + password := createValidUpdatePasswordBody() + password.CurrentPassword = value + assert.NotNil(t, password.Validate()) + } + + { + password := createValidUpdatePasswordBody() + password.NewPassword = value + assert.NotNil(t, password.Validate()) + } + + { + password := createValidUpdatePasswordBody() + password.ConfirmPassword = value + assert.NotNil(t, password.Validate()) + } + +} + +func TestValidateCredentialRepresentation(t *testing.T) { + { + credential := createValidCredentialRepresentation() + assert.Nil(t, credential.Validate()) + } + + value := "" + + { + credential := createValidCredentialRepresentation() + credential.Id = &value + assert.NotNil(t, credential.Validate()) + } + + { + credential := createValidCredentialRepresentation() + credential.Type = &value + assert.NotNil(t, credential.Validate()) + } + + { + credential := createValidCredentialRepresentation() + credential.UserLabel = &value + assert.NotNil(t, credential.Validate()) + } + +} + +func createValidUpdatePasswordBody() UpdatePasswordBody { + password := "password" + + return UpdatePasswordBody{ + CurrentPassword: password, + NewPassword: password, + ConfirmPassword: password, + } +} + +func createValidCredentialRepresentation() CredentialRepresentation { + id := "f467ed7c-0a1d-4eee-9bb8-669c6f89c0ee" + credType := "otp" + userLabel := "my otp" + credData := "{}" + + return CredentialRepresentation{ + Id: &id, + Type: &credType, + CredentialData: &credData, + UserLabel: &userLabel, + } +} diff --git a/api/account/swagger-api_account.yaml b/api/account/swagger-api_account.yaml index f30ecb84d..eeea16d20 100644 --- a/api/account/swagger-api_account.yaml +++ b/api/account/swagger-api_account.yaml @@ -5,20 +5,17 @@ info: version: 1.0.0 servers: - url: http://localhost:8888 -tags: -- name: Account - description: Account management paths: /account/credentials/password: post: tags: - - Password + - Credentials requestBody: content: application/json: schema: $ref: '#/components/schemas/UpdatePassword' - summary: Update a password + summary: Update password responses: 200: description: The password has been updated @@ -80,4 +77,4 @@ components: openIdConnectUrl: http://toto.com/.well-known/openid-configuration security: - openId: - - todo + - todo \ No newline at end of file diff --git a/api/management/api.go b/api/management/api.go index c798fca2d..065be84b3 100644 --- a/api/management/api.go +++ b/api/management/api.go @@ -55,11 +55,13 @@ type ClientRepresentation struct { // CredentialRepresentation struct type CredentialRepresentation struct { - Id *string `json:"id,omitempty"` - Type *string `json:"type,omitempty"` - Algorithm *string `json:"algorithm,omitempty"` - CreatedDate *int64 `json:"createdDate,omitempty"` - Config *map[string][]string `json:"config,omitempty"` + Id *string `json:"id,omitempty"` + Type *string `json:"type,omitempty"` + UserLabel *string `json:"userLabel,omitempty"` + CreatedDate *int64 `json:"createdDate,omitempty"` + CredentialData *string `json:"credentialData,omitempty"` + Value *string `json:"value,omitempty"` + Temporary *bool `json:"temporary,omitempty"` } // RoleRepresentation struct @@ -85,8 +87,10 @@ type PasswordRepresentation struct { // RealmCustomConfiguration struct type RealmCustomConfiguration struct { - DefaultClientId *string `json:"default_client_id,omitempty"` - DefaultRedirectUri *string `json:"default_redirect_uri,omitempty"` + DefaultClientId *string `json:"default_client_id,omitempty"` + DefaultRedirectUri *string `json:"default_redirect_uri,omitempty"` + SelfAuthenticatorMgmtEnabled *bool `json:"self_authenticator_mgmt_enabled"` + SelfPasswordChangeEnabled *bool `json:"self_password_change_enabled"` } // RequiredAction type @@ -97,19 +101,12 @@ func ConvertCredential(credKc *kc.CredentialRepresentation) CredentialRepresenta var cred CredentialRepresentation cred.Id = credKc.Id cred.Type = credKc.Type - cred.Algorithm = credKc.Algorithm + cred.UserLabel = credKc.UserLabel cred.CreatedDate = credKc.CreatedDate - if credKc.Config != nil { - var m map[string][]string - m = make(map[string][]string) - for _, key := range []string{"deviceInfo_Manufacturer", "deviceInfo_Model", "deviceInfo_Name", "deviceInfo_Plateform", "shortId", "usedChallenges", "availableChallenges", "cardStatus", "expirationDate"} { - value, ok := (*credKc.Config)[key] - if ok { - m[key] = value - } - } - cred.Config = &m - } + cred.CredentialData = credKc.CredentialData + cred.Temporary = credKc.Temporary + cred.Value = credKc.Value + return cred } diff --git a/api/management/api_test.go b/api/management/api_test.go index 67817d2fa..b7f2347a3 100644 --- a/api/management/api_test.go +++ b/api/management/api_test.go @@ -13,22 +13,19 @@ func TestConvertCredential(t *testing.T) { var credKc kc.CredentialRepresentation var credType = "password" var credID = "123456" - var configKc map[string][]string - configKc = make(map[string][]string) - configKc["undesired_Key"] = make([]string, 0) - configKc["deviceInfo_Model"] = make([]string, 0) + var configKc = "{}" credKc.Type = &credType credKc.Id = &credID - credKc.Config = nil + credKc.CredentialData = nil assert.Equal(t, credKc.Type, ConvertCredential(&credKc).Type) assert.Equal(t, credKc.Id, ConvertCredential(&credKc).Id) - assert.Nil(t, ConvertCredential(&credKc).Config) + assert.Nil(t, ConvertCredential(&credKc).CredentialData) - credKc.Config = &configKc - assert.NotNil(t, ConvertCredential(&credKc).Config) - assert.Equal(t, 1, len(*ConvertCredential(&credKc).Config)) + credKc.CredentialData = &configKc + assert.NotNil(t, ConvertCredential(&credKc).CredentialData) + assert.Equal(t, "{}", *ConvertCredential(&credKc).CredentialData) } func TestConvertToAPIUser(t *testing.T) { diff --git a/configs/keycloak_bridge.yml b/configs/keycloak_bridge.yml index 3b0091585..aa82b7233 100644 --- a/configs/keycloak_bridge.yml +++ b/configs/keycloak_bridge.yml @@ -38,8 +38,8 @@ event-basic-auth-token: "superpasswordverylongandstrong" # Keycloak configs -keycloak-api-uri: http://localhost:8080 -keycloak-oidc-uri: http://localhost:8080 +keycloak-api-uri: http://localhost:8081 +keycloak-oidc-uri: http://localhost:8081 keycloak-timeout: 5s # DB Audit RW diff --git a/pkg/account/component.go b/pkg/account/component.go index 4ac3f5e84..4b4b3ef09 100644 --- a/pkg/account/component.go +++ b/pkg/account/component.go @@ -14,8 +14,8 @@ import ( kc "github.com/cloudtrust/keycloak-client" ) -// KeycloakClient interface exposes methods we need to call to send requests to Keycloak API -type KeycloakClient interface { +// KeycloakAccountClient interface exposes methods we need to call to send requests to Keycloak API of Account +type KeycloakAccountClient interface { UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword string) (string, error) UpdateAccount(accessToken, realm string, user kc.UserRepresentation) error GetAccount(accessToken, realm string) (kc.UserRepresentation, error) @@ -60,7 +60,7 @@ func (c *component) UpdatePassword(ctx context.Context, currentPassword, newPass } } - _, err := c.keycloakClient.UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword) + _, err := c.keycloakAccountClient.UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword) var updateError error = nil if err != nil { diff --git a/pkg/account/component_test.go b/pkg/account/component_test.go index f1711fba7..1b11c8768 100644 --- a/pkg/account/component_test.go +++ b/pkg/account/component_test.go @@ -23,7 +23,7 @@ func genericUpdatePasswordTest(t *testing.T, oldPasswd, newPasswd, confirmPasswo var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() - mockKeycloakClient := mock.NewAccKeycloakClient(mockCtrl) + mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) mockEventDBModule := mock.NewEventsDBModule(mockCtrl) mockLogger := mock.NewLogger(mockCtrl) component := NewComponent(mockKeycloakClient, mockEventDBModule, mockLogger) @@ -37,7 +37,7 @@ func genericUpdatePasswordTest(t *testing.T, oldPasswd, newPasswd, confirmPasswo ctx = context.WithValue(ctx, cs.CtContextUserID, userID) ctx = context.WithValue(ctx, cs.CtContextUsername, username) - mockKeycloakClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, confirmPassword).Return("", nil).Times(kcCalls) + mockKeycloakAccountClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, confirmPassword).Return("", nil).Times(kcCalls) mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "PASSWORD_RESET", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(kcCalls) err := component.UpdatePassword(ctx, oldPasswd, newPasswd, confirmPassword) @@ -70,7 +70,7 @@ func TestUpdatePasswordWrongPwd(t *testing.T) { var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() - mockKeycloakClient := mock.NewAccKeycloakClient(mockCtrl) + mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) mockEventDBModule := mock.NewEventsDBModule(mockCtrl) mockLogger := mock.NewLogger(mockCtrl) component := NewComponent(mockKeycloakClient, mockEventDBModule, mockLogger) @@ -84,14 +84,14 @@ func TestUpdatePasswordWrongPwd(t *testing.T) { ctx = context.WithValue(ctx, cs.CtContextUserID, userID) ctx = context.WithValue(ctx, cs.CtContextUsername, username) - mockKeycloakClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalidPasswordExistingMessage")).Times(1) + mockKeycloakAccountClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalidPasswordExistingMessage")).Times(1) mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "PASSWORD_RESET", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) err := component.UpdatePassword(ctx, oldPasswd, newPasswd, newPasswd) assert.True(t, err != nil) - mockKeycloakClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalid")).Times(1) + mockKeycloakAccountClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalid")).Times(1) mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "PASSWORD_RESET", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) err = component.UpdatePassword(ctx, oldPasswd, newPasswd, newPasswd) @@ -362,3 +362,234 @@ func TestGetUser(t *testing.T) { assert.NotNil(t, err) } } + +func TestGetCredentials(t *testing.T) { + var mockCtrl = gomock.NewController(t) + defer mockCtrl.Finish() + + mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) + mockEventDBModule := mock.NewEventsDBModule(mockCtrl) + mockLogger := log.NewNopLogger() + component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) + + var accessToken = "TOKEN==" + var currentRealm = "master" + var currentUserID = "1234-789" + + // Get credentials with succces + { + var id = "1245" + + var kcCredRep = kc.CredentialRepresentation{ + Id: &id, + } + + var kcCredsRep []kc.CredentialRepresentation + kcCredsRep = append(kcCredsRep, kcCredRep) + + mockKeycloakAccountClient.EXPECT().GetCredentials(accessToken, currentRealm).Return(kcCredsRep, nil).Times(1) + + var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) + ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) + ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) + + apiCredsRep, err := component.GetCredentials(ctx) + + var expectedAPICredRep = account_api.CredentialRepresentation{ + Id: &id, + } + + var expectedAPICredsRep []account_api.CredentialRepresentation + expectedAPICredsRep = append(expectedAPICredsRep, expectedAPICredRep) + + assert.Nil(t, err) + assert.Equal(t, expectedAPICredsRep, apiCredsRep) + } + + //Error + { + mockKeycloakAccountClient.EXPECT().GetCredentials(accessToken, currentRealm).Return([]kc.CredentialRepresentation{}, fmt.Errorf("Unexpected error")).Times(1) + + var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) + ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) + ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) + + _, err := component.GetCredentials(ctx) + + assert.NotNil(t, err) + } +} + +func TestGetCredentialTypes(t *testing.T) { + var mockCtrl = gomock.NewController(t) + defer mockCtrl.Finish() + + mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) + mockEventDBModule := mock.NewEventsDBModule(mockCtrl) + mockLogger := log.NewNopLogger() + component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) + + var accessToken = "TOKEN==" + var currentRealm = "master" + var currentUserID = "1234-789" + + // Get credential types with succces + { + var credTypes = []string{"paper", "push"} + + mockKeycloakAccountClient.EXPECT().GetCredentialTypes(accessToken, currentRealm).Return(credTypes, nil).Times(1) + + var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) + ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) + ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) + + resCredTypes, err := component.GetCredentialTypes(ctx) + + assert.Nil(t, err) + assert.Equal(t, credTypes, resCredTypes) + } + + //Error + { + mockKeycloakAccountClient.EXPECT().GetCredentialTypes(accessToken, currentRealm).Return([]string{}, fmt.Errorf("Unexpected error")).Times(1) + + var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) + ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) + ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) + + _, err := component.GetCredentialTypes(ctx) + + assert.NotNil(t, err) + } +} + +func TestUpdateLabelCredential(t *testing.T) { + + var mockCtrl = gomock.NewController(t) + defer mockCtrl.Finish() + + mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) + mockEventDBModule := mock.NewEventsDBModule(mockCtrl) + mockLogger := log.NewNopLogger() + component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) + + accessToken := "access token" + realm := "sample realm" + userID := "123-456-789" + username := "username" + ctx := context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) + ctx = context.WithValue(ctx, cs.CtContextRealm, realm) + ctx = context.WithValue(ctx, cs.CtContextUserID, userID) + ctx = context.WithValue(ctx, cs.CtContextUsername, username) + + credentialID := "78945-845" + label := "cred label" + + { + mockKeycloakAccountClient.EXPECT().UpdateLabelCredential(accessToken, realm, credentialID, label).Return(nil).Times(1) + mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_UPDATE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) + + err := component.UpdateLabelCredential(ctx, credentialID, label) + + assert.Nil(t, err) + } + + { + mockKeycloakAccountClient.EXPECT().UpdateLabelCredential(accessToken, realm, credentialID, label).Return(fmt.Errorf("Unexpected error")).Times(1) + err := component.UpdateLabelCredential(ctx, credentialID, label) + + assert.NotNil(t, err) + } +} + +func TestDeleteCredential(t *testing.T) { + + var mockCtrl = gomock.NewController(t) + defer mockCtrl.Finish() + + mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) + mockEventDBModule := mock.NewEventsDBModule(mockCtrl) + mockLogger := log.NewNopLogger() + component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) + + accessToken := "access token" + realm := "sample realm" + userID := "123-456-789" + username := "username" + ctx := context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) + ctx = context.WithValue(ctx, cs.CtContextRealm, realm) + ctx = context.WithValue(ctx, cs.CtContextUserID, userID) + ctx = context.WithValue(ctx, cs.CtContextUsername, username) + + credentialID := "78945-845" + { + mockKeycloakAccountClient.EXPECT().DeleteCredential(accessToken, realm, credentialID).Return(nil).Times(1) + mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_DELETE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) + + err := component.DeleteCredential(ctx, credentialID) + + assert.Nil(t, err) + } + + { + mockKeycloakAccountClient.EXPECT().DeleteCredential(accessToken, realm, credentialID).Return(fmt.Errorf("Unexpected error")).Times(1) + err := component.DeleteCredential(ctx, credentialID) + + assert.NotNil(t, err) + } +} + +func TestMoveCredential(t *testing.T) { + + var mockCtrl = gomock.NewController(t) + defer mockCtrl.Finish() + + mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) + mockEventDBModule := mock.NewEventsDBModule(mockCtrl) + mockLogger := log.NewNopLogger() + component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) + + accessToken := "access token" + realm := "sample realm" + userID := "123-456-789" + username := "username" + ctx := context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) + ctx = context.WithValue(ctx, cs.CtContextRealm, realm) + ctx = context.WithValue(ctx, cs.CtContextUserID, userID) + ctx = context.WithValue(ctx, cs.CtContextUsername, username) + + credentialID := "78945-845" + previousCredentialID := "6589-7841" + { + mockKeycloakAccountClient.EXPECT().MoveAfter(accessToken, realm, credentialID, previousCredentialID).Return(nil).Times(1) + mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_MOVE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) + + err := component.MoveCredential(ctx, credentialID, previousCredentialID) + + assert.Nil(t, err) + } + + { + mockKeycloakAccountClient.EXPECT().MoveToFirst(accessToken, realm, credentialID).Return(nil).Times(1) + mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_MOVE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) + + err := component.MoveCredential(ctx, credentialID, "null") + + assert.Nil(t, err) + } + + { + mockKeycloakAccountClient.EXPECT().MoveAfter(accessToken, realm, credentialID, previousCredentialID).Return(fmt.Errorf("Unexpected error")).Times(1) + err := component.MoveCredential(ctx, credentialID, previousCredentialID) + + assert.NotNil(t, err) + } + + { + mockKeycloakAccountClient.EXPECT().MoveToFirst(accessToken, realm, credentialID).Return(fmt.Errorf("Unexpected error")).Times(1) + err := component.MoveCredential(ctx, credentialID, "null") + + assert.NotNil(t, err) + } + +} diff --git a/pkg/account/endpoint.go b/pkg/account/endpoint.go index 1cd76d112..4d28fcef0 100644 --- a/pkg/account/endpoint.go +++ b/pkg/account/endpoint.go @@ -35,13 +35,17 @@ type AccountComponent interface { func MakeUpdatePasswordEndpoint(component AccountComponent) cs.Endpoint { return func(ctx context.Context, req interface{}) (interface{}, error) { var m = req.(map[string]string) - var body UpdatePasswordBody + var body api.UpdatePasswordBody err := json.Unmarshal([]byte(m["body"]), &body) if err != nil { return nil, http.CreateBadRequestError("Invalid body") } + if err = body.Validate(); err != nil { + return nil, http.CreateBadRequestError(err.Error()) + } + return nil, component.UpdatePassword(ctx, body.CurrentPassword, body.NewPassword, body.ConfirmPassword) } } diff --git a/pkg/account/endpoint_test.go b/pkg/account/endpoint_test.go index 5e10205da..71d842d0c 100644 --- a/pkg/account/endpoint_test.go +++ b/pkg/account/endpoint_test.go @@ -15,12 +15,12 @@ func TestMakeUpdatePasswordEndpoint(t *testing.T) { defer mockCtrl.Finish() mockAccountComponent := mock.NewAccountComponent(mockCtrl) - mockAccountComponent.EXPECT().UpdatePassword(gomock.Any(), "", "", "").Return(nil).Times(1) + mockAccountComponent.EXPECT().UpdatePassword(gomock.Any(), "password", "password2", "password2").Return(nil).Times(1) m := map[string]string{} { - m["body"] = "{}" + m["body"] = "{ \"currentPassword\":\"password\", \"newPassword\":\"password2\", \"confirmPassword\":\"password2\"}" _, err := MakeUpdatePasswordEndpoint(mockAccountComponent)(context.Background(), m) assert.Nil(t, err) } diff --git a/pkg/account/http.go b/pkg/account/http.go index 8a5a1a085..9700beb74 100644 --- a/pkg/account/http.go +++ b/pkg/account/http.go @@ -6,6 +6,7 @@ import ( commonhttp "github.com/cloudtrust/common-service/http" "github.com/cloudtrust/common-service/log" + account_api "github.com/cloudtrust/keycloak-bridge/api/account" "github.com/go-kit/kit/endpoint" http_transport "github.com/go-kit/kit/transport/http" ) @@ -13,15 +14,20 @@ import ( // MakeAccountHandler make an HTTP handler for an Account endpoint. func MakeAccountHandler(e endpoint.Endpoint, logger log.Logger) *http_transport.Server { return http_transport.NewServer(e, - decodeEventsRequest, + decodeAccountRequest, commonhttp.EncodeReply, http_transport.ServerErrorEncoder(commonhttp.ErrorHandler(logger)), ) } // decodeEventsRequest gets the HTTP parameters and body content -func decodeEventsRequest(ctx context.Context, req *http.Request) (interface{}, error) { - pathParams := map[string]string{"realm": "^[a-zA-Z0-9_-]{1,36}$"} - queryParams := map[string]string{} +func decodeAccountRequest(ctx context.Context, req *http.Request) (interface{}, error) { + var pathParams = map[string]string{ + "credentialID": account_api.RegExpID, + "previousCredentialID": account_api.RegExpIDNullable, + } + + var queryParams = map[string]string{} + return commonhttp.DecodeRequest(ctx, req, pathParams, queryParams) } diff --git a/pkg/account/http_test.go b/pkg/account/http_test.go index 87fcb86bb..fe11e89c1 100644 --- a/pkg/account/http_test.go +++ b/pkg/account/http_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/cloudtrust/common-service/log" + account_api "github.com/cloudtrust/keycloak-bridge/api/account" "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/cloudtrust/keycloak-bridge/pkg/account/mock" "github.com/golang/mock/gomock" @@ -19,23 +20,23 @@ import ( func TestHTTPAccountHandler(t *testing.T) { var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() - var mockComponent = mock.NewComponent(mockCtrl) + var mockAccountComponent = mock.NewAccountComponent(mockCtrl) r := mux.NewRouter() - r.Handle("/path/to/{realm}/password", MakeAccountHandler(keycloakb.ToGoKitEndpoint(MakeUpdatePasswordEndpoint(mockComponent)), log.NewNopLogger())) + r.Handle("/path/to/{realm}/password", MakeAccountHandler(keycloakb.ToGoKitEndpoint(MakeUpdatePasswordEndpoint(mockAccountComponent)), log.NewNopLogger())) ts := httptest.NewServer(r) defer ts.Close() { - body := UpdatePasswordBody{ + body := account_api.UpdatePasswordBody{ CurrentPassword: "current", NewPassword: "new", ConfirmPassword: "confirm", } json, _ := json.MarshalIndent(body, "", " ") - mockComponent.EXPECT().UpdatePassword(gomock.Any(), body.CurrentPassword, body.NewPassword, body.ConfirmPassword).Return(nil).Times(1) + mockAccountComponent.EXPECT().UpdatePassword(gomock.Any(), body.CurrentPassword, body.NewPassword, body.ConfirmPassword).Return(nil).Times(1) res, err := http.Post(ts.URL+"/path/to/master/password", "application/json", ioutil.NopCloser(bytes.NewBuffer(json))) diff --git a/pkg/account/mock_test.go b/pkg/account/mock_test.go index 6a88e299b..b0173a10d 100644 --- a/pkg/account/mock_test.go +++ b/pkg/account/mock_test.go @@ -1,6 +1,6 @@ package account -//go:generate mockgen -destination=./mock/acc_keycloak_client.go -package=mock -mock_names=KeycloakClient=AccKeycloakClient github.com/cloudtrust/keycloak-bridge/pkg/account KeycloakClient +//go:generate mockgen -destination=./mock/account_keycloak_client.go -package=mock -mock_names=KeycloakAccountClient=KeycloakAccountClient github.com/cloudtrust/keycloak-bridge/pkg/account KeycloakAccountClient //go:generate mockgen -destination=./mock/eventsdbmodule.go -package=mock -mock_names=EventsDBModule=EventsDBModule github.com/cloudtrust/common-service/database EventsDBModule //go:generate mockgen -destination=./mock/component.go -package=mock -mock_names=AccountComponent=AccountComponent,Component=Component github.com/cloudtrust/keycloak-bridge/pkg/account AccountComponent,Component //go:generate mockgen -destination=./mock/logger.go -package=mock -mock_names=Logger=Logger github.com/cloudtrust/keycloak-bridge/internal/keycloakb Logger From bbf489c6e4b2d1a096c5e861e75ecc1df02ed645 Mon Sep 17 00:00:00 2001 From: harture <31417989+harture@users.noreply.github.com> Date: Mon, 19 Aug 2019 11:12:19 +0200 Subject: [PATCH 02/24] Fixup: Dependency on a branch of keycloak-client instead of a version (cherry picked from commit a57187a3ca31a8c9ca180679306a35f7cb817b1f) --- api/account/api_test.go | 107 ---------------------------------------- 1 file changed, 107 deletions(-) delete mode 100644 api/account/api_test.go diff --git a/api/account/api_test.go b/api/account/api_test.go deleted file mode 100644 index 6bda05b7c..000000000 --- a/api/account/api_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package account_api - -import ( - "testing" - - kc "github.com/cloudtrust/keycloak-client" - "github.com/stretchr/testify/assert" -) - -func TestConvertCredential(t *testing.T) { - var credKc kc.CredentialRepresentation - var credType = "password" - var credID = "123456" - var configKc = "{}" - - credKc.Type = &credType - credKc.Id = &credID - credKc.CredentialData = nil - - assert.Equal(t, credKc.Type, ConvertCredential(&credKc).Type) - assert.Equal(t, credKc.Id, ConvertCredential(&credKc).Id) - assert.Nil(t, ConvertCredential(&credKc).CredentialData) - - credKc.CredentialData = &configKc - assert.NotNil(t, ConvertCredential(&credKc).CredentialData) - assert.Equal(t, "{}", *ConvertCredential(&credKc).CredentialData) -} - -func TestValidateUpdatePasswordRepresentation(t *testing.T) { - { - password := createValidUpdatePasswordBody() - assert.Nil(t, password.Validate()) - } - - value := "" - - { - password := createValidUpdatePasswordBody() - password.CurrentPassword = value - assert.NotNil(t, password.Validate()) - } - - { - password := createValidUpdatePasswordBody() - password.NewPassword = value - assert.NotNil(t, password.Validate()) - } - - { - password := createValidUpdatePasswordBody() - password.ConfirmPassword = value - assert.NotNil(t, password.Validate()) - } - -} - -func TestValidateCredentialRepresentation(t *testing.T) { - { - credential := createValidCredentialRepresentation() - assert.Nil(t, credential.Validate()) - } - - value := "" - - { - credential := createValidCredentialRepresentation() - credential.Id = &value - assert.NotNil(t, credential.Validate()) - } - - { - credential := createValidCredentialRepresentation() - credential.Type = &value - assert.NotNil(t, credential.Validate()) - } - - { - credential := createValidCredentialRepresentation() - credential.UserLabel = &value - assert.NotNil(t, credential.Validate()) - } - -} - -func createValidUpdatePasswordBody() UpdatePasswordBody { - password := "password" - - return UpdatePasswordBody{ - CurrentPassword: password, - NewPassword: password, - ConfirmPassword: password, - } -} - -func createValidCredentialRepresentation() CredentialRepresentation { - id := "f467ed7c-0a1d-4eee-9bb8-669c6f89c0ee" - credType := "otp" - userLabel := "my otp" - credData := "{}" - - return CredentialRepresentation{ - Id: &id, - Type: &credType, - CredentialData: &credData, - UserLabel: &userLabel, - } -} From f844594e84ab3e87c1a44682e55e2ac1e367ad7a Mon Sep 17 00:00:00 2001 From: Christophe Frattino Date: Mon, 19 Aug 2019 13:11:37 +0200 Subject: [PATCH 03/24] CLOUDTRUST-1561 Label can be empty (cherry picked from commit 32496e63045787bf0c105d5d560089fc7268284b) --- api/account/api.go | 101 --------------------------------------------- 1 file changed, 101 deletions(-) delete mode 100644 api/account/api.go diff --git a/api/account/api.go b/api/account/api.go deleted file mode 100644 index a681f7c62..000000000 --- a/api/account/api.go +++ /dev/null @@ -1,101 +0,0 @@ -package account - -import ( - "errors" - "regexp" - - kc "github.com/cloudtrust/keycloak-client" -) - -// UserRepresentation struct -type AccountRepresentation struct { - Username *string `json:"username,omitempty"` - Email *string `json:"email,omitempty"` - FirstName *string `json:"firstName,omitempty"` - LastName *string `json:"lastName,omitempty"` - PhoneNumber *string `json:"phoneNumber,omitempty"` -} - -// ConvertToAPIAccount creates an API account representation from a KC user representation -func ConvertToAPIAccount(userKc kc.UserRepresentation) AccountRepresentation { - var userRep AccountRepresentation - - userRep.Username = userKc.Username - userRep.Email = userKc.Email - userRep.FirstName = userKc.FirstName - userRep.LastName = userKc.LastName - - if userKc.Attributes != nil { - var m = *userKc.Attributes - - if m["phoneNumber"] != nil { - var phoneNumber = m["phoneNumber"][0] - userRep.PhoneNumber = &phoneNumber - } - } - return userRep -} - -// ConvertToKCUser creates a KC user representation from an API user -func ConvertToKCUser(user AccountRepresentation) kc.UserRepresentation { - var userRep kc.UserRepresentation - - userRep.Username = user.Username - userRep.Email = user.Email - userRep.FirstName = user.FirstName - userRep.LastName = user.LastName - - var attributes = make(map[string][]string) - - if user.PhoneNumber != nil { - attributes["phoneNumber"] = []string{*user.PhoneNumber} - } - - if len(attributes) > 0 { - userRep.Attributes = &attributes - } - - return userRep -} - -// Validators - -// Validate is a validator for AccountRepresentation -func (user AccountRepresentation) Validate() error { - if user.Username != nil && !matchesRegExp(*user.Username, RegExpUsername) { - return errors.New("Invalid username") - } - - if user.Email != nil && !matchesRegExp(*user.Email, RegExpEmail) { - return errors.New("Invalid email") - } - - if user.FirstName != nil && !matchesRegExp(*user.FirstName, RegExpFirstName) { - return errors.New("Invalid firstname") - } - - if user.LastName != nil && !matchesRegExp(*user.LastName, RegExpLastName) { - return errors.New("Invalid lastname") - } - - if user.PhoneNumber != nil && !matchesRegExp(*user.PhoneNumber, RegExpPhoneNumber) { - return errors.New("Invalid phone number") - } - - return nil -} - -func matchesRegExp(value, re string) bool { - res, _ := regexp.MatchString(re, value) - return res -} - -// Regular expressions for parameters validation -const ( - // User - RegExpUsername = `^[a-zA-Z0-9-_.]{1,128}$` - RegExpEmail = `^.+\@.+\..+` - RegExpFirstName = `^.{1,128}$` - RegExpLastName = `^.{1,128}$` - RegExpPhoneNumber = `^\+[1-9]\d{1,14}$` -) From 624505c5ab4c45059c62a122fab1b214c29aa037 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 11 Jul 2019 14:22:39 +0200 Subject: [PATCH 04/24] formatting errors --- cmd/keycloakb/keycloak_bridge.go | 2 ++ pkg/account/component.go | 15 ++------------- pkg/event/component.go | 5 +++++ pkg/event/endpoint.go | 2 +- pkg/event/http.go | 12 ++++++------ pkg/export/component.go | 5 +++++ pkg/export/http.go | 4 ++-- 7 files changed, 23 insertions(+), 22 deletions(-) diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index c46a153c1..337fc9a37 100644 --- a/cmd/keycloakb/keycloak_bridge.go +++ b/cmd/keycloakb/keycloak_bridge.go @@ -463,6 +463,8 @@ func main() { var exportEndpoint = export.MakeExportEndpoint(exportComponent) var exportSaveAndExportEndpoint = export.MakeStoreAndExportEndpoint(exportComponent) + commonhttp.SetEmitter(ComponentName) + // HTTP Internal Call Server (Event reception from Keycloak & Export API). go func() { var logger = log.With(logger, "transport", "http") diff --git a/pkg/account/component.go b/pkg/account/component.go index 4b4b3ef09..dbb4a29ce 100644 --- a/pkg/account/component.go +++ b/pkg/account/component.go @@ -56,24 +56,13 @@ func (c *component) UpdatePassword(ctx context.Context, currentPassword, newPass if currentPassword == newPassword || newPassword != confirmPassword { return commonhttp.Error{ - Status: http.StatusBadRequest, + Status: http.StatusBadRequest, + Message: ComponentName + ".", } } _, err := c.keycloakAccountClient.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 { diff --git a/pkg/event/component.go b/pkg/event/component.go index 48215074e..38f6b502c 100755 --- a/pkg/event/component.go +++ b/pkg/event/component.go @@ -13,6 +13,11 @@ import ( "github.com/cloudtrust/keycloak-bridge/api/event/fb" ) +var ( + // ComponentName is the name of the component. + ComponentName = "keycloak-bridge" +) + const ( timeFormat = "2006-01-02 15:04:05.000" ) diff --git a/pkg/event/endpoint.go b/pkg/event/endpoint.go index a4161d733..f7d309c80 100755 --- a/pkg/event/endpoint.go +++ b/pkg/event/endpoint.go @@ -20,7 +20,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(ComponentName+".wrongTypeRequest.%T", req) } } } diff --git a/pkg/event/http.go b/pkg/event/http.go index 71614840b..bb4f1d60f 100755 --- a/pkg/event/http.go +++ b/pkg/event/http.go @@ -51,7 +51,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, "cannotDecodeJSONRequest") } } @@ -61,7 +61,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, "cannotDecodeBase64ObjectFromRequest") } } @@ -69,14 +69,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, "cannotDecodeBase64ObjectFromRequest") } } // 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, "invalidFlatbufferLength") } return Request{ @@ -97,7 +97,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. @@ -110,5 +110,5 @@ func errorHandler(ctx context.Context, err error, w http.ResponseWriter) { w.WriteHeader(http.StatusInternalServerError) } - json.NewEncoder(w).Encode(map[string]interface{}{"error": err.Error()}) + w.Write([]byte(ComponentName + "." + err.Error())) } diff --git a/pkg/export/component.go b/pkg/export/component.go index 1400ac800..54b0d756f 100644 --- a/pkg/export/component.go +++ b/pkg/export/component.go @@ -9,6 +9,11 @@ import ( "github.com/pkg/errors" ) +var ( + // ComponentName is the name of the component. + ComponentName = "keycloak-bridge" +) + type component struct { componentName string componentVersion string diff --git a/pkg/export/http.go b/pkg/export/http.go index 86556ead6..391f51288 100755 --- a/pkg/export/http.go +++ b/pkg/export/http.go @@ -43,7 +43,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, "cannotMarshalResponse") } w.WriteHeader(http.StatusOK) @@ -55,5 +55,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(ComponentName + "." + err.Error())) } From 65b4e4ea63274a4fc44b277271621c04bbe7fe68 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 11 Jul 2019 16:07:33 +0200 Subject: [PATCH 05/24] more errors to format --- api/management/api.go | 40 ++++++++++++++-------------- internal/keycloakb/eventsdbmodule.go | 2 +- pkg/export/component.go | 6 ++--- pkg/export/module.go | 2 +- pkg/export/storage.go | 4 +-- pkg/management/component.go | 7 ++++- pkg/management/endpoint.go | 16 +++++------ pkg/management/http.go | 2 ++ 8 files changed, 43 insertions(+), 36 deletions(-) diff --git a/api/management/api.go b/api/management/api.go index 065be84b3..2511e6c08 100644 --- a/api/management/api.go +++ b/api/management/api.go @@ -228,45 +228,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("invalidUserID") } if user.Username != nil && !matchesRegExp(*user.Username, RegExpUsername) { - return errors.New("Invalid username") + return errors.New("invalidUsername") } if user.Email != nil && !matchesRegExp(*user.Email, RegExpEmail) { - return errors.New("Invalid email") + return errors.New("invalidEmail") } if user.FirstName != nil && !matchesRegExp(*user.FirstName, RegExpFirstName) { - return errors.New("Invalid firstname") + return errors.New("invalidFirstname") } if user.LastName != nil && !matchesRegExp(*user.LastName, RegExpLastName) { - return errors.New("Invalid lastname") + return errors.New("invalidLastname") } if user.PhoneNumber != nil && !matchesRegExp(*user.PhoneNumber, RegExpPhoneNumber) { - return errors.New("Invalid phone number") + return errors.New("invalidPhoneNumber") } if user.Label != nil && !matchesRegExp(*user.Label, RegExpLabel) { - return errors.New("Invalid label") + return errors.New("invalidLabel") } if user.Gender != nil && !matchesRegExp(*user.Gender, RegExpGender) { - return errors.New("Invalid gender") + return errors.New("invalidGender") } if user.BirthDate != nil && !matchesRegExp(*user.BirthDate, RegExpBirthDate) { - return errors.New("Invalid birthdate") + return errors.New("invalidBirthdate") } if user.Groups != nil { for _, groupID := range *(user.Groups) { if !matchesRegExp(groupID, RegExpID) { - return errors.New("Invalid group ID") + return errors.New("invalidGroupID") } } } @@ -274,13 +274,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("invalidRoleID") } } } if user.Locale != nil && !matchesRegExp(*user.Locale, RegExpLocale) { - return errors.New("Invalid locale") + return errors.New("invalidLocale") } return nil @@ -289,19 +289,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("invalidRoleID") } if role.Name != nil && !matchesRegExp(*role.Name, RegExpName) { - return errors.New("Invalid username") + return errors.New("invalidUsername") } if role.Description != nil && !matchesRegExp(*role.Description, RegExpDescription) { - return errors.New("Invalid description") + return errors.New("invalidDescription") } if role.ContainerId != nil && !matchesRegExp(*role.ContainerId, RegExpID) { - return errors.New("Invalid container ID") + return errors.New("invalidContainerID") } return nil @@ -310,7 +310,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("invalidPassword") } return nil @@ -319,11 +319,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("invalidDefaultClientID") } if config.DefaultRedirectUri != nil && !matchesRegExp(*config.DefaultRedirectUri, RegExpRedirectURI) { - return errors.New("Invalid default redirect uri") + return errors.New("invalidDefaultRedirectUri") } return nil @@ -332,7 +332,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("invalidRequiredAction") } return nil diff --git a/internal/keycloakb/eventsdbmodule.go b/internal/keycloakb/eventsdbmodule.go index e4c838898..16c098f6d 100644 --- a/internal/keycloakb/eventsdbmodule.go +++ b/internal/keycloakb/eventsdbmodule.go @@ -146,7 +146,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("invalidDurationLabel") } var res = int64(0) var row = cm.db.QueryRow(strings.ReplaceAll(selectConnectionsCount, "##INTERVAL##", durationLabel), realmName) diff --git a/pkg/export/component.go b/pkg/export/component.go index 54b0d756f..ebb0fe184 100644 --- a/pkg/export/component.go +++ b/pkg/export/component.go @@ -70,7 +70,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, "exportFailed.cannotGetKeycloakRealms") } } @@ -88,13 +88,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, "cannotMarshalConfig.component%sWithVersion%s", 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, "cannotSaveConfigInDB.component%sWithVersion%s", c.componentName, c.componentVersion) } return realmsMap, nil diff --git a/pkg/export/module.go b/pkg/export/module.go index 48dbbed11..309dc338e 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, "cannotGetListOfRealms") } for _, realm := range realms { diff --git a/pkg/export/storage.go b/pkg/export/storage.go index 940b0354b..c9d76dbe4 100644 --- a/pkg/export/storage.go +++ b/pkg/export/storage.go @@ -38,7 +38,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, "cannotUpdateConfig.component'%s'WithVersion'%s'", componentName, version) } return nil @@ -53,7 +53,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, "cannotUpdateConfig.component'%s'WithVersion'%s'", componentName, version) } return config, nil diff --git a/pkg/management/component.go b/pkg/management/component.go index 6b8034947..f0e0472f4 100644 --- a/pkg/management/component.go +++ b/pkg/management/component.go @@ -14,6 +14,11 @@ import ( kc "github.com/cloudtrust/keycloak-client" ) +var ( + // ComponentName is the name of the component. + ComponentName = "keycloak-bridge" +) + const ( initPasswordAction = "sms-password-set" ) @@ -875,7 +880,7 @@ func (c *component) UpdateRealmCustomConfiguration(ctx context.Context, realmNam if !match { return http.Error{ Status: 400, - Message: "Invalid client ID or redirect URI", + Message: "invalidClientIDOrRedirectURI", } } // transform customConfig object into JSON string diff --git a/pkg/management/endpoint.go b/pkg/management/endpoint.go index 7a74e9404..69079c8b8 100644 --- a/pkg/management/endpoint.go +++ b/pkg/management/endpoint.go @@ -120,7 +120,7 @@ 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, http.CreateBadRequestError("invalidBody") } if err = user.Validate(); err != nil { @@ -173,7 +173,7 @@ 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, http.CreateBadRequestError("invalidBody") } if err = user.Validate(); err != nil { @@ -252,7 +252,7 @@ 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, http.CreateBadRequestError("invalidBody") } for _, role := range roles { @@ -274,7 +274,7 @@ 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, http.CreateBadRequestError("invalidBody") } if err = password.Validate(); err != nil { @@ -322,7 +322,7 @@ 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, http.CreateBadRequestError("invalidBody") } for _, action := range actions { @@ -424,7 +424,7 @@ 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, http.CreateBadRequestError("invalidBody") } if err = role.Validate(); err != nil { @@ -466,7 +466,7 @@ func MakeUpdateRealmCustomConfigurationEndpoint(managementComponent ManagementCo var customConfig api.RealmCustomConfiguration if err = json.Unmarshal(configJSON, &customConfig); err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, http.CreateBadRequestError("invalidBody") } if err = customConfig.Validate(); err != nil { @@ -488,7 +488,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..8b5119c53 100644 --- a/pkg/management/http.go +++ b/pkg/management/http.go @@ -69,9 +69,11 @@ func managementErrorHandler(logger log.Logger) func(context.Context, error, http switch e := errors.Cause(err).(type) { case kc_client.HTTPError: w.WriteHeader(e.HTTPStatus) + w.Write([]byte(ComponentName + ".")) case ConvertLocationError: // 201-Created, even if ConvertLocationError occurs, the creation was a success w.WriteHeader(http.StatusCreated) + w.Write([]byte(ComponentName + ".")) default: defaultHandler(ctx, err, w) } From 69204da11022c05a7ed0b1aca7a7b905255d5f6b Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 11 Jul 2019 16:56:49 +0200 Subject: [PATCH 06/24] corrections --- api/management/api.go | 2 +- pkg/event/endpoint.go | 2 +- pkg/management/http_test.go | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/api/management/api.go b/api/management/api.go index 2511e6c08..9195729de 100644 --- a/api/management/api.go +++ b/api/management/api.go @@ -323,7 +323,7 @@ func (config RealmCustomConfiguration) Validate() error { } if config.DefaultRedirectUri != nil && !matchesRegExp(*config.DefaultRedirectUri, RegExpRedirectURI) { - return errors.New("invalidDefaultRedirectUri") + return errors.New("invalidDefaultRedirectURI") } return nil diff --git a/pkg/event/endpoint.go b/pkg/event/endpoint.go index f7d309c80..2e5c47f2b 100755 --- a/pkg/event/endpoint.go +++ b/pkg/event/endpoint.go @@ -20,7 +20,7 @@ func MakeEventEndpoint(c MuxComponent) cs.Endpoint { case Request: return nil, c.Event(ctx, r.Type, r.Object) default: - return nil, fmt.Errorf(ComponentName+".wrongTypeRequest.%T", req) + return nil, fmt.Errorf("wrongTypeRequest.%T", req) } } } diff --git a/pkg/management/http_test.go b/pkg/management/http_test.go index 075638015..c3ec7507c 100644 --- a/pkg/management/http_test.go +++ b/pkg/management/http_test.go @@ -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 From 3bf263138fea7964b4e3604fa1aaea789951f924 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 22 Aug 2019 14:46:51 +0200 Subject: [PATCH 07/24] fixing variables called in other packages --- internal/keycloakb/variables.go | 14 ++++++++++++++ pkg/account/component.go | 2 +- pkg/event/http.go | 3 ++- pkg/export/component.go | 2 +- pkg/management/http.go | 1 + 5 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 internal/keycloakb/variables.go diff --git a/internal/keycloakb/variables.go b/internal/keycloakb/variables.go new file mode 100644 index 000000000..53df0e634 --- /dev/null +++ b/internal/keycloakb/variables.go @@ -0,0 +1,14 @@ +package keycloakb + +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. + GitCommit = "unknown" +) diff --git a/pkg/account/component.go b/pkg/account/component.go index dbb4a29ce..8b5340e3e 100644 --- a/pkg/account/component.go +++ b/pkg/account/component.go @@ -57,7 +57,7 @@ func (c *component) UpdatePassword(ctx context.Context, currentPassword, newPass if currentPassword == newPassword || newPassword != confirmPassword { return commonhttp.Error{ Status: http.StatusBadRequest, - Message: ComponentName + ".", + Message: ComponentName + "." + "invalidValues", } } diff --git a/pkg/event/http.go b/pkg/event/http.go index bb4f1d60f..35dd4fe00 100755 --- a/pkg/event/http.go +++ b/pkg/event/http.go @@ -8,6 +8,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" @@ -110,5 +111,5 @@ func errorHandler(ctx context.Context, err error, w http.ResponseWriter) { w.WriteHeader(http.StatusInternalServerError) } - w.Write([]byte(ComponentName + "." + err.Error())) + w.Write([]byte(internal.ComponentName + "." + err.Error())) } diff --git a/pkg/export/component.go b/pkg/export/component.go index ebb0fe184..d3d77b086 100644 --- a/pkg/export/component.go +++ b/pkg/export/component.go @@ -70,7 +70,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, "exportFailed.cannotGetKeycloakRealms") + return nil, errors.Wrap(err, "cannotGetKeycloakRealms") } } diff --git a/pkg/management/http.go b/pkg/management/http.go index 8b5119c53..9390d3c50 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" From b435386b28f375d45b3fec46ad5cd34bf202e5e7 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 22 Aug 2019 14:47:57 +0200 Subject: [PATCH 08/24] fixing variables called in other packages --- Gopkg.lock | 4 ++-- pkg/event/http.go | 12 ++++++++++++ pkg/export/component.go | 9 ++------- pkg/export/http.go | 2 +- pkg/export/storage.go | 4 ++-- pkg/management/http.go | 1 + 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 9ee1125ab..e671f5e2b 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" @@ -170,7 +170,7 @@ version = "v1.0.0" [[projects]] - digest = "1:3c6faaeb500b7e6fadbe52c0b3fd62b6eed7801ed0d74bb3bd9577017df8d2f4" + digest = "1:2629521d27f3b04ce4d524cb52a25fdc77745071239c91d6fe9a7ce10131365a" name = "github.com/influxdata/influxdb" packages = [ "client/v2", diff --git a/pkg/event/http.go b/pkg/event/http.go index 35dd4fe00..42b498285 100755 --- a/pkg/event/http.go +++ b/pkg/event/http.go @@ -8,7 +8,12 @@ import ( "net/http" cs "github.com/cloudtrust/common-service" +<<<<<<< Updated upstream internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" +||||||| merged common ancestors +======= + main "github.com/cloudtrust/keycloak-bridge/cmd/main" +>>>>>>> Stashed changes "github.com/go-kit/kit/endpoint" http_transport "github.com/go-kit/kit/transport/http" "github.com/pkg/errors" @@ -111,5 +116,12 @@ func errorHandler(ctx context.Context, err error, w http.ResponseWriter) { w.WriteHeader(http.StatusInternalServerError) } +<<<<<<< Updated upstream w.Write([]byte(internal.ComponentName + "." + err.Error())) +||||||| merged common ancestors + w.Write([]byte(ComponentName + "." + err.Error())) +======= + w.Write([]byte(main.ComponentName + "." + err.Error())) + +>>>>>>> Stashed changes } diff --git a/pkg/export/component.go b/pkg/export/component.go index d3d77b086..a107e981f 100644 --- a/pkg/export/component.go +++ b/pkg/export/component.go @@ -9,11 +9,6 @@ import ( "github.com/pkg/errors" ) -var ( - // ComponentName is the name of the component. - ComponentName = "keycloak-bridge" -) - type component struct { componentName string componentVersion string @@ -88,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, "cannotMarshalConfig.component%sWithVersion%s", c.componentName, c.componentVersion) + return nil, errors.Wrapf(err, "cannotMarshalConfig.%s.%s", c.componentName, c.componentVersion) } err = c.s.Save(c.componentName, c.componentVersion, data) if err != nil { - return nil, errors.Wrapf(err, "cannotSaveConfigInDB.component%sWithVersion%s", c.componentName, c.componentVersion) + return nil, errors.Wrapf(err, "cannotSaveConfigInDB.%s.%s", c.componentName, c.componentVersion) } return realmsMap, nil diff --git a/pkg/export/http.go b/pkg/export/http.go index 391f51288..abb8259c2 100755 --- a/pkg/export/http.go +++ b/pkg/export/http.go @@ -55,5 +55,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(ComponentName + "." + err.Error())) + w.Write([]byte(main.ComponentName + "." + err.Error())) } diff --git a/pkg/export/storage.go b/pkg/export/storage.go index c9d76dbe4..1bad67f2e 100644 --- a/pkg/export/storage.go +++ b/pkg/export/storage.go @@ -38,7 +38,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, "cannotUpdateConfig.component'%s'WithVersion'%s'", componentName, version) + return errors.Wrapf(err, "cannotUpdateConfig.%s.%s", componentName, version) } return nil @@ -53,7 +53,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, "cannotUpdateConfig.component'%s'WithVersion'%s'", componentName, version) + return nil, errors.Wrapf(err, "cannotUpdateConfig.%s.%s", componentName, version) } return config, nil diff --git a/pkg/management/http.go b/pkg/management/http.go index 9390d3c50..df9247823 100644 --- a/pkg/management/http.go +++ b/pkg/management/http.go @@ -77,6 +77,7 @@ func managementErrorHandler(logger log.Logger) func(context.Context, error, http w.Write([]byte(ComponentName + ".")) default: defaultHandler(ctx, err, w) + } } } From fae4babbeecf34244b54e40f7a04fe788835a677 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 22 Aug 2019 14:52:53 +0200 Subject: [PATCH 09/24] merge fix --- pkg/event/http.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pkg/event/http.go b/pkg/event/http.go index 42b498285..cb56abe98 100755 --- a/pkg/event/http.go +++ b/pkg/event/http.go @@ -8,12 +8,7 @@ import ( "net/http" cs "github.com/cloudtrust/common-service" -<<<<<<< Updated upstream internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" -||||||| merged common ancestors -======= - main "github.com/cloudtrust/keycloak-bridge/cmd/main" ->>>>>>> Stashed changes "github.com/go-kit/kit/endpoint" http_transport "github.com/go-kit/kit/transport/http" "github.com/pkg/errors" @@ -115,13 +110,5 @@ func errorHandler(ctx context.Context, err error, w http.ResponseWriter) { default: w.WriteHeader(http.StatusInternalServerError) } - -<<<<<<< Updated upstream w.Write([]byte(internal.ComponentName + "." + err.Error())) -||||||| merged common ancestors - w.Write([]byte(ComponentName + "." + err.Error())) -======= - w.Write([]byte(main.ComponentName + "." + err.Error())) - ->>>>>>> Stashed changes } From ed0582b877a64d3b77eaea0b70da92c5eca00c24 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 22 Aug 2019 17:19:40 +0200 Subject: [PATCH 10/24] fixup! merge fix --- pkg/export/http.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/export/http.go b/pkg/export/http.go index abb8259c2..ea02d3b77 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" @@ -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(main.ComponentName + "." + err.Error())) + w.Write([]byte(internal.ComponentName + "." + err.Error())) } From e3a0e5388bfdf72c29896ddcc322a8999434890b Mon Sep 17 00:00:00 2001 From: Laurent Pages Date: Thu, 29 Aug 2019 16:11:06 +0200 Subject: [PATCH 11/24] fix rebase --- pkg/account/component.go | 2 +- pkg/management/component.go | 5 ----- pkg/management/http.go | 6 +++--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/pkg/account/component.go b/pkg/account/component.go index 8b5340e3e..25634f68b 100644 --- a/pkg/account/component.go +++ b/pkg/account/component.go @@ -57,7 +57,7 @@ func (c *component) UpdatePassword(ctx context.Context, currentPassword, newPass if currentPassword == newPassword || newPassword != confirmPassword { return commonhttp.Error{ Status: http.StatusBadRequest, - Message: ComponentName + "." + "invalidValues", + Message: internal.ComponentName + "." + "invalidValues", } } diff --git a/pkg/management/component.go b/pkg/management/component.go index f0e0472f4..5b5e07cf8 100644 --- a/pkg/management/component.go +++ b/pkg/management/component.go @@ -14,11 +14,6 @@ import ( kc "github.com/cloudtrust/keycloak-client" ) -var ( - // ComponentName is the name of the component. - ComponentName = "keycloak-bridge" -) - const ( initPasswordAction = "sms-password-set" ) diff --git a/pkg/management/http.go b/pkg/management/http.go index df9247823..74d5aff7c 100644 --- a/pkg/management/http.go +++ b/pkg/management/http.go @@ -70,14 +70,14 @@ func managementErrorHandler(logger log.Logger) func(context.Context, error, http switch e := errors.Cause(err).(type) { case kc_client.HTTPError: w.WriteHeader(e.HTTPStatus) - w.Write([]byte(ComponentName + ".")) + w.Write([]byte(internal.ComponentName + ".")) case ConvertLocationError: // 201-Created, even if ConvertLocationError occurs, the creation was a success w.WriteHeader(http.StatusCreated) - w.Write([]byte(ComponentName + ".")) + w.Write([]byte(internal.ComponentName + ".")) default: defaultHandler(ctx, err, w) - + } } } From 4eb74a075336172adc460f26622a5a6aa5a37369 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Fri, 30 Aug 2019 15:33:20 +0200 Subject: [PATCH 12/24] variable refactoring --- api/management/api.go | 40 ++++----- cmd/keycloakb/keycloak_bridge.go | 120 +++++++++++++-------------- internal/keycloakb/eventsdbmodule.go | 2 +- internal/keycloakb/variables.go | 4 - pkg/event/http.go | 7 +- pkg/management/http.go | 4 +- 6 files changed, 84 insertions(+), 93 deletions(-) diff --git a/api/management/api.go b/api/management/api.go index 9195729de..ba12f947d 100644 --- a/api/management/api.go +++ b/api/management/api.go @@ -228,45 +228,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("invalidUserID") + return errors.New("invalidParameter.userID") } if user.Username != nil && !matchesRegExp(*user.Username, RegExpUsername) { - return errors.New("invalidUsername") + return errors.New("invalidParameter.username") } if user.Email != nil && !matchesRegExp(*user.Email, RegExpEmail) { - return errors.New("invalidEmail") + return errors.New("invalidParameter.email") } if user.FirstName != nil && !matchesRegExp(*user.FirstName, RegExpFirstName) { - return errors.New("invalidFirstname") + return errors.New("invalidParameter.firstname") } if user.LastName != nil && !matchesRegExp(*user.LastName, RegExpLastName) { - return errors.New("invalidLastname") + return errors.New("invalidParameter.lastname") } if user.PhoneNumber != nil && !matchesRegExp(*user.PhoneNumber, RegExpPhoneNumber) { - return errors.New("invalidPhoneNumber") + return errors.New("invalidParameter.phoneNumber") } if user.Label != nil && !matchesRegExp(*user.Label, RegExpLabel) { - return errors.New("invalidLabel") + return errors.New("invalidParameter.label") } if user.Gender != nil && !matchesRegExp(*user.Gender, RegExpGender) { - return errors.New("invalidGender") + return errors.New("invalidParameter.gender") } if user.BirthDate != nil && !matchesRegExp(*user.BirthDate, RegExpBirthDate) { - return errors.New("invalidBirthdate") + return errors.New("invalidParameter.birthdate") } if user.Groups != nil { for _, groupID := range *(user.Groups) { if !matchesRegExp(groupID, RegExpID) { - return errors.New("invalidGroupID") + return errors.New("invalidParameter.groupID") } } } @@ -274,13 +274,13 @@ func (user UserRepresentation) Validate() error { if user.Roles != nil { for _, roleID := range *(user.Roles) { if !matchesRegExp(roleID, RegExpID) { - return errors.New("invalidRoleID") + return errors.New("invalidParameter.roleID") } } } if user.Locale != nil && !matchesRegExp(*user.Locale, RegExpLocale) { - return errors.New("invalidLocale") + return errors.New("invalidParameter.locale") } return nil @@ -289,19 +289,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("invalidRoleID") + return errors.New("invalidParameter.roleID") } if role.Name != nil && !matchesRegExp(*role.Name, RegExpName) { - return errors.New("invalidUsername") + return errors.New("invalidParameter.username") } if role.Description != nil && !matchesRegExp(*role.Description, RegExpDescription) { - return errors.New("invalidDescription") + return errors.New("invalidParameter.description") } if role.ContainerId != nil && !matchesRegExp(*role.ContainerId, RegExpID) { - return errors.New("invalidContainerID") + return errors.New("invalidParameter.containerID") } return nil @@ -310,7 +310,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("invalidPassword") + return errors.New("invalidParameter.password") } return nil @@ -319,11 +319,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("invalidDefaultClientID") + return errors.New("invalidParameter.defaultClientID") } if config.DefaultRedirectUri != nil && !matchesRegExp(*config.DefaultRedirectUri, RegExpRedirectURI) { - return errors.New("invalidDefaultRedirectURI") + return errors.New("invalidParameter.defaultRedirectURI") } return nil @@ -332,7 +332,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("invalidRequiredAction") + return errors.New("invalidParameter.requiredAction") } return nil diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index 337fc9a37..04971ef7a 100644 --- a/cmd/keycloakb/keycloak_bridge.go +++ b/cmd/keycloakb/keycloak_bridge.go @@ -43,12 +43,6 @@ 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. @@ -72,7 +66,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.keycloakb.ComponentName, "component_id", ComponentID, "component_version", keycloakb.Version) } defer logger.Info("msg", "Shutdown") @@ -133,7 +127,7 @@ func main() { ) // Unique ID generator - var idGenerator = idgenerator.New(ComponentName, ComponentID) + var idGenerator = idgenerator.New(keycloakb.keycloakb.ComponentName, keycloakb.ComponentID) // Critical errors channel. var errc = make(chan error) @@ -235,7 +229,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 @@ -459,11 +453,11 @@ 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) - commonhttp.SetEmitter(ComponentName) + commonhttp.SetEmitter(keycloakb.ComponentName) // HTTP Internal Call Server (Event reception from Keycloak & Export API). go func() { @@ -472,8 +466,8 @@ func main() { var route = mux.NewRouter() - // Version. - route.Handle("/", commonhttp.MakeVersionHandler(ComponentName, ComponentID, Version, Environment, GitCommit)) + // keycloakb.Version. + route.Handle("/", commonhttp.Makekeycloakb.VersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit)) // Event. var eventSubroute = route.PathPrefix("/event").Subrouter() @@ -481,8 +475,8 @@ func main() { var eventHandler http.Handler { eventHandler = event.MakeHTTPEventHandler(eventEndpoints.Endpoint) - 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) @@ -511,23 +505,23 @@ func main() { var route = mux.NewRouter() - // Version. - route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(ComponentName, ComponentID, Version, Environment, GitCommit))) + // keycloakb.Version. + route.Handle("/", http.HandlerFunc(commonhttp.Makekeycloakb.VersionHandler(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) @@ -536,42 +530,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) @@ -630,8 +624,8 @@ func main() { var route = mux.NewRouter() - // Version. - route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(ComponentName, ComponentID, Version, Environment, GitCommit))) + // keycloakb.Version. + route.Handle("/", http.HandlerFunc(commonhttp.Makekeycloakb.VersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit))) // Account var updatePasswordHandler = configureAccountHandler(ComponentName, ComponentID, idGenerator, keycloakClient, audienceRequired, tracer, logger)(accountEndpoints.UpdatePassword) @@ -785,49 +779,49 @@ func config(logger log.Logger) *viper.Viper { return v } -func configureEventsHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureEventsHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = events.MakeEventsHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } } -func configureStatisiticsHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureStatisiticsHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = statistics.MakeStatisticsHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } } -func configureManagementHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureManagementHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = management.MakeManagementHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } } -func configureRightsHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, authorizationManager security.AuthorizationManager, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) http.Handler { +func configureRightsHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, authorizationManager security.AuthorizationManager, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) http.Handler { var handler http.Handler handler = commonhttp.MakeRightsHandler(authorizationManager) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } -func configureAccountHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureAccountHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = account.MakeAccountHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } diff --git a/internal/keycloakb/eventsdbmodule.go b/internal/keycloakb/eventsdbmodule.go index 16c098f6d..6f2a7fb3c 100644 --- a/internal/keycloakb/eventsdbmodule.go +++ b/internal/keycloakb/eventsdbmodule.go @@ -146,7 +146,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("invalidDurationLabel") + return 0, errors.New("invalidParameter.durationLabel") } var res = int64(0) var row = cm.db.QueryRow(strings.ReplaceAll(selectConnectionsCount, "##INTERVAL##", durationLabel), realmName) diff --git a/internal/keycloakb/variables.go b/internal/keycloakb/variables.go index 53df0e634..6da9aa92c 100644 --- a/internal/keycloakb/variables.go +++ b/internal/keycloakb/variables.go @@ -7,8 +7,4 @@ var ( ComponentID = "unknown" // Version of the component. Version = "1.1" - // Environment is filled by the compiler. - Environment = "unknown" - // GitCommit is filled by the compiler. - GitCommit = "unknown" ) diff --git a/pkg/event/http.go b/pkg/event/http.go index cb56abe98..1270d982b 100755 --- a/pkg/event/http.go +++ b/pkg/event/http.go @@ -52,7 +52,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, "cannotDecodeJSONRequest") + return nil, errors.Wrap(err, "invalidJSONRequest") } } @@ -62,7 +62,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, "cannotDecodeBase64ObjectFromRequest") + return nil, errors.Wrap(err, "invalidBase64Object") } } @@ -70,7 +70,7 @@ 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, "cannotDecodeBase64ObjectFromRequest") + return nil, errors.Wrap(err, "invalidBase64Object") } } @@ -110,5 +110,6 @@ func errorHandler(ctx context.Context, err error, w http.ResponseWriter) { default: w.WriteHeader(http.StatusInternalServerError) } + // no leakage issue as this is done internally between the bridge and keycloak w.Write([]byte(internal.ComponentName + "." + err.Error())) } diff --git a/pkg/management/http.go b/pkg/management/http.go index 74d5aff7c..7ff683403 100644 --- a/pkg/management/http.go +++ b/pkg/management/http.go @@ -70,11 +70,11 @@ func managementErrorHandler(logger log.Logger) func(context.Context, error, http switch e := errors.Cause(err).(type) { case kc_client.HTTPError: w.WriteHeader(e.HTTPStatus) - w.Write([]byte(internal.ComponentName + ".")) + w.Write([]byte(internal.ComponentName + "." + "unknowError")) case ConvertLocationError: // 201-Created, even if ConvertLocationError occurs, the creation was a success w.WriteHeader(http.StatusCreated) - w.Write([]byte(internal.ComponentName + ".")) + w.Write([]byte(internal.ComponentName + "." + "unknowError")) default: defaultHandler(ctx, err, w) From 0e0c64444cf087fcab1617d9ba4f3fa91cba620e Mon Sep 17 00:00:00 2001 From: bsoniam Date: Fri, 30 Aug 2019 16:50:57 +0200 Subject: [PATCH 13/24] variable refactoring2 --- api/management/api.go | 41 +++++++++++++++-------------- cmd/keycloakb/keycloak_bridge.go | 34 +++++++++++++----------- internal/keycloakb/errormessages.go | 30 +++++++++++++++++++++ internal/keycloakb/variables.go | 2 -- 4 files changed, 69 insertions(+), 38 deletions(-) create mode 100644 internal/keycloakb/errormessages.go diff --git a/api/management/api.go b/api/management/api.go index ba12f947d..1b33772ad 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" ) @@ -228,45 +229,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("invalidParameter.userID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.UserId) } if user.Username != nil && !matchesRegExp(*user.Username, RegExpUsername) { - return errors.New("invalidParameter.username") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Username) } if user.Email != nil && !matchesRegExp(*user.Email, RegExpEmail) { - return errors.New("invalidParameter.email") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Email) } if user.FirstName != nil && !matchesRegExp(*user.FirstName, RegExpFirstName) { - return errors.New("invalidParameter.firstname") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Firstname) } if user.LastName != nil && !matchesRegExp(*user.LastName, RegExpLastName) { - return errors.New("invalidParameter.lastname") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Lastname) } if user.PhoneNumber != nil && !matchesRegExp(*user.PhoneNumber, RegExpPhoneNumber) { - return errors.New("invalidParameter.phoneNumber") + return errors.New(internal.MsgErrInvalidParam + "." + internal.PhoneNumber) } if user.Label != nil && !matchesRegExp(*user.Label, RegExpLabel) { - return errors.New("invalidParameter.label") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Label) } if user.Gender != nil && !matchesRegExp(*user.Gender, RegExpGender) { - return errors.New("invalidParameter.gender") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Gender) } if user.BirthDate != nil && !matchesRegExp(*user.BirthDate, RegExpBirthDate) { - return errors.New("invalidParameter.birthdate") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Birthdate) } if user.Groups != nil { for _, groupID := range *(user.Groups) { if !matchesRegExp(groupID, RegExpID) { - return errors.New("invalidParameter.groupID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.GroudId) } } } @@ -274,13 +275,13 @@ func (user UserRepresentation) Validate() error { if user.Roles != nil { for _, roleID := range *(user.Roles) { if !matchesRegExp(roleID, RegExpID) { - return errors.New("invalidParameter.roleID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.RoleId) } } } if user.Locale != nil && !matchesRegExp(*user.Locale, RegExpLocale) { - return errors.New("invalidParameter.locale") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Locale) } return nil @@ -289,19 +290,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("invalidParameter.roleID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.RoleId) } if role.Name != nil && !matchesRegExp(*role.Name, RegExpName) { - return errors.New("invalidParameter.username") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Username) } if role.Description != nil && !matchesRegExp(*role.Description, RegExpDescription) { - return errors.New("invalidParameter.description") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Description) } if role.ContainerId != nil && !matchesRegExp(*role.ContainerId, RegExpID) { - return errors.New("invalidParameter.containerID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.ContainerId) } return nil @@ -310,7 +311,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("invalidParameter.password") + return errors.New(internal.MsgErrInvalidParam + "." + internal.Password) } return nil @@ -319,11 +320,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("invalidParameter.defaultClientID") + return errors.New(internal.MsgErrInvalidParam + "." + internal.DefaultClientID) } if config.DefaultRedirectUri != nil && !matchesRegExp(*config.DefaultRedirectUri, RegExpRedirectURI) { - return errors.New("invalidParameter.defaultRedirectURI") + return errors.New(internal.MsgErrInvalidParam + "." + internal.DefaultRedirectURI) } return nil @@ -332,7 +333,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("invalidParameter.requiredAction") + return errors.New(internal.MsgErrInvalidParam + "." + internal.RequiredAction) } return nil diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index 04971ef7a..acb4f384c 100644 --- a/cmd/keycloakb/keycloak_bridge.go +++ b/cmd/keycloakb/keycloak_bridge.go @@ -43,6 +43,8 @@ import ( ) var ( + // ComponentID is an unique ID generated at component startup. + ComponentID = "unknown" // Environment is filled by the compiler. Environment = "unknown" // GitCommit is filled by the compiler. @@ -54,7 +56,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)) @@ -66,7 +68,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", keycloakb.keycloakb.ComponentName, "component_id", ComponentID, "component_version", keycloakb.Version) + logger = log.With(logger, "component_name", keycloakb.ComponentName, "component_id", ComponentID, "component_version", keycloakb.Version) } defer logger.Info("msg", "Shutdown") @@ -127,7 +129,7 @@ func main() { ) // Unique ID generator - var idGenerator = idgenerator.New(keycloakb.keycloakb.ComponentName, keycloakb.ComponentID) + var idGenerator = idgenerator.New(keycloakb.ComponentName, ComponentID) // Critical errors channel. var errc = make(chan error) @@ -467,7 +469,7 @@ func main() { var route = mux.NewRouter() // keycloakb.Version. - route.Handle("/", commonhttp.Makekeycloakb.VersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit)) + route.Handle("/", commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit)) // Event. var eventSubroute = route.PathPrefix("/event").Subrouter() @@ -506,7 +508,7 @@ func main() { var route = mux.NewRouter() // keycloakb.Version. - route.Handle("/", http.HandlerFunc(commonhttp.Makekeycloakb.VersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit))) + route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit))) // Rights var rightsHandler = configureRightsHandler(keycloakb.ComponentName, ComponentID, idGenerator, authorizationManager, keycloakClient, audienceRequired, tracer, logger) @@ -625,7 +627,7 @@ func main() { var route = mux.NewRouter() // keycloakb.Version. - route.Handle("/", http.HandlerFunc(commonhttp.Makekeycloakb.VersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.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) @@ -779,49 +781,49 @@ func config(logger log.Logger) *viper.Viper { return v } -func configureEventsHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureEventsHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = events.MakeEventsHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } } -func configureStatisiticsHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureStatisiticsHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = statistics.MakeStatisticsHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } } -func configureManagementHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureManagementHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = management.MakeManagementHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } } -func configureRightsHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, authorizationManager security.AuthorizationManager, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) http.Handler { +func configureRightsHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, authorizationManager security.AuthorizationManager, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) http.Handler { var handler http.Handler handler = commonhttp.MakeRightsHandler(authorizationManager) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } -func configureAccountHandler(keycloakb.ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { +func configureAccountHandler(ComponentName string, ComponentID string, idGenerator idgenerator.IDGenerator, keycloakClient *keycloak.Client, audienceRequired string, tracer tracing.OpentracingClient, logger log.Logger) func(endpoint endpoint.Endpoint) http.Handler { return func(endpoint endpoint.Endpoint) http.Handler { var handler http.Handler handler = account.MakeAccountHandler(endpoint, logger) - handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, keycloakb.ComponentName, ComponentID)(handler) + handler = middleware.MakeHTTPCorrelationIDMW(idGenerator, tracer, logger, ComponentName, ComponentID)(handler) handler = middleware.MakeHTTPOIDCTokenValidationMW(keycloakClient, audienceRequired, logger)(handler) return handler } diff --git a/internal/keycloakb/errormessages.go b/internal/keycloakb/errormessages.go new file mode 100644 index 000000000..d89ecdbb8 --- /dev/null +++ b/internal/keycloakb/errormessages.go @@ -0,0 +1,30 @@ +package keycloakb + +const ( + MsgErrInvalidParam = "invalidParameter" + + CurrentPassword = "currentPassword" + NewPassword = "newPassword" + ConfirmPassword = "confirmPassword" + Password = "password" + Type = "type" + Id = "id" + Label = "label" + + UserId = "userID" + Username = "username" + Email = "email" + Firstname = "firstname" + Lastname = "lastname" + PhoneNumber = "phoneNumber" + Gender = "gender" + Birthdate = "birthdate" + GroudId = "groudId" + RoleId = "roleId" + Locale = "locale" + Description = "description" + ContainerId = "containerId" + DefaultClientID = "defaultClientID" + DefaultRedirectURI = "defaultRedirectURI" + RequiredAction = "requiredAction" +) diff --git a/internal/keycloakb/variables.go b/internal/keycloakb/variables.go index 6da9aa92c..518aefbf2 100644 --- a/internal/keycloakb/variables.go +++ b/internal/keycloakb/variables.go @@ -3,8 +3,6 @@ package keycloakb 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" ) From e421da88445bc3273eb57478e696024423cbe0ba Mon Sep 17 00:00:00 2001 From: bsoniam Date: Mon, 2 Sep 2019 16:23:03 +0200 Subject: [PATCH 14/24] added more error messages --- internal/keycloakb/errormessages.go | 40 +++++++++++++++++++++-------- pkg/account/endpoint.go | 3 ++- pkg/event/endpoint.go | 3 ++- pkg/event/http.go | 8 +++--- pkg/events/component.go | 4 +-- pkg/export/component.go | 6 ++--- pkg/export/http.go | 2 +- pkg/export/module.go | 2 +- pkg/export/storage.go | 5 ++-- pkg/management/endpoint.go | 19 +++++++------- pkg/management/http.go | 4 +-- 11 files changed, 60 insertions(+), 36 deletions(-) diff --git a/internal/keycloakb/errormessages.go b/internal/keycloakb/errormessages.go index d89ecdbb8..377181641 100644 --- a/internal/keycloakb/errormessages.go +++ b/internal/keycloakb/errormessages.go @@ -1,25 +1,36 @@ package keycloakb const ( - MsgErrInvalidParam = "invalidParameter" - - CurrentPassword = "currentPassword" - NewPassword = "newPassword" - ConfirmPassword = "confirmPassword" - Password = "password" - Type = "type" - Id = "id" - Label = "label" + 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 = "groudId" + GroudId = "groupId" + GroudIds = "groupIds" RoleId = "roleId" Locale = "locale" Description = "description" @@ -27,4 +38,13 @@ const ( DefaultClientID = "defaultClientID" DefaultRedirectURI = "defaultRedirectURI" RequiredAction = "requiredAction" + DurationLabel = "durationLabel" + Body = "body" + Flatbuffer = "flatbuffer" + Realm = "realm" + KeycloakRealms = "keycloakRealms" + Config = "config" + Response = "response" + ListOfRealms = "listOfRealms" + Groups = "groups" ) diff --git a/pkg/account/endpoint.go b/pkg/account/endpoint.go index 4d28fcef0..8ad9090ea 100644 --- a/pkg/account/endpoint.go +++ b/pkg/account/endpoint.go @@ -7,6 +7,7 @@ import ( cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/http" api "github.com/cloudtrust/keycloak-bridge/api/account" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/go-kit/kit/endpoint" ) @@ -65,7 +66,7 @@ func MakeUpdateAccountEndpoint(component AccountComponent) cs.Endpoint { err := json.Unmarshal([]byte(m["body"]), &body) if err != nil { - return nil, http.CreateBadRequestError("Invalid body") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = body.Validate(); err != nil { diff --git a/pkg/event/endpoint.go b/pkg/event/endpoint.go index 2e5c47f2b..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("wrongTypeRequest.%T", req) + return nil, fmt.Errorf(internal.MsgErrWrongTypeRequest+".%T", req) } } } diff --git a/pkg/event/http.go b/pkg/event/http.go index 1270d982b..942d7886d 100755 --- a/pkg/event/http.go +++ b/pkg/event/http.go @@ -52,7 +52,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, "invalidJSONRequest") + return nil, errors.Wrap(err, internal.MsgErrInvalidJSONRequest) } } @@ -62,7 +62,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, "invalidBase64Object") + return nil, errors.Wrap(err, internal.MsgErrInvalidBase64Object) } } @@ -70,14 +70,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, "invalidBase64Object") + 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, "invalidFlatbufferLength") + return nil, errors.Wrap(err, internal.MsgErrInvalidLength+"."+internal.Flatbuffer) } return Request{ diff --git a/pkg/events/component.go b/pkg/events/component.go index c7e4d4452..abebf9b5c 100644 --- a/pkg/events/component.go +++ b/pkg/events/component.go @@ -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{}, http.CreateMissingParameterError(app.Realm) } if val, ok := params["userID"]; !ok || len(val) == 0 { - return api.AuditEventsRepresentation{}, http.CreateMissingParameterError("userID") + return api.AuditEventsRepresentation{}, http.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 a107e981f..076b70f0a 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, "cannotGetKeycloakRealms") + 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, "cannotMarshalConfig.%s.%s", c.componentName, c.componentVersion) + return nil, errors.Wrapf(err, internal.MsgErrCannotMarshal+"."+internal.Config+".%s.%s", c.componentName, c.componentVersion) } err = c.s.Save(c.componentName, c.componentVersion, data) if err != nil { - return nil, errors.Wrapf(err, "cannotSaveConfigInDB.%s.%s", c.componentName, c.componentVersion) + return nil, errors.Wrapf(err, internal.MsgErrCannotSaveConfigInDB+".%s.%s", c.componentName, c.componentVersion) } return realmsMap, nil diff --git a/pkg/export/http.go b/pkg/export/http.go index ea02d3b77..13350a3b4 100755 --- a/pkg/export/http.go +++ b/pkg/export/http.go @@ -44,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, "cannotMarshalResponse") + return errors.Wrap(err, internal.MsgErrCannotMarshal+internal.Response) } w.WriteHeader(http.StatusOK) diff --git a/pkg/export/module.go b/pkg/export/module.go index 309dc338e..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, "cannotGetListOfRealms") + 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 1bad67f2e..2cf452c4f 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, "cannotUpdateConfig.%s.%s", componentName, version) + return errors.Wrapf(err, internal.MsgErrCannotUpdate+"."+internal.Config+".%s.%s", 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, "cannotUpdateConfig.%s.%s", componentName, version) + return nil, errors.Wrapf(err, internal.MsgErrCannotUpdate+"."+internal.Config+".%s.%s", componentName, version) } return config, nil diff --git a/pkg/management/endpoint.go b/pkg/management/endpoint.go index 69079c8b8..57c5bf8c7 100644 --- a/pkg/management/endpoint.go +++ b/pkg/management/endpoint.go @@ -10,6 +10,7 @@ import ( cs "github.com/cloudtrust/common-service" "github.com/cloudtrust/common-service/http" api "github.com/cloudtrust/keycloak-bridge/api/management" + internal "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/go-kit/kit/endpoint" ) @@ -120,7 +121,7 @@ func MakeCreateUserEndpoint(managementComponent ManagementComponent) cs.Endpoint var user api.UserRepresentation if err = json.Unmarshal([]byte(m["body"]), &user); err != nil { - return nil, http.CreateBadRequestError("invalidBody") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = user.Validate(); err != nil { @@ -128,7 +129,7 @@ func MakeCreateUserEndpoint(managementComponent ManagementComponent) cs.Endpoint } if user.Groups == nil || len(*user.Groups) == 0 { - return nil, http.CreateMissingParameterError("groups") + return nil, http.CreateMissingParameterError(internal.Groups) } var keycloakLocation string @@ -173,7 +174,7 @@ func MakeUpdateUserEndpoint(managementComponent ManagementComponent) cs.Endpoint var user api.UserRepresentation if err = json.Unmarshal([]byte(m["body"]), &user); err != nil { - return nil, http.CreateBadRequestError("invalidBody") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + internal.Body) } if err = user.Validate(); err != nil { @@ -198,7 +199,7 @@ func MakeGetUsersEndpoint(managementComponent ManagementComponent) cs.Endpoint { _, ok := m["groupIds"] if !ok { - return nil, http.CreateMissingParameterError("groupIds") + return nil, http.CreateMissingParameterError(internal.GroudIds) } groupIDs := strings.Split(m["groupIds"], ",") @@ -252,7 +253,7 @@ func MakeAddClientRolesToUserEndpoint(managementComponent ManagementComponent) c var roles []api.RoleRepresentation if err = json.Unmarshal([]byte(m["body"]), &roles); err != nil { - return nil, http.CreateBadRequestError("invalidBody") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } for _, role := range roles { @@ -274,7 +275,7 @@ func MakeResetPasswordEndpoint(managementComponent ManagementComponent) cs.Endpo var password api.PasswordRepresentation if err = json.Unmarshal([]byte(m["body"]), &password); err != nil { - return nil, http.CreateBadRequestError("invalidBody") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = password.Validate(); err != nil { @@ -322,7 +323,7 @@ func MakeExecuteActionsEmailEndpoint(managementComponent ManagementComponent) cs var actions []api.RequiredAction if err = json.Unmarshal([]byte(m["body"]), &actions); err != nil { - return nil, http.CreateBadRequestError("invalidBody") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } for _, action := range actions { @@ -424,7 +425,7 @@ func MakeCreateClientRoleEndpoint(managementComponent ManagementComponent) cs.En var role api.RoleRepresentation if err = json.Unmarshal([]byte(m["body"]), &role); err != nil { - return nil, http.CreateBadRequestError("invalidBody") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = role.Validate(); err != nil { @@ -466,7 +467,7 @@ func MakeUpdateRealmCustomConfigurationEndpoint(managementComponent ManagementCo var customConfig api.RealmCustomConfiguration if err = json.Unmarshal(configJSON, &customConfig); err != nil { - return nil, http.CreateBadRequestError("invalidBody") + return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } if err = customConfig.Validate(); err != nil { diff --git a/pkg/management/http.go b/pkg/management/http.go index 7ff683403..dcf54559f 100644 --- a/pkg/management/http.go +++ b/pkg/management/http.go @@ -70,11 +70,11 @@ func managementErrorHandler(logger log.Logger) func(context.Context, error, http switch e := errors.Cause(err).(type) { case kc_client.HTTPError: w.WriteHeader(e.HTTPStatus) - w.Write([]byte(internal.ComponentName + "." + "unknowError")) + w.Write([]byte(internal.ComponentName + "." + internal.MsgErrUnknown)) case ConvertLocationError: // 201-Created, even if ConvertLocationError occurs, the creation was a success w.WriteHeader(http.StatusCreated) - w.Write([]byte(internal.ComponentName + "." + "unknowError")) + w.Write([]byte(internal.ComponentName + "." + internal.MsgErrUnknown)) default: defaultHandler(ctx, err, w) From a079877c6be9cc61bb91b01bbf760dbf4657ae60 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Tue, 3 Sep 2019 15:33:30 +0200 Subject: [PATCH 15/24] err msgs --- configs/keycloak_bridge.yml | 4 ++-- internal/keycloakb/errormessages.go | 2 ++ internal/keycloakb/eventsdbmodule.go | 3 +-- pkg/management/component.go | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/configs/keycloak_bridge.yml b/configs/keycloak_bridge.yml index aa82b7233..3b0091585 100644 --- a/configs/keycloak_bridge.yml +++ b/configs/keycloak_bridge.yml @@ -38,8 +38,8 @@ event-basic-auth-token: "superpasswordverylongandstrong" # Keycloak configs -keycloak-api-uri: http://localhost:8081 -keycloak-oidc-uri: http://localhost:8081 +keycloak-api-uri: http://localhost:8080 +keycloak-oidc-uri: http://localhost:8080 keycloak-timeout: 5s # DB Audit RW diff --git a/internal/keycloakb/errormessages.go b/internal/keycloakb/errormessages.go index 377181641..b3ebfe413 100644 --- a/internal/keycloakb/errormessages.go +++ b/internal/keycloakb/errormessages.go @@ -47,4 +47,6 @@ const ( Response = "response" ListOfRealms = "listOfRealms" Groups = "groups" + ClientId = "clientId" + RedirectURI = "redirectURI" ) diff --git a/internal/keycloakb/eventsdbmodule.go b/internal/keycloakb/eventsdbmodule.go index 6f2a7fb3c..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("invalidParameter.durationLabel") + return 0, errors.New(MsgErrInvalidParam + "." + DurationLabel) } var res = int64(0) var row = cm.db.QueryRow(strings.ReplaceAll(selectConnectionsCount, "##INTERVAL##", durationLabel), realmName) diff --git a/pkg/management/component.go b/pkg/management/component.go index 5b5e07cf8..545fa5f63 100644 --- a/pkg/management/component.go +++ b/pkg/management/component.go @@ -875,7 +875,7 @@ func (c *component) UpdateRealmCustomConfiguration(ctx context.Context, realmNam if !match { return http.Error{ Status: 400, - Message: "invalidClientIDOrRedirectURI", + Message: internal.MsgErrInvalidParam + "." + internal.ClientId + "Or" + internal.RedirectURI, } } // transform customConfig object into JSON string From a52989d511438d6048ab6d1ef3bc55a9e7d695dd Mon Sep 17 00:00:00 2001 From: rpo Date: Thu, 5 Sep 2019 16:50:18 +0200 Subject: [PATCH 16/24] Revert "CLOUDTRUST-1561 Label can be empty" This reverts commit f844594e84ab3e87c1a44682e55e2ac1e367ad7a. --- api/account/api.go | 101 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 api/account/api.go diff --git a/api/account/api.go b/api/account/api.go new file mode 100644 index 000000000..a681f7c62 --- /dev/null +++ b/api/account/api.go @@ -0,0 +1,101 @@ +package account + +import ( + "errors" + "regexp" + + kc "github.com/cloudtrust/keycloak-client" +) + +// UserRepresentation struct +type AccountRepresentation struct { + Username *string `json:"username,omitempty"` + Email *string `json:"email,omitempty"` + FirstName *string `json:"firstName,omitempty"` + LastName *string `json:"lastName,omitempty"` + PhoneNumber *string `json:"phoneNumber,omitempty"` +} + +// ConvertToAPIAccount creates an API account representation from a KC user representation +func ConvertToAPIAccount(userKc kc.UserRepresentation) AccountRepresentation { + var userRep AccountRepresentation + + userRep.Username = userKc.Username + userRep.Email = userKc.Email + userRep.FirstName = userKc.FirstName + userRep.LastName = userKc.LastName + + if userKc.Attributes != nil { + var m = *userKc.Attributes + + if m["phoneNumber"] != nil { + var phoneNumber = m["phoneNumber"][0] + userRep.PhoneNumber = &phoneNumber + } + } + return userRep +} + +// ConvertToKCUser creates a KC user representation from an API user +func ConvertToKCUser(user AccountRepresentation) kc.UserRepresentation { + var userRep kc.UserRepresentation + + userRep.Username = user.Username + userRep.Email = user.Email + userRep.FirstName = user.FirstName + userRep.LastName = user.LastName + + var attributes = make(map[string][]string) + + if user.PhoneNumber != nil { + attributes["phoneNumber"] = []string{*user.PhoneNumber} + } + + if len(attributes) > 0 { + userRep.Attributes = &attributes + } + + return userRep +} + +// Validators + +// Validate is a validator for AccountRepresentation +func (user AccountRepresentation) Validate() error { + if user.Username != nil && !matchesRegExp(*user.Username, RegExpUsername) { + return errors.New("Invalid username") + } + + if user.Email != nil && !matchesRegExp(*user.Email, RegExpEmail) { + return errors.New("Invalid email") + } + + if user.FirstName != nil && !matchesRegExp(*user.FirstName, RegExpFirstName) { + return errors.New("Invalid firstname") + } + + if user.LastName != nil && !matchesRegExp(*user.LastName, RegExpLastName) { + return errors.New("Invalid lastname") + } + + if user.PhoneNumber != nil && !matchesRegExp(*user.PhoneNumber, RegExpPhoneNumber) { + return errors.New("Invalid phone number") + } + + return nil +} + +func matchesRegExp(value, re string) bool { + res, _ := regexp.MatchString(re, value) + return res +} + +// Regular expressions for parameters validation +const ( + // User + RegExpUsername = `^[a-zA-Z0-9-_.]{1,128}$` + RegExpEmail = `^.+\@.+\..+` + RegExpFirstName = `^.{1,128}$` + RegExpLastName = `^.{1,128}$` + RegExpPhoneNumber = `^\+[1-9]\d{1,14}$` +) From 85b960f0176136a933e540dd47d4151a6d90ebad Mon Sep 17 00:00:00 2001 From: rpo Date: Thu, 5 Sep 2019 16:50:42 +0200 Subject: [PATCH 17/24] Revert "Fixup: Dependency on a branch of keycloak-client instead of a version" This reverts commit bbf489c6e4b2d1a096c5e861e75ecc1df02ed645. --- api/account/api_test.go | 107 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 api/account/api_test.go diff --git a/api/account/api_test.go b/api/account/api_test.go new file mode 100644 index 000000000..6bda05b7c --- /dev/null +++ b/api/account/api_test.go @@ -0,0 +1,107 @@ +package account_api + +import ( + "testing" + + kc "github.com/cloudtrust/keycloak-client" + "github.com/stretchr/testify/assert" +) + +func TestConvertCredential(t *testing.T) { + var credKc kc.CredentialRepresentation + var credType = "password" + var credID = "123456" + var configKc = "{}" + + credKc.Type = &credType + credKc.Id = &credID + credKc.CredentialData = nil + + assert.Equal(t, credKc.Type, ConvertCredential(&credKc).Type) + assert.Equal(t, credKc.Id, ConvertCredential(&credKc).Id) + assert.Nil(t, ConvertCredential(&credKc).CredentialData) + + credKc.CredentialData = &configKc + assert.NotNil(t, ConvertCredential(&credKc).CredentialData) + assert.Equal(t, "{}", *ConvertCredential(&credKc).CredentialData) +} + +func TestValidateUpdatePasswordRepresentation(t *testing.T) { + { + password := createValidUpdatePasswordBody() + assert.Nil(t, password.Validate()) + } + + value := "" + + { + password := createValidUpdatePasswordBody() + password.CurrentPassword = value + assert.NotNil(t, password.Validate()) + } + + { + password := createValidUpdatePasswordBody() + password.NewPassword = value + assert.NotNil(t, password.Validate()) + } + + { + password := createValidUpdatePasswordBody() + password.ConfirmPassword = value + assert.NotNil(t, password.Validate()) + } + +} + +func TestValidateCredentialRepresentation(t *testing.T) { + { + credential := createValidCredentialRepresentation() + assert.Nil(t, credential.Validate()) + } + + value := "" + + { + credential := createValidCredentialRepresentation() + credential.Id = &value + assert.NotNil(t, credential.Validate()) + } + + { + credential := createValidCredentialRepresentation() + credential.Type = &value + assert.NotNil(t, credential.Validate()) + } + + { + credential := createValidCredentialRepresentation() + credential.UserLabel = &value + assert.NotNil(t, credential.Validate()) + } + +} + +func createValidUpdatePasswordBody() UpdatePasswordBody { + password := "password" + + return UpdatePasswordBody{ + CurrentPassword: password, + NewPassword: password, + ConfirmPassword: password, + } +} + +func createValidCredentialRepresentation() CredentialRepresentation { + id := "f467ed7c-0a1d-4eee-9bb8-669c6f89c0ee" + credType := "otp" + userLabel := "my otp" + credData := "{}" + + return CredentialRepresentation{ + Id: &id, + Type: &credType, + CredentialData: &credData, + UserLabel: &userLabel, + } +} From f8ef6642ced1dbb0db7f5029c7297273e5d8ba0a Mon Sep 17 00:00:00 2001 From: rpo Date: Thu, 5 Sep 2019 16:50:54 +0200 Subject: [PATCH 18/24] Revert "[CLOUDTRUST-1502] Self service API" This reverts commit 321ac91a4a9c321c89307f07815bc7e1f1ac0263. --- api/account/api_test.go | 107 ------------ api/account/swagger-api_account.yaml | 9 +- api/management/api.go | 35 ++-- api/management/api_test.go | 15 +- cmd/keycloakb/keycloak_bridge.go | 9 +- pkg/account/component.go | 20 +-- pkg/account/component_test.go | 241 +-------------------------- pkg/account/endpoint.go | 14 +- pkg/account/endpoint_test.go | 4 +- pkg/account/http.go | 14 +- pkg/account/http_test.go | 9 +- pkg/account/mock_test.go | 2 +- pkg/event/component.go | 5 - pkg/events/component.go | 6 +- pkg/management/component.go | 4 +- pkg/management/endpoint.go | 34 ++-- 16 files changed, 92 insertions(+), 436 deletions(-) delete mode 100644 api/account/api_test.go diff --git a/api/account/api_test.go b/api/account/api_test.go deleted file mode 100644 index 6bda05b7c..000000000 --- a/api/account/api_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package account_api - -import ( - "testing" - - kc "github.com/cloudtrust/keycloak-client" - "github.com/stretchr/testify/assert" -) - -func TestConvertCredential(t *testing.T) { - var credKc kc.CredentialRepresentation - var credType = "password" - var credID = "123456" - var configKc = "{}" - - credKc.Type = &credType - credKc.Id = &credID - credKc.CredentialData = nil - - assert.Equal(t, credKc.Type, ConvertCredential(&credKc).Type) - assert.Equal(t, credKc.Id, ConvertCredential(&credKc).Id) - assert.Nil(t, ConvertCredential(&credKc).CredentialData) - - credKc.CredentialData = &configKc - assert.NotNil(t, ConvertCredential(&credKc).CredentialData) - assert.Equal(t, "{}", *ConvertCredential(&credKc).CredentialData) -} - -func TestValidateUpdatePasswordRepresentation(t *testing.T) { - { - password := createValidUpdatePasswordBody() - assert.Nil(t, password.Validate()) - } - - value := "" - - { - password := createValidUpdatePasswordBody() - password.CurrentPassword = value - assert.NotNil(t, password.Validate()) - } - - { - password := createValidUpdatePasswordBody() - password.NewPassword = value - assert.NotNil(t, password.Validate()) - } - - { - password := createValidUpdatePasswordBody() - password.ConfirmPassword = value - assert.NotNil(t, password.Validate()) - } - -} - -func TestValidateCredentialRepresentation(t *testing.T) { - { - credential := createValidCredentialRepresentation() - assert.Nil(t, credential.Validate()) - } - - value := "" - - { - credential := createValidCredentialRepresentation() - credential.Id = &value - assert.NotNil(t, credential.Validate()) - } - - { - credential := createValidCredentialRepresentation() - credential.Type = &value - assert.NotNil(t, credential.Validate()) - } - - { - credential := createValidCredentialRepresentation() - credential.UserLabel = &value - assert.NotNil(t, credential.Validate()) - } - -} - -func createValidUpdatePasswordBody() UpdatePasswordBody { - password := "password" - - return UpdatePasswordBody{ - CurrentPassword: password, - NewPassword: password, - ConfirmPassword: password, - } -} - -func createValidCredentialRepresentation() CredentialRepresentation { - id := "f467ed7c-0a1d-4eee-9bb8-669c6f89c0ee" - credType := "otp" - userLabel := "my otp" - credData := "{}" - - return CredentialRepresentation{ - Id: &id, - Type: &credType, - CredentialData: &credData, - UserLabel: &userLabel, - } -} diff --git a/api/account/swagger-api_account.yaml b/api/account/swagger-api_account.yaml index eeea16d20..f30ecb84d 100644 --- a/api/account/swagger-api_account.yaml +++ b/api/account/swagger-api_account.yaml @@ -5,17 +5,20 @@ info: version: 1.0.0 servers: - url: http://localhost:8888 +tags: +- name: Account + description: Account management paths: /account/credentials/password: post: tags: - - Credentials + - Password requestBody: content: application/json: schema: $ref: '#/components/schemas/UpdatePassword' - summary: Update password + summary: Update a password responses: 200: description: The password has been updated @@ -77,4 +80,4 @@ components: openIdConnectUrl: http://toto.com/.well-known/openid-configuration security: - openId: - - todo \ No newline at end of file + - todo diff --git a/api/management/api.go b/api/management/api.go index 1b33772ad..b5b9c1150 100644 --- a/api/management/api.go +++ b/api/management/api.go @@ -56,13 +56,11 @@ type ClientRepresentation struct { // CredentialRepresentation struct type CredentialRepresentation struct { - Id *string `json:"id,omitempty"` - Type *string `json:"type,omitempty"` - UserLabel *string `json:"userLabel,omitempty"` - CreatedDate *int64 `json:"createdDate,omitempty"` - CredentialData *string `json:"credentialData,omitempty"` - Value *string `json:"value,omitempty"` - Temporary *bool `json:"temporary,omitempty"` + Id *string `json:"id,omitempty"` + Type *string `json:"type,omitempty"` + Algorithm *string `json:"algorithm,omitempty"` + CreatedDate *int64 `json:"createdDate,omitempty"` + Config *map[string][]string `json:"config,omitempty"` } // RoleRepresentation struct @@ -88,10 +86,8 @@ type PasswordRepresentation struct { // RealmCustomConfiguration struct type RealmCustomConfiguration struct { - DefaultClientId *string `json:"default_client_id,omitempty"` - DefaultRedirectUri *string `json:"default_redirect_uri,omitempty"` - SelfAuthenticatorMgmtEnabled *bool `json:"self_authenticator_mgmt_enabled"` - SelfPasswordChangeEnabled *bool `json:"self_password_change_enabled"` + DefaultClientId *string `json:"default_client_id,omitempty"` + DefaultRedirectUri *string `json:"default_redirect_uri,omitempty"` } // RequiredAction type @@ -102,12 +98,19 @@ func ConvertCredential(credKc *kc.CredentialRepresentation) CredentialRepresenta var cred CredentialRepresentation cred.Id = credKc.Id cred.Type = credKc.Type - cred.UserLabel = credKc.UserLabel + cred.Algorithm = credKc.Algorithm cred.CreatedDate = credKc.CreatedDate - cred.CredentialData = credKc.CredentialData - cred.Temporary = credKc.Temporary - cred.Value = credKc.Value - + if credKc.Config != nil { + var m map[string][]string + m = make(map[string][]string) + for _, key := range []string{"deviceInfo_Manufacturer", "deviceInfo_Model", "deviceInfo_Name", "deviceInfo_Plateform", "shortId", "usedChallenges", "availableChallenges", "cardStatus", "expirationDate"} { + value, ok := (*credKc.Config)[key] + if ok { + m[key] = value + } + } + cred.Config = &m + } return cred } diff --git a/api/management/api_test.go b/api/management/api_test.go index b7f2347a3..67817d2fa 100644 --- a/api/management/api_test.go +++ b/api/management/api_test.go @@ -13,19 +13,22 @@ func TestConvertCredential(t *testing.T) { var credKc kc.CredentialRepresentation var credType = "password" var credID = "123456" - var configKc = "{}" + var configKc map[string][]string + configKc = make(map[string][]string) + configKc["undesired_Key"] = make([]string, 0) + configKc["deviceInfo_Model"] = make([]string, 0) credKc.Type = &credType credKc.Id = &credID - credKc.CredentialData = nil + credKc.Config = nil assert.Equal(t, credKc.Type, ConvertCredential(&credKc).Type) assert.Equal(t, credKc.Id, ConvertCredential(&credKc).Id) - assert.Nil(t, ConvertCredential(&credKc).CredentialData) + assert.Nil(t, ConvertCredential(&credKc).Config) - credKc.CredentialData = &configKc - assert.NotNil(t, ConvertCredential(&credKc).CredentialData) - assert.Equal(t, "{}", *ConvertCredential(&credKc).CredentialData) + credKc.Config = &configKc + assert.NotNil(t, ConvertCredential(&credKc).Config) + assert.Equal(t, 1, len(*ConvertCredential(&credKc).Config)) } func TestConvertToAPIUser(t *testing.T) { diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index acb4f384c..87757ccb3 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" @@ -459,7 +460,7 @@ func main() { var exportEndpoint = export.MakeExportEndpoint(exportComponent) var exportSaveAndExportEndpoint = export.MakeStoreAndExportEndpoint(exportComponent) - commonhttp.SetEmitter(keycloakb.ComponentName) + errorhandler.SetEmitter(keycloakb.ComponentName) // HTTP Internal Call Server (Event reception from Keycloak & Export API). go func() { @@ -630,9 +631,9 @@ func main() { 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 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) route.Path("/account/credentials/password").Methods("POST").Handler(updatePasswordHandler) route.Path("/account").Methods("GET").Handler(getAccountHandler) diff --git a/pkg/account/component.go b/pkg/account/component.go index 25634f68b..0c32b8146 100644 --- a/pkg/account/component.go +++ b/pkg/account/component.go @@ -8,14 +8,14 @@ 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" ) -// KeycloakAccountClient interface exposes methods we need to call to send requests to Keycloak API of Account -type KeycloakAccountClient interface { +// KeycloakClient interface exposes methods we need to call to send requests to Keycloak API +type KeycloakClient interface { UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword string) (string, error) UpdateAccount(accessToken, realm string, user kc.UserRepresentation) error GetAccount(accessToken, realm string) (kc.UserRepresentation, error) @@ -55,29 +55,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{ + return errorhandler.Error{ Status: http.StatusBadRequest, Message: internal.ComponentName + "." + "invalidValues", } } - _, err := c.keycloakAccountClient.UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword) + _, err := c.keycloakClient.UpdatePassword(accessToken, realm, currentPassword, newPassword, confirmPassword) //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/component_test.go b/pkg/account/component_test.go index 1b11c8768..f1711fba7 100644 --- a/pkg/account/component_test.go +++ b/pkg/account/component_test.go @@ -23,7 +23,7 @@ func genericUpdatePasswordTest(t *testing.T, oldPasswd, newPasswd, confirmPasswo var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() - mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) + mockKeycloakClient := mock.NewAccKeycloakClient(mockCtrl) mockEventDBModule := mock.NewEventsDBModule(mockCtrl) mockLogger := mock.NewLogger(mockCtrl) component := NewComponent(mockKeycloakClient, mockEventDBModule, mockLogger) @@ -37,7 +37,7 @@ func genericUpdatePasswordTest(t *testing.T, oldPasswd, newPasswd, confirmPasswo ctx = context.WithValue(ctx, cs.CtContextUserID, userID) ctx = context.WithValue(ctx, cs.CtContextUsername, username) - mockKeycloakAccountClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, confirmPassword).Return("", nil).Times(kcCalls) + mockKeycloakClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, confirmPassword).Return("", nil).Times(kcCalls) mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "PASSWORD_RESET", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(kcCalls) err := component.UpdatePassword(ctx, oldPasswd, newPasswd, confirmPassword) @@ -70,7 +70,7 @@ func TestUpdatePasswordWrongPwd(t *testing.T) { var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() - mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) + mockKeycloakClient := mock.NewAccKeycloakClient(mockCtrl) mockEventDBModule := mock.NewEventsDBModule(mockCtrl) mockLogger := mock.NewLogger(mockCtrl) component := NewComponent(mockKeycloakClient, mockEventDBModule, mockLogger) @@ -84,14 +84,14 @@ func TestUpdatePasswordWrongPwd(t *testing.T) { ctx = context.WithValue(ctx, cs.CtContextUserID, userID) ctx = context.WithValue(ctx, cs.CtContextUsername, username) - mockKeycloakAccountClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalidPasswordExistingMessage")).Times(1) + mockKeycloakClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalidPasswordExistingMessage")).Times(1) mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "PASSWORD_RESET", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) err := component.UpdatePassword(ctx, oldPasswd, newPasswd, newPasswd) assert.True(t, err != nil) - mockKeycloakAccountClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalid")).Times(1) + mockKeycloakClient.EXPECT().UpdatePassword(accessToken, realm, oldPasswd, newPasswd, newPasswd).Return("", fmt.Errorf("invalid")).Times(1) mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "PASSWORD_RESET", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) err = component.UpdatePassword(ctx, oldPasswd, newPasswd, newPasswd) @@ -362,234 +362,3 @@ func TestGetUser(t *testing.T) { assert.NotNil(t, err) } } - -func TestGetCredentials(t *testing.T) { - var mockCtrl = gomock.NewController(t) - defer mockCtrl.Finish() - - mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) - mockEventDBModule := mock.NewEventsDBModule(mockCtrl) - mockLogger := log.NewNopLogger() - component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) - - var accessToken = "TOKEN==" - var currentRealm = "master" - var currentUserID = "1234-789" - - // Get credentials with succces - { - var id = "1245" - - var kcCredRep = kc.CredentialRepresentation{ - Id: &id, - } - - var kcCredsRep []kc.CredentialRepresentation - kcCredsRep = append(kcCredsRep, kcCredRep) - - mockKeycloakAccountClient.EXPECT().GetCredentials(accessToken, currentRealm).Return(kcCredsRep, nil).Times(1) - - var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) - ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) - - apiCredsRep, err := component.GetCredentials(ctx) - - var expectedAPICredRep = account_api.CredentialRepresentation{ - Id: &id, - } - - var expectedAPICredsRep []account_api.CredentialRepresentation - expectedAPICredsRep = append(expectedAPICredsRep, expectedAPICredRep) - - assert.Nil(t, err) - assert.Equal(t, expectedAPICredsRep, apiCredsRep) - } - - //Error - { - mockKeycloakAccountClient.EXPECT().GetCredentials(accessToken, currentRealm).Return([]kc.CredentialRepresentation{}, fmt.Errorf("Unexpected error")).Times(1) - - var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) - ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) - - _, err := component.GetCredentials(ctx) - - assert.NotNil(t, err) - } -} - -func TestGetCredentialTypes(t *testing.T) { - var mockCtrl = gomock.NewController(t) - defer mockCtrl.Finish() - - mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) - mockEventDBModule := mock.NewEventsDBModule(mockCtrl) - mockLogger := log.NewNopLogger() - component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) - - var accessToken = "TOKEN==" - var currentRealm = "master" - var currentUserID = "1234-789" - - // Get credential types with succces - { - var credTypes = []string{"paper", "push"} - - mockKeycloakAccountClient.EXPECT().GetCredentialTypes(accessToken, currentRealm).Return(credTypes, nil).Times(1) - - var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) - ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) - - resCredTypes, err := component.GetCredentialTypes(ctx) - - assert.Nil(t, err) - assert.Equal(t, credTypes, resCredTypes) - } - - //Error - { - mockKeycloakAccountClient.EXPECT().GetCredentialTypes(accessToken, currentRealm).Return([]string{}, fmt.Errorf("Unexpected error")).Times(1) - - var ctx = context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - ctx = context.WithValue(ctx, cs.CtContextRealm, currentRealm) - ctx = context.WithValue(ctx, cs.CtContextUserID, currentUserID) - - _, err := component.GetCredentialTypes(ctx) - - assert.NotNil(t, err) - } -} - -func TestUpdateLabelCredential(t *testing.T) { - - var mockCtrl = gomock.NewController(t) - defer mockCtrl.Finish() - - mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) - mockEventDBModule := mock.NewEventsDBModule(mockCtrl) - mockLogger := log.NewNopLogger() - component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) - - accessToken := "access token" - realm := "sample realm" - userID := "123-456-789" - username := "username" - ctx := context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - ctx = context.WithValue(ctx, cs.CtContextRealm, realm) - ctx = context.WithValue(ctx, cs.CtContextUserID, userID) - ctx = context.WithValue(ctx, cs.CtContextUsername, username) - - credentialID := "78945-845" - label := "cred label" - - { - mockKeycloakAccountClient.EXPECT().UpdateLabelCredential(accessToken, realm, credentialID, label).Return(nil).Times(1) - mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_UPDATE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) - - err := component.UpdateLabelCredential(ctx, credentialID, label) - - assert.Nil(t, err) - } - - { - mockKeycloakAccountClient.EXPECT().UpdateLabelCredential(accessToken, realm, credentialID, label).Return(fmt.Errorf("Unexpected error")).Times(1) - err := component.UpdateLabelCredential(ctx, credentialID, label) - - assert.NotNil(t, err) - } -} - -func TestDeleteCredential(t *testing.T) { - - var mockCtrl = gomock.NewController(t) - defer mockCtrl.Finish() - - mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) - mockEventDBModule := mock.NewEventsDBModule(mockCtrl) - mockLogger := log.NewNopLogger() - component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) - - accessToken := "access token" - realm := "sample realm" - userID := "123-456-789" - username := "username" - ctx := context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - ctx = context.WithValue(ctx, cs.CtContextRealm, realm) - ctx = context.WithValue(ctx, cs.CtContextUserID, userID) - ctx = context.WithValue(ctx, cs.CtContextUsername, username) - - credentialID := "78945-845" - { - mockKeycloakAccountClient.EXPECT().DeleteCredential(accessToken, realm, credentialID).Return(nil).Times(1) - mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_DELETE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) - - err := component.DeleteCredential(ctx, credentialID) - - assert.Nil(t, err) - } - - { - mockKeycloakAccountClient.EXPECT().DeleteCredential(accessToken, realm, credentialID).Return(fmt.Errorf("Unexpected error")).Times(1) - err := component.DeleteCredential(ctx, credentialID) - - assert.NotNil(t, err) - } -} - -func TestMoveCredential(t *testing.T) { - - var mockCtrl = gomock.NewController(t) - defer mockCtrl.Finish() - - mockKeycloakAccountClient := mock.NewKeycloakAccountClient(mockCtrl) - mockEventDBModule := mock.NewEventsDBModule(mockCtrl) - mockLogger := log.NewNopLogger() - component := NewComponent(mockKeycloakAccountClient, mockEventDBModule, mockLogger) - - accessToken := "access token" - realm := "sample realm" - userID := "123-456-789" - username := "username" - ctx := context.WithValue(context.Background(), cs.CtContextAccessToken, accessToken) - ctx = context.WithValue(ctx, cs.CtContextRealm, realm) - ctx = context.WithValue(ctx, cs.CtContextUserID, userID) - ctx = context.WithValue(ctx, cs.CtContextUsername, username) - - credentialID := "78945-845" - previousCredentialID := "6589-7841" - { - mockKeycloakAccountClient.EXPECT().MoveAfter(accessToken, realm, credentialID, previousCredentialID).Return(nil).Times(1) - mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_MOVE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) - - err := component.MoveCredential(ctx, credentialID, previousCredentialID) - - assert.Nil(t, err) - } - - { - mockKeycloakAccountClient.EXPECT().MoveToFirst(accessToken, realm, credentialID).Return(nil).Times(1) - mockEventDBModule.EXPECT().ReportEvent(gomock.Any(), "SELF_MOVE_CREDENTIAL", "self-service", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1) - - err := component.MoveCredential(ctx, credentialID, "null") - - assert.Nil(t, err) - } - - { - mockKeycloakAccountClient.EXPECT().MoveAfter(accessToken, realm, credentialID, previousCredentialID).Return(fmt.Errorf("Unexpected error")).Times(1) - err := component.MoveCredential(ctx, credentialID, previousCredentialID) - - assert.NotNil(t, err) - } - - { - mockKeycloakAccountClient.EXPECT().MoveToFirst(accessToken, realm, credentialID).Return(fmt.Errorf("Unexpected error")).Times(1) - err := component.MoveCredential(ctx, credentialID, "null") - - assert.NotNil(t, err) - } - -} diff --git a/pkg/account/endpoint.go b/pkg/account/endpoint.go index 8ad9090ea..695bed337 100644 --- a/pkg/account/endpoint.go +++ b/pkg/account/endpoint.go @@ -5,7 +5,7 @@ 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" @@ -36,15 +36,11 @@ type AccountComponent interface { func MakeUpdatePasswordEndpoint(component AccountComponent) cs.Endpoint { return func(ctx context.Context, req interface{}) (interface{}, error) { var m = req.(map[string]string) - var body api.UpdatePasswordBody + var body UpdatePasswordBody err := json.Unmarshal([]byte(m["body"]), &body) if err != nil { - return nil, http.CreateBadRequestError("Invalid body") - } - - if err = body.Validate(); err != nil { - return nil, http.CreateBadRequestError(err.Error()) + return nil, errrorhandler.CreateBadRequestError("Invalid body") } return nil, component.UpdatePassword(ctx, body.CurrentPassword, body.NewPassword, body.ConfirmPassword) @@ -66,11 +62,11 @@ func MakeUpdateAccountEndpoint(component AccountComponent) cs.Endpoint { err := json.Unmarshal([]byte(m["body"]), &body) if err != nil { - return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.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/account/endpoint_test.go b/pkg/account/endpoint_test.go index 71d842d0c..5e10205da 100644 --- a/pkg/account/endpoint_test.go +++ b/pkg/account/endpoint_test.go @@ -15,12 +15,12 @@ func TestMakeUpdatePasswordEndpoint(t *testing.T) { defer mockCtrl.Finish() mockAccountComponent := mock.NewAccountComponent(mockCtrl) - mockAccountComponent.EXPECT().UpdatePassword(gomock.Any(), "password", "password2", "password2").Return(nil).Times(1) + mockAccountComponent.EXPECT().UpdatePassword(gomock.Any(), "", "", "").Return(nil).Times(1) m := map[string]string{} { - m["body"] = "{ \"currentPassword\":\"password\", \"newPassword\":\"password2\", \"confirmPassword\":\"password2\"}" + m["body"] = "{}" _, err := MakeUpdatePasswordEndpoint(mockAccountComponent)(context.Background(), m) assert.Nil(t, err) } diff --git a/pkg/account/http.go b/pkg/account/http.go index 9700beb74..8a5a1a085 100644 --- a/pkg/account/http.go +++ b/pkg/account/http.go @@ -6,7 +6,6 @@ import ( commonhttp "github.com/cloudtrust/common-service/http" "github.com/cloudtrust/common-service/log" - account_api "github.com/cloudtrust/keycloak-bridge/api/account" "github.com/go-kit/kit/endpoint" http_transport "github.com/go-kit/kit/transport/http" ) @@ -14,20 +13,15 @@ import ( // MakeAccountHandler make an HTTP handler for an Account endpoint. func MakeAccountHandler(e endpoint.Endpoint, logger log.Logger) *http_transport.Server { return http_transport.NewServer(e, - decodeAccountRequest, + decodeEventsRequest, commonhttp.EncodeReply, http_transport.ServerErrorEncoder(commonhttp.ErrorHandler(logger)), ) } // decodeEventsRequest gets the HTTP parameters and body content -func decodeAccountRequest(ctx context.Context, req *http.Request) (interface{}, error) { - var pathParams = map[string]string{ - "credentialID": account_api.RegExpID, - "previousCredentialID": account_api.RegExpIDNullable, - } - - var queryParams = map[string]string{} - +func decodeEventsRequest(ctx context.Context, req *http.Request) (interface{}, error) { + pathParams := map[string]string{"realm": "^[a-zA-Z0-9_-]{1,36}$"} + queryParams := map[string]string{} return commonhttp.DecodeRequest(ctx, req, pathParams, queryParams) } diff --git a/pkg/account/http_test.go b/pkg/account/http_test.go index fe11e89c1..87fcb86bb 100644 --- a/pkg/account/http_test.go +++ b/pkg/account/http_test.go @@ -9,7 +9,6 @@ import ( "testing" "github.com/cloudtrust/common-service/log" - account_api "github.com/cloudtrust/keycloak-bridge/api/account" "github.com/cloudtrust/keycloak-bridge/internal/keycloakb" "github.com/cloudtrust/keycloak-bridge/pkg/account/mock" "github.com/golang/mock/gomock" @@ -20,23 +19,23 @@ import ( func TestHTTPAccountHandler(t *testing.T) { var mockCtrl = gomock.NewController(t) defer mockCtrl.Finish() - var mockAccountComponent = mock.NewAccountComponent(mockCtrl) + var mockComponent = mock.NewComponent(mockCtrl) r := mux.NewRouter() - r.Handle("/path/to/{realm}/password", MakeAccountHandler(keycloakb.ToGoKitEndpoint(MakeUpdatePasswordEndpoint(mockAccountComponent)), log.NewNopLogger())) + r.Handle("/path/to/{realm}/password", MakeAccountHandler(keycloakb.ToGoKitEndpoint(MakeUpdatePasswordEndpoint(mockComponent)), log.NewNopLogger())) ts := httptest.NewServer(r) defer ts.Close() { - body := account_api.UpdatePasswordBody{ + body := UpdatePasswordBody{ CurrentPassword: "current", NewPassword: "new", ConfirmPassword: "confirm", } json, _ := json.MarshalIndent(body, "", " ") - mockAccountComponent.EXPECT().UpdatePassword(gomock.Any(), body.CurrentPassword, body.NewPassword, body.ConfirmPassword).Return(nil).Times(1) + mockComponent.EXPECT().UpdatePassword(gomock.Any(), body.CurrentPassword, body.NewPassword, body.ConfirmPassword).Return(nil).Times(1) res, err := http.Post(ts.URL+"/path/to/master/password", "application/json", ioutil.NopCloser(bytes.NewBuffer(json))) diff --git a/pkg/account/mock_test.go b/pkg/account/mock_test.go index b0173a10d..6a88e299b 100644 --- a/pkg/account/mock_test.go +++ b/pkg/account/mock_test.go @@ -1,6 +1,6 @@ package account -//go:generate mockgen -destination=./mock/account_keycloak_client.go -package=mock -mock_names=KeycloakAccountClient=KeycloakAccountClient github.com/cloudtrust/keycloak-bridge/pkg/account KeycloakAccountClient +//go:generate mockgen -destination=./mock/acc_keycloak_client.go -package=mock -mock_names=KeycloakClient=AccKeycloakClient github.com/cloudtrust/keycloak-bridge/pkg/account KeycloakClient //go:generate mockgen -destination=./mock/eventsdbmodule.go -package=mock -mock_names=EventsDBModule=EventsDBModule github.com/cloudtrust/common-service/database EventsDBModule //go:generate mockgen -destination=./mock/component.go -package=mock -mock_names=AccountComponent=AccountComponent,Component=Component github.com/cloudtrust/keycloak-bridge/pkg/account AccountComponent,Component //go:generate mockgen -destination=./mock/logger.go -package=mock -mock_names=Logger=Logger github.com/cloudtrust/keycloak-bridge/internal/keycloakb Logger diff --git a/pkg/event/component.go b/pkg/event/component.go index 38f6b502c..48215074e 100755 --- a/pkg/event/component.go +++ b/pkg/event/component.go @@ -13,11 +13,6 @@ import ( "github.com/cloudtrust/keycloak-bridge/api/event/fb" ) -var ( - // ComponentName is the name of the component. - ComponentName = "keycloak-bridge" -) - const ( timeFormat = "2006-01-02 15:04:05.000" ) diff --git a/pkg/events/component.go b/pkg/events/component.go index abebf9b5c..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(app.Realm) + return api.AuditEventsRepresentation{}, errorhandler.CreateMissingParameterError(app.Realm) } if val, ok := params["userID"]; !ok || len(val) == 0 { - return api.AuditEventsRepresentation{}, http.CreateMissingParameterError(app.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/management/component.go b/pkg/management/component.go index 545fa5f63..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,7 +873,7 @@ func (c *component) UpdateRealmCustomConfiguration(ctx context.Context, realmNam } } if !match { - return http.Error{ + return errorhandler.Error{ Status: 400, Message: internal.MsgErrInvalidParam + "." + internal.ClientId + "Or" + internal.RedirectURI, } diff --git a/pkg/management/endpoint.go b/pkg/management/endpoint.go index 57c5bf8c7..0e033fdbf 100644 --- a/pkg/management/endpoint.go +++ b/pkg/management/endpoint.go @@ -8,7 +8,7 @@ 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" @@ -121,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(internal.MsgErrInvalidParam + "." + internal.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(internal.Groups) + return nil, errorhandler.CreateMissingParameterError(internal.Groups) } var keycloakLocation string @@ -174,11 +174,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(internal.MsgErrInvalidParam + internal.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) @@ -199,7 +199,7 @@ func MakeGetUsersEndpoint(managementComponent ManagementComponent) cs.Endpoint { _, ok := m["groupIds"] if !ok { - return nil, http.CreateMissingParameterError(internal.GroudIds) + return nil, errorhandler.CreateMissingParameterError(internal.GroudIds) } groupIDs := strings.Split(m["groupIds"], ",") @@ -253,12 +253,12 @@ func MakeAddClientRolesToUserEndpoint(managementComponent ManagementComponent) c var roles []api.RoleRepresentation if err = json.Unmarshal([]byte(m["body"]), &roles); err != nil { - return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.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()) } } @@ -275,11 +275,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(internal.MsgErrInvalidParam + "." + internal.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) @@ -323,12 +323,12 @@ func MakeExecuteActionsEmailEndpoint(managementComponent ManagementComponent) cs var actions []api.RequiredAction if err = json.Unmarshal([]byte(m["body"]), &actions); err != nil { - return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.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()) } } @@ -425,11 +425,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(internal.MsgErrInvalidParam + "." + internal.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 @@ -467,11 +467,11 @@ func MakeUpdateRealmCustomConfigurationEndpoint(managementComponent ManagementCo var customConfig api.RealmCustomConfiguration if err = json.Unmarshal(configJSON, &customConfig); err != nil { - return nil, http.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.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) From 560932af8474bb8118ab04767e6930611392182c Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 5 Sep 2019 18:00:28 +0200 Subject: [PATCH 19/24] fixup! Revert "[CLOUDTRUST-1502] Self service API" --- Gopkg.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gopkg.toml b/Gopkg.toml index 64ec36ad9..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-rc4" + branch = "error-handling" [[constraint]] name = "github.com/go-kit/kit" From c5363679bb59ce1e434d7f8a0377e5f42a19c876 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Thu, 5 Sep 2019 18:10:50 +0200 Subject: [PATCH 20/24] fixup! fixup! Revert "[CLOUDTRUST-1502] Self service API" --- Gopkg.toml | 4 ++-- cmd/keycloakb/keycloak_bridge.go | 6 +++--- internal/keycloakb/eventsdbmodule_test.go | 6 +++--- pkg/account/endpoint.go | 2 +- pkg/management/component_test.go | 2 +- pkg/management/http_test.go | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Gopkg.toml b/Gopkg.toml index 0cde17682..64ec36ad9 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -27,11 +27,11 @@ [[constraint]] name = "github.com/cloudtrust/common-service" - branch = "error-handling" + version = "v1.0-rc6" [[constraint]] name = "github.com/cloudtrust/keycloak-client" - branch = "error-handling" + version = "v1.0-rc4" [[constraint]] name = "github.com/go-kit/kit" diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index 87757ccb3..e23035a5f 100644 --- a/cmd/keycloakb/keycloak_bridge.go +++ b/cmd/keycloakb/keycloak_bridge.go @@ -469,7 +469,7 @@ func main() { var route = mux.NewRouter() - // keycloakb.Version. + // Version. route.Handle("/", commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit)) // Event. @@ -508,7 +508,7 @@ func main() { var route = mux.NewRouter() - // keycloakb.Version. + // Version. route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit))) // Rights @@ -627,7 +627,7 @@ func main() { var route = mux.NewRouter() - // keycloakb.Version. + // Version. route.Handle("/", http.HandlerFunc(commonhttp.MakeVersionHandler(keycloakb.ComponentName, ComponentID, keycloakb.Version, Environment, GitCommit))) // Account 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/pkg/account/endpoint.go b/pkg/account/endpoint.go index 695bed337..a3ac1532e 100644 --- a/pkg/account/endpoint.go +++ b/pkg/account/endpoint.go @@ -40,7 +40,7 @@ func MakeUpdatePasswordEndpoint(component AccountComponent) cs.Endpoint { err := json.Unmarshal([]byte(m["body"]), &body) if err != nil { - return nil, errrorhandler.CreateBadRequestError("Invalid body") + return nil, errrorhandler.CreateBadRequestError(internal.MsgErrInvalidParam + "." + internal.Body) } return nil, component.UpdatePassword(ctx, body.CurrentPassword, body.NewPassword, body.ConfirmPassword) 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/http_test.go b/pkg/management/http_test.go index c3ec7507c..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" From 58797d6e53858552eb5c182c61edc2c829673348 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Tue, 10 Sep 2019 17:40:01 +0200 Subject: [PATCH 21/24] fixup! fixup! fixup! fixup! Revert "[CLOUDTRUST-1502] Self service API" --- Gopkg.lock | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 0b01b6e6e..20ba08837 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -170,13 +170,7 @@ version = "v1.0.0" [[projects]] -<<<<<<< HEAD - digest = "1:2629521d27f3b04ce4d524cb52a25fdc77745071239c91d6fe9a7ce10131365a" -||||||| merged common ancestors - digest = "1:3c6faaeb500b7e6fadbe52c0b3fd62b6eed7801ed0d74bb3bd9577017df8d2f4" -======= digest = "1:4ffdbf6b310da314d1d171f356012e16157ceb43869c7e43e0f3c438c0c3d5d3" ->>>>>>> origin name = "github.com/influxdata/influxdb" packages = [ "client/v2", From 1159331dae2fed1bb922038f17ba750025000aff Mon Sep 17 00:00:00 2001 From: bsoniam Date: Wed, 11 Sep 2019 14:39:29 +0200 Subject: [PATCH 22/24] fixup! fixup! fixup! fixup! fixup! Revert "[CLOUDTRUST-1502] Self service API" --- Gopkg.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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" From 83bb552645a841955e2184c4b4d6fc8d1a631eb8 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Wed, 11 Sep 2019 15:56:28 +0200 Subject: [PATCH 23/24] fixup! fixup! fixup! fixup! fixup! fixup! Revert "[CLOUDTRUST-1502] Self service API" --- pkg/export/component.go | 4 ++-- pkg/export/storage.go | 4 ++-- pkg/management/endpoint.go | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pkg/export/component.go b/pkg/export/component.go index 076b70f0a..a631ca8e4 100644 --- a/pkg/export/component.go +++ b/pkg/export/component.go @@ -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, internal.MsgErrCannotMarshal+"."+internal.Config+".%s.%s", 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, internal.MsgErrCannotSaveConfigInDB+".%s.%s", c.componentName, c.componentVersion) + return nil, errors.Wrapf(err, internal.MsgErrCannotSaveConfigInDB+"."+c.componentName+"."+c.componentVersion) } return realmsMap, nil diff --git a/pkg/export/storage.go b/pkg/export/storage.go index 2cf452c4f..9e07c7763 100644 --- a/pkg/export/storage.go +++ b/pkg/export/storage.go @@ -39,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, internal.MsgErrCannotUpdate+"."+internal.Config+".%s.%s", componentName, version) + return errors.Wrapf(err, internal.MsgErrCannotUpdate+"."+internal.Config+"."+componentName+"."+version) } return nil @@ -54,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, internal.MsgErrCannotUpdate+"."+internal.Config+".%s.%s", componentName, version) + return nil, errors.Wrapf(err, internal.MsgErrCannotUpdate+"."+internal.Config+"."+componentName+"."+version) } return config, nil diff --git a/pkg/management/endpoint.go b/pkg/management/endpoint.go index 0e033fdbf..fe10d2d76 100644 --- a/pkg/management/endpoint.go +++ b/pkg/management/endpoint.go @@ -140,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 } } @@ -440,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 } } From 0e534f597d0039523a26a2027e12d2a6720b5262 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Wed, 11 Sep 2019 15:57:09 +0200 Subject: [PATCH 24/24] fixup! fixup! fixup! fixup! fixup! fixup! fixup! Revert "[CLOUDTRUST-1502] Self service API" --- pkg/management/http.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/management/http.go b/pkg/management/http.go index dcf54559f..860793e8f 100644 --- a/pkg/management/http.go +++ b/pkg/management/http.go @@ -71,10 +71,6 @@ func managementErrorHandler(logger log.Logger) func(context.Context, error, http case kc_client.HTTPError: w.WriteHeader(e.HTTPStatus) w.Write([]byte(internal.ComponentName + "." + internal.MsgErrUnknown)) - 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)