From 776bd5cdbc1586c8f8c8f1c9157867386a681cfe Mon Sep 17 00:00:00 2001 From: bsoniam Date: Tue, 16 Apr 2019 10:44:50 +0200 Subject: [PATCH 1/3] small fixes + PR comments --- pkg/event/component.go | 14 +++++++++----- pkg/management/component.go | 33 ++++++++++++++++----------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/pkg/event/component.go b/pkg/event/component.go index bb5be662..1d6ffffd 100755 --- a/pkg/event/component.go +++ b/pkg/event/component.go @@ -14,6 +14,10 @@ import ( "github.com/cloudtrust/keycloak-bridge/api/event/fb" ) +const ( + timeFormat = "2006-01-02 15:04:05.000" +) + // MuxComponent is the Mux component interface. type MuxComponent interface { Event(ctx context.Context, eventType string, obj []byte) error @@ -137,7 +141,7 @@ func addCTtypeToEvent(event map[string]string) map[string]string { } case "ACTION": //ACTIVATION_EMAIL_SENT - // check if the resourcePath ends with sufix send-verify-email + // check if the resourcePath ends with suffix send-verify-email if strings.HasSuffix(f["resource_path"], "send-verify-email") { event["ct_event_type"] = "ACTIVATION_EMAIL_SENT" return event @@ -197,7 +201,7 @@ func adminEventToMap(adminEvent *fb.AdminEvent) map[string]string { addInfo["uid"] = fmt.Sprint(adminEvent.Uid()) time := epochMilliToTime(adminEvent.Time()).UTC() - adminEventMap["audit_time"] = time.Format("2006-01-02 15:04:05.000") //audit_time + adminEventMap["audit_time"] = time.Format(timeFormat) //audit_time adminEventMap["realm_name"] = string(adminEvent.RealmId()) //realm_name adminEventMap["origin"] = "keycloak" //origin @@ -213,8 +217,8 @@ func adminEventToMap(adminEvent *fb.AdminEvent) map[string]string { adminEventMap["kc_operation_type"] = fb.EnumNamesOperationType[int8(adminEvent.OperationType())] //kc_operation_type addInfo["resource_path"] = string(adminEvent.ResourcePath()) reg := regexp.MustCompile(`[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}`) - if strings.HasPrefix(addInfo["resourcePath"], "users") { - adminEventMap["user_id"] = string(reg.Find([]byte(addInfo["resourcePath"]))) //user_id + if strings.HasPrefix(addInfo["resource_path"], "users") { + adminEventMap["user_id"] = string(reg.Find([]byte(addInfo["resource_path"]))) //user_id } addInfo["representation"] = string(adminEvent.Representation()) @@ -241,7 +245,7 @@ func eventToMap(event *fb.Event) map[string]string { addInfo["uid"] = fmt.Sprint(event.Uid()) time := epochMilliToTime(event.Time()).UTC() - eventMap["audit_time"] = time.Format("2006-01-02 15:04:05.000") //audit_time + eventMap["audit_time"] = time.Format(timeFormat) //audit_time eventMap["kc_event_type"] = fb.EnumNamesEventType[int8(event.Type())] // kc_event_type eventMap["realm_name"] = string(event.RealmId()) //realm_name diff --git a/pkg/management/component.go b/pkg/management/component.go index c11d2693..8755f1b7 100644 --- a/pkg/management/component.go +++ b/pkg/management/component.go @@ -60,6 +60,10 @@ type component struct { eventDBModule event.EventsDBModule } +const ( + timeFormat = "2006-01-02 15:04:05.000" +) + // NewComponent returns the management component. func NewComponent(keycloakClient KeycloakClient, eventDBModule event.EventsDBModule) Component { return &component{ @@ -68,15 +72,15 @@ func NewComponent(keycloakClient KeycloakClient, eventDBModule event.EventsDBMod } } -func getAgentDetails(ctx context.Context, event map[string]string) map[string]string { +func addAgentDetails(ctx context.Context, event map[string]string) { //retrieve agent username event["agent_username"] = ctx.Value("username").(string) //retrieve agent user id - not yet implemented + //to be uncommented once the ctx contains the userId value //event["userId"] = ctx.Value("userId").(string) //retrieve agent realm event["agent_realm_name"] = ctx.Value("realm").(string) - return event } func (c *component) GetRealm(ctx context.Context, realm string) (api.RealmRepresentation, error) { @@ -185,10 +189,9 @@ func (c *component) CreateUser(ctx context.Context, realmName string, user api.U } event["origin"] = "back-office" - time := time.Now().UTC() - event["audit_time"] = time.Format("2006-01-02 15:04:05.000") + event["audit_time"] = time.Now().UTC().Format(timeFormat) //retrieve details of the agent - event = getAgentDetails(ctx, event) + addAgentDetails(ctx, event) // the error should be treated _ = c.eventDBModule.Store(ctx, event) @@ -211,11 +214,10 @@ func (c *component) DeleteUser(ctx context.Context, realmName, userID string) er event["realm_name"] = realmName event["user_id"] = userID event["origin"] = "back-office" - time := time.Now().UTC() - event["audit_time"] = time.Format("2006-01-02 15:04:05.000") + event["audit_time"] = time.Now().UTC().Format(timeFormat) //retrieve details of the agent - event = getAgentDetails(ctx, event) + addAgentDetails(ctx, event) // the error should be treated _ = c.eventDBModule.Store(ctx, event) @@ -274,11 +276,10 @@ func (c *component) GetUser(ctx context.Context, realmName, userID string) (api. event["username"] = *userKc.Username } event["origin"] = "back-office" - time := time.Now().UTC() - event["audit_time"] = time.Format("2006-01-02 15:04:05.000") + event["audit_time"] = time.Now().UTC().Format(timeFormat) //retrieve details of the agent - event = getAgentDetails(ctx, event) + addAgentDetails(ctx, event) // the error should be treated _ = c.eventDBModule.Store(ctx, event) @@ -335,10 +336,9 @@ func (c *component) UpdateUser(ctx context.Context, realmName, userID string, us event["username"] = *user.Username } event["origin"] = "back-office" - time := time.Now().UTC() - event["audit_time"] = time.Format("2006-01-02 15:04:05.000") + event["audit_time"] = time.Now().UTC().Format(timeFormat) //retrieve details of the agent - event = getAgentDetails(ctx, event) + addAgentDetails(ctx, event) //add ct_event_type if *user.Enabled { @@ -495,10 +495,9 @@ func (c *component) ResetPassword(ctx context.Context, realmName string, userID event["realm_name"] = realmName event["user_id"] = userID event["origin"] = "back-office" - time := time.Now().UTC() - event["audit_time"] = time.Format("2006-01-02 15:04:05.000") + event["audit_time"] = time.Now().UTC().Format(timeFormat) //retrieve details of the agent - event = getAgentDetails(ctx, event) + addAgentDetails(ctx, event) // the error should be treated _ = c.eventDBModule.Store(ctx, event) From 50526c514747ff2705beff7f49b36e30c6b4b476 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Tue, 16 Apr 2019 11:08:28 +0200 Subject: [PATCH 2/3] fixes on default values --- cmd/keycloakb/keycloak_bridge.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/keycloakb/keycloak_bridge.go b/cmd/keycloakb/keycloak_bridge.go index e7b853bc..34e3d8fa 100644 --- a/cmd/keycloakb/keycloak_bridge.go +++ b/cmd/keycloakb/keycloak_bridge.go @@ -721,13 +721,18 @@ func config(logger log.Logger) *viper.Viper { v.SetDefault("keycloak-timeout", "5s") //Storage events in DB - v.SetDefault("events-DB", false) + v.SetDefault("events-db", false) + + // DB v.SetDefault("db-host-port", "") v.SetDefault("db-username", "") v.SetDefault("db-password", "") v.SetDefault("db-database", "") v.SetDefault("db-table", "") - v.SetDefault("protocol", "") + v.SetDefault("db-protocol", "") + v.SetDefault("db-max-open-conns", 10) + v.SetDefault("db-max-idle-conns", 2) + v.SetDefault("db-conn-max-lifetime", 3600) // Rate limiting (in requests/second) v.SetDefault("rate-event", 1000) From 493a4f3e1fb4ae609f9e59fa624760d0456e9c57 Mon Sep 17 00:00:00 2001 From: bsoniam Date: Tue, 16 Apr 2019 14:40:05 +0200 Subject: [PATCH 3/3] cleaning code + restructure --- pkg/event/module.go | 2 +- pkg/management/component.go | 107 +++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/pkg/event/module.go b/pkg/event/module.go index 39bf7a57..e522f272 100644 --- a/pkg/event/module.go +++ b/pkg/event/module.go @@ -148,7 +148,7 @@ type eventsDBModule struct { // NewConsoleModule returns a Console module. func NewEventsDBModule(db DBEvents) EventsDBModule { - db.Exec(createTable) + //db.Exec(createTable) return &eventsDBModule{ db: db, } diff --git a/pkg/management/component.go b/pkg/management/component.go index 8755f1b7..36a561b0 100644 --- a/pkg/management/component.go +++ b/pkg/management/component.go @@ -2,6 +2,7 @@ package management import ( "context" + "regexp" "time" api "github.com/cloudtrust/keycloak-bridge/api/management" @@ -83,6 +84,29 @@ func addAgentDetails(ctx context.Context, event map[string]string) { event["agent_realm_name"] = ctx.Value("realm").(string) } +// create the generic event that contains the ct_event_type, origin and audit_time +func createEventMap(apiCall string) map[string]string { + event := make(map[string]string) + event["ct_event_type"] = apiCall + event["origin"] = "back-office" + event["audit_time"] = time.Now().UTC().Format(timeFormat) + + return event +} + +// enhance the event with more information +func addEventValues(ctx context.Context, event map[string]string, values ...string) { + + //add information to the event + noTuples := len(values) + for i := 0; i < noTuples; i = i + 2 { + event[values[i]] = values[i+1] + } + + //retrieve details of the agent + addAgentDetails(ctx, event) +} + func (c *component) GetRealm(ctx context.Context, realm string) (api.RealmRepresentation, error) { var accessToken = ctx.Value("access_token").(string) @@ -178,20 +202,18 @@ func (c *component) CreateUser(ctx context.Context, realmName string, user api.U } //store the API call into the DB - var event = make(map[string]string) - event["ct_event_type"] = "API_ACCOUNT_CREATION" - event["realm_name"] = realmName - if user.Id != nil { - event["user_id"] = *user.Id - } + event := createEventMap("API_ACCOUNT_CREATION") + + var username = "" if user.Username != nil { - event["username"] = *user.Username + username = *user.Username } - event["origin"] = "back-office" - event["audit_time"] = time.Now().UTC().Format(timeFormat) - //retrieve details of the agent - addAgentDetails(ctx, event) + //retrieve the user ID + reg := regexp.MustCompile(`[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}`) + userID := string(reg.Find([]byte(locationURL))) + + addEventValues(ctx, event, "realm_name", realmName, "user_id", userID, "username", username) // the error should be treated _ = c.eventDBModule.Store(ctx, event) @@ -209,15 +231,9 @@ func (c *component) DeleteUser(ctx context.Context, realmName, userID string) er } //store the API call into the DB - var event = make(map[string]string) - event["ct_event_type"] = "API_ACCOUNT_DELETION" - event["realm_name"] = realmName - event["user_id"] = userID - event["origin"] = "back-office" - event["audit_time"] = time.Now().UTC().Format(timeFormat) + event := createEventMap("API_ACCOUNT_DELETION") - //retrieve details of the agent - addAgentDetails(ctx, event) + addEventValues(ctx, event, "realm_name", realmName, "user_id", userID) // the error should be treated _ = c.eventDBModule.Store(ctx, event) @@ -268,23 +284,20 @@ func (c *component) GetUser(ctx context.Context, realmName, userID string) (api. } //store the API call into the DB - var event = make(map[string]string) - event["ct_event_type"] = "GET_DETAILS" - event["realm_name"] = realmName - event["user_id"] = userID + event := createEventMap("GET_DETAILS") + + var username = "" if userKc.Username != nil { - event["username"] = *userKc.Username + username = *userKc.Username } - event["origin"] = "back-office" - event["audit_time"] = time.Now().UTC().Format(timeFormat) - //retrieve details of the agent - addAgentDetails(ctx, event) + addEventValues(ctx, event, "realm_name", realmName, "user_id", userID, "username", username) // the error should be treated _ = c.eventDBModule.Store(ctx, event) return userRep, nil + } func (c *component) UpdateUser(ctx context.Context, realmName, userID string, user api.UserRepresentation) error { @@ -326,28 +339,25 @@ func (c *component) UpdateUser(ctx context.Context, realmName, userID string, us return err } - //store the API call into the DB in case the user.Enable is present + //store the API call into the DB in case where user.Enable is present if user.Enabled != nil { - var event = make(map[string]string) - - event["realm_name"] = realmName - event["user_id"] = userID - if user.Username != nil { - event["username"] = *user.Username - } - event["origin"] = "back-office" - event["audit_time"] = time.Now().UTC().Format(timeFormat) - //retrieve details of the agent - addAgentDetails(ctx, event) - //add ct_event_type + var event map[string]string if *user.Enabled { // UNLOCK_ACCOUNT ct_event_type - event["ct_event_type"] = "UNLOCK_ACCOUNT" + event = createEventMap("UNLOCK_ACCOUNT") } else { // LOCK_ACCOUNT ct_event_type - event["ct_event_type"] = "LOCK_ACCOUNT" + event = createEventMap("LOCK_ACCOUNT") } + + var username = "" + if user.Username != nil { + username = *user.Username + } + + addEventValues(ctx, event, "realm_name", realmName, "user_id", userID, "username", username) + // the error should be treated _ = c.eventDBModule.Store(ctx, event) @@ -490,14 +500,9 @@ func (c *component) ResetPassword(ctx context.Context, realmName string, userID } //store the API call into the DB - var event = make(map[string]string) - event["ct_event_type"] = "INIT_PASSWORD" - event["realm_name"] = realmName - event["user_id"] = userID - event["origin"] = "back-office" - event["audit_time"] = time.Now().UTC().Format(timeFormat) - //retrieve details of the agent - addAgentDetails(ctx, event) + event := createEventMap("INIT_PASSWORD") + + addEventValues(ctx, event, "realm_name", realmName, "user_id", userID) // the error should be treated _ = c.eventDBModule.Store(ctx, event)