Skip to content

Commit

Permalink
Merge b406482 into 4005903
Browse files Browse the repository at this point in the history
  • Loading branch information
lagess committed Apr 18, 2019
2 parents 4005903 + b406482 commit 4e42a14
Show file tree
Hide file tree
Showing 27 changed files with 1,601 additions and 90 deletions.
12 changes: 6 additions & 6 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions api/management/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ type PasswordRepresentation struct {
Value *string `json:"value,omitempty"`
}

type RealmCustomConfiguration struct {
DefaultClientId *string `json:"default_client_id,omitempty"`
DefaultRedirectUri *string `json:"default_redirect_uri,omitempty"`
}

// ConvertCredential creates an API credential from a KC credential
func ConvertCredential(credKc *kc.CredentialRepresentation) CredentialRepresentation {
var cred CredentialRepresentation
Expand Down
95 changes: 69 additions & 26 deletions cmd/keycloakb/keycloak_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func main() {

// Enabled units
eventsDBEnabled = c.GetBool("events-db")
configDBEnabled = c.GetBool("config-db")
influxEnabled = c.GetBool("influx")
jaegerEnabled = c.GetBool("jaeger")
sentryEnabled = c.GetBool("sentry")
Expand Down Expand Up @@ -143,6 +144,11 @@ func main() {
dbMaxIdleConns = c.GetInt("db-max-idle-conns")
dbConnMaxLifetime = c.GetInt("db-conn-max-lifetime")

// DB for custom configuration
dbConfigUsername = c.GetString("db-config-username")
dbConfigPassword = c.GetString("db-config-password")
dbConfigDatabase = c.GetString("db-config-database")

// Rate limiting
rateLimit = map[string]int{
"event": c.GetInt("rate-event"),
Expand Down Expand Up @@ -260,15 +266,15 @@ func main() {
}

// Audit events DB.
type EventsDB interface {
type CloudtrustDB interface {
Exec(query string, args ...interface{}) (sql.Result, error)
QueryRow(query string, args ...interface{}) *sql.Row
SetMaxOpenConns(n int)
SetMaxIdleConns(n int)
SetConnMaxLifetime(d time.Duration)
}

var eventsDBConn EventsDB = keycloakb.NoopEventsDB{}
var eventsDBConn CloudtrustDB = keycloakb.NoopDB{}
if eventsDBEnabled {
var err error
eventsDBConn, err = sql.Open("mysql", fmt.Sprintf("%s:%s@%s(%s)/%s", dbUsername, dbPassword, dbProtocol, dbHostPort, dbDatabase))
Expand All @@ -284,6 +290,21 @@ func main() {

}

var configurationDBConn CloudtrustDB = keycloakb.NoopDB{}
if configDBEnabled {
var err error
configurationDBConn, err = sql.Open("mysql", fmt.Sprintf("%s:%s@%s(%s)/%s", dbConfigUsername, dbConfigPassword, dbProtocol, dbHostPort, dbConfigDatabase))

if err != nil {
logger.Log("msg", "could not create DB connection for configuration storage", "error", err)
return
}
// the config of the DB should have a max_connections > SetMaxOpenConns
configurationDBConn.SetMaxOpenConns(dbMaxOpenConns)
configurationDBConn.SetMaxIdleConns(dbMaxIdleConns)
configurationDBConn.SetConnMaxLifetime(time.Duration(dbConnMaxLifetime) * time.Second)
}

// Event service.
var eventEndpoints = event.Endpoints{}
{
Expand Down Expand Up @@ -312,7 +333,6 @@ func main() {
eventsDBModule = event.MakeEventsDBModuleInstrumentingMW(influxMetrics.NewHistogram("eventsDB_module"))(eventsDBModule)
eventsDBModule = event.MakeEventsDBModuleLoggingMW(log.With(eventLogger, "mw", "module", "unit", "eventsDB"))(eventsDBModule)
eventsDBModule = event.MakeEventsDBModuleTracingMW(tracer)(eventsDBModule)

}

var eventAdminComponent event.AdminComponent
Expand Down Expand Up @@ -372,37 +392,47 @@ func main() {
eventsDBModule = event.MakeEventsDBModuleInstrumentingMW(influxMetrics.NewHistogram("eventsDB_module"))(eventsDBModule)
eventsDBModule = event.MakeEventsDBModuleLoggingMW(log.With(managementLogger, "mw", "module", "unit", "eventsDB"))(eventsDBModule)
eventsDBModule = event.MakeEventsDBModuleTracingMW(tracer)(eventsDBModule)

}

// module for storing and retrieving the custom configuration
var configDBModule management.ConfigurationDBModule
{
configDBModule = management.NewConfigurationDBModule(configurationDBConn)
configDBModule = management.MakeConfigurationDBModuleInstrumentingMW(influxMetrics.NewHistogram("configDB_module"))(configDBModule)
configDBModule = management.MakeConfigurationDBModuleLoggingMW(log.With(managementLogger, "mw", "module", "unit", "configDB"))(configDBModule)
configDBModule = management.MakeConfigurationDBModuleTracingMW(tracer)(configDBModule)
}

var keycloakComponent management.Component
{
keycloakComponent = management.NewComponent(keycloakClient, eventsDBModule)
keycloakComponent = management.NewComponent(keycloakClient, eventsDBModule, configDBModule)
keycloakComponent = management.MakeAuthorizationManagementComponentMW(log.With(managementLogger, "mw", "endpoint"), keycloakClient, authorizationManager)(keycloakComponent)
}

managementEndpoints = management.Endpoints{
GetRealms: prepareEndpoint(management.MakeGetRealmsEndpoint(keycloakComponent), "realms_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRealm: prepareEndpoint(management.MakeGetRealmEndpoint(keycloakComponent), "realm_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClients: prepareEndpoint(management.MakeGetClientsEndpoint(keycloakComponent), "get_clients_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClient: prepareEndpoint(management.MakeGetClientEndpoint(keycloakComponent), "get_client_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
CreateUser: prepareEndpoint(management.MakeCreateUserEndpoint(keycloakComponent), "create_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetUser: prepareEndpoint(management.MakeGetUserEndpoint(keycloakComponent), "get_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
UpdateUser: prepareEndpoint(management.MakeUpdateUserEndpoint(keycloakComponent), "update_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
DeleteUser: prepareEndpoint(management.MakeDeleteUserEndpoint(keycloakComponent), "delete_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetUsers: prepareEndpoint(management.MakeGetUsersEndpoint(keycloakComponent), "get_users_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetUserAccountStatus: prepareEndpoint(management.MakeGetUserAccountStatusEndpoint(keycloakComponent), "get_user_accountstatus", influxMetrics, managementLogger, tracer, rateLimit),
GetRoles: prepareEndpoint(management.MakeGetRolesEndpoint(keycloakComponent), "get_roles_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRole: prepareEndpoint(management.MakeGetRoleEndpoint(keycloakComponent), "get_role_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClientRoles: prepareEndpoint(management.MakeGetClientRolesEndpoint(keycloakComponent), "get_client_roles_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
CreateClientRole: prepareEndpoint(management.MakeCreateClientRoleEndpoint(keycloakComponent), "create_client_role_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClientRoleForUser: prepareEndpoint(management.MakeGetClientRolesForUserEndpoint(keycloakComponent), "get_client_roles_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
AddClientRoleToUser: prepareEndpoint(management.MakeAddClientRolesToUserEndpoint(keycloakComponent), "get_client_roles_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRealmRoleForUser: prepareEndpoint(management.MakeGetRealmRolesForUserEndpoint(keycloakComponent), "get_realm_roles_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
ResetPassword: prepareEndpoint(management.MakeResetPasswordEndpoint(keycloakComponent), "reset_password_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
SendVerifyEmail: prepareEndpoint(management.MakeSendVerifyEmailEndpoint(keycloakComponent), "send_verify_email_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetCredentialsForUser: prepareEndpoint(management.MakeGetCredentialsForUserEndpoint(keycloakComponent), "get_credentials_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
DeleteCredentialsForUser: prepareEndpoint(management.MakeDeleteCredentialsForUserEndpoint(keycloakComponent), "delete_credentials_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRealms: prepareEndpoint(management.MakeGetRealmEndpoint(keycloakComponent), "realms_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRealm: prepareEndpoint(management.MakeGetRealmEndpoint(keycloakComponent), "realm_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClients: prepareEndpoint(management.MakeGetClientsEndpoint(keycloakComponent), "get_clients_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClient: prepareEndpoint(management.MakeGetClientEndpoint(keycloakComponent), "get_client_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
CreateUser: prepareEndpoint(management.MakeCreateUserEndpoint(keycloakComponent), "create_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetUser: prepareEndpoint(management.MakeGetUserEndpoint(keycloakComponent), "get_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
UpdateUser: prepareEndpoint(management.MakeUpdateUserEndpoint(keycloakComponent), "update_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
DeleteUser: prepareEndpoint(management.MakeDeleteUserEndpoint(keycloakComponent), "delete_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetUsers: prepareEndpoint(management.MakeGetUsersEndpoint(keycloakComponent), "get_users_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetUserAccountStatus: prepareEndpoint(management.MakeGetUserAccountStatusEndpoint(keycloakComponent), "get_user_accountstatus", influxMetrics, managementLogger, tracer, rateLimit),
GetRoles: prepareEndpoint(management.MakeGetRolesEndpoint(keycloakComponent), "get_roles_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRole: prepareEndpoint(management.MakeGetRoleEndpoint(keycloakComponent), "get_role_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClientRoles: prepareEndpoint(management.MakeGetClientRolesEndpoint(keycloakComponent), "get_client_roles_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
CreateClientRole: prepareEndpoint(management.MakeCreateClientRoleEndpoint(keycloakComponent), "create_client_role_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetClientRoleForUser: prepareEndpoint(management.MakeGetClientRolesForUserEndpoint(keycloakComponent), "get_client_roles_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
AddClientRoleToUser: prepareEndpoint(management.MakeAddClientRolesToUserEndpoint(keycloakComponent), "get_client_roles_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRealmRoleForUser: prepareEndpoint(management.MakeGetRealmRolesForUserEndpoint(keycloakComponent), "get_realm_roles_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
ResetPassword: prepareEndpoint(management.MakeResetPasswordEndpoint(keycloakComponent), "reset_password_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
SendVerifyEmail: prepareEndpoint(management.MakeSendVerifyEmailEndpoint(keycloakComponent), "send_verify_email_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetCredentialsForUser: prepareEndpoint(management.MakeGetCredentialsForUserEndpoint(keycloakComponent), "get_credentials_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
DeleteCredentialsForUser: prepareEndpoint(management.MakeDeleteCredentialsForUserEndpoint(keycloakComponent), "delete_credentials_for_user_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
GetRealmCustomConfiguration: prepareEndpoint(management.MakeGetRealmCustomConfigurationEndpoint(keycloakComponent), "get_realm_custom_config_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
UpdateRealmCustomConfiguration: prepareEndpoint(management.MakeUpdateRealmCustomConfigurationEndpoint(keycloakComponent), "update_realm_custom_config_endpoint", influxMetrics, managementLogger, tracer, rateLimit),
}
}

Expand Down Expand Up @@ -467,6 +497,9 @@ func main() {
var getCredentialsForUserHandler = ConfigureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, tracer, logger)(managementEndpoints.GetCredentialsForUser)
var deleteCredentialsForUserHandler = ConfigureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, tracer, logger)(managementEndpoints.DeleteCredentialsForUser)

var getRealmCustomConfigurationHandler = ConfigureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, tracer, logger)(managementEndpoints.GetRealmCustomConfiguration)
var updateRealmCustomConfigurationHandler = ConfigureManagementHandler(ComponentName, ComponentID, idGenerator, keycloakClient, tracer, logger)(managementEndpoints.UpdateRealmCustomConfiguration)

//realms
managementSubroute.Path("/realms").Methods("GET").Handler(getRealmsHandler)
managementSubroute.Path("/realms/{realm}").Methods("GET").Handler(getRealmHandler)
Expand Down Expand Up @@ -498,6 +531,10 @@ func main() {
managementSubroute.Path("/realms/{realm}/clients/{clientID}/roles").Methods("GET").Handler(getClientRolesHandler)
managementSubroute.Path("/realms/{realm}/clients/{clientID}/roles").Methods("POST").Handler(createClientRolesHandler)

// custom configuration par realm
managementSubroute.Path("/realms/{realm}/configuration").Methods("GET").Handler(getRealmCustomConfigurationHandler)
managementSubroute.Path("/realms/{realm}/configuration").Methods("PUT").Handler(updateRealmCustomConfigurationHandler)

// Export.
route.Handle("/export", export.MakeHTTPExportHandler(exportEndpoint)).Methods("GET")
route.Handle("/export", export.MakeHTTPExportHandler(exportSaveAndExportEndpoint)).Methods("POST")
Expand Down Expand Up @@ -595,6 +632,12 @@ func config(logger log.Logger) *viper.Viper {
v.SetDefault("db-max-idle-conns", 2)
v.SetDefault("db-conn-max-lifetime", 3600)

//Storage custom configuration in DB
v.SetDefault("config-db", true)
v.SetDefault("db-config-username", "")
v.SetDefault("db-config-password", "")
v.SetDefault("db-config-database", "")

// Rate limiting (in requests/second)
v.SetDefault("rate-event", 1000)
v.SetDefault("rate-management", 1000)
Expand Down
24 changes: 22 additions & 2 deletions configs/authorization.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,17 @@
"DEP": {
"*": {}
}
}
},
"GetRealmCustomConfiguration": {
"DEP": {
"*": {}
}
},
"UpdateRealmCustomConfiguration": {
"DEP": {
"*": {}
}
}
},
"integrator_agent":{
"GetRealms": {
Expand Down Expand Up @@ -151,7 +161,17 @@
"DEP": {
"*": {}
}
}
},
"GetRealmCustomConfiguration": {
"DEP": {
"*": {}
}
},
"UpdateRealmCustomConfiguration": {
"DEP": {
"*": {}
}
}
},
"l2_support_manager":{
"GetRealms": {
Expand Down
5 changes: 5 additions & 0 deletions configs/keycloak_bridge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ db-max-open-conns: 10
db-max-idle-conns: 2
db-conn-max-lifetime: 3600

# Configuration DB
db-config-username: bridge
db-config-password: bridge-password
db-config-database: cloudtrust_configuration

# audit events
events-db: true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,32 @@ import (
"time"
)

// NoopEventsDB is a eventsDB client that does nothing.
type NoopEventsDB struct{}
// NoopDB is a database client that does nothing.
type NoopDB struct{}

// Exec does nothing.
func (NoopEventsDB) Exec(query string, args ...interface{}) (sql.Result, error) {
func (NoopDB) Exec(query string, args ...interface{}) (sql.Result, error) {
return NoopResult{}, nil
}

// Query does nothing.
func (NoopEventsDB) Query(query string, args ...interface{}) (*sql.Rows, error) {
func (NoopDB) Query(query string, args ...interface{}) (*sql.Rows, error) {
return nil, nil
}

// QueryRow does nothing.
func (NoopEventsDB) QueryRow(query string, args ...interface{}) *sql.Row {
func (NoopDB) QueryRow(query string, args ...interface{}) *sql.Row {
return nil
}

func (NoopEventsDB) SetMaxOpenConns(n int) {
func (NoopDB) SetMaxOpenConns(n int) {

}
func (NoopEventsDB) SetMaxIdleConns(n int) {
func (NoopDB) SetMaxIdleConns(n int) {

}

func (NoopEventsDB) SetConnMaxLifetime(d time.Duration) {
func (NoopDB) SetConnMaxLifetime(d time.Duration) {

}

Expand Down
2 changes: 1 addition & 1 deletion internal/security/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ type AuthorizationManager interface {
//
// Note:
// '*' can be used to express all target realms
// '-' can be used to express all non master realms
// '/' can be used to express all non master realms
// '*' can be used to express all target groups are allowed
func NewAuthorizationManager(keycloakClient KeycloakClient, jsonAuthz string) (AuthorizationManager, error) {
matrix, err := loadAuthorizations(jsonAuthz)
Expand Down
22 changes: 22 additions & 0 deletions pkg/management/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,25 @@ func (c *authorizationComponentMW) CreateClientRole(ctx context.Context, realmNa

return c.next.CreateClientRole(ctx, realmName, clientID, role)
}

func (c *authorizationComponentMW) GetRealmCustomConfiguration(ctx context.Context, realmName string) (api.RealmCustomConfiguration, error) {
var action = "GetRealmCustomConfiguration"
var targetRealm = realmName

if err := c.authManager.CheckAuthorizationOnTargetRealm(ctx, action, targetRealm); err != nil {
return api.RealmCustomConfiguration{}, err
}

return c.next.GetRealmCustomConfiguration(ctx, realmName)
}

func (c *authorizationComponentMW) UpdateRealmCustomConfiguration(ctx context.Context, realmName string, customConfig api.RealmCustomConfiguration) error {
var action = "UpdateRealmCustomConfiguration"
var targetRealm = realmName

if err := c.authManager.CheckAuthorizationOnTargetRealm(ctx, action, targetRealm); err != nil {
return err
}

return c.next.UpdateRealmCustomConfiguration(ctx, realmName, customConfig)
}

0 comments on commit 4e42a14

Please sign in to comment.