mirror of
https://github.com/OpenMaxIO/openmaxio-object-browser
synced 2026-07-01 07:41:18 -07:00
Operator Console bug fixes and MinIO configuration file support (#898)
- Added support for MinIO configuration file - fix: tenant deployment with oidc integration - fix: tenant deployment with ldap integration - fix: certificate parsing for domains and IP addresses on security tab - fix: console certificate upload was not working Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
This commit is contained in:
4
go.mod
4
go.mod
@@ -22,8 +22,8 @@ require (
|
||||
github.com/minio/madmin-go v1.0.17
|
||||
github.com/minio/mc v0.0.0-20210626002108-cebf3318546f
|
||||
github.com/minio/minio-go/v7 v7.0.13-0.20210715203016-9e713532886e
|
||||
github.com/minio/operator v0.0.0-20210616045941-65f31f5f78ae
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210604224119-7e256f98cf90
|
||||
github.com/minio/operator v0.0.0-20210803012017-0f43eee7fd7a
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210803012017-0f43eee7fd7a
|
||||
github.com/minio/pkg v1.0.8
|
||||
github.com/minio/selfupdate v0.3.1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
|
||||
11
go.sum
11
go.sum
@@ -469,6 +469,8 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -876,7 +878,6 @@ github.com/minio/filepath v1.0.0 h1:fvkJu1+6X+ECRA6G3+JJETj4QeAYO9sV43I79H8ubDY=
|
||||
github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw=
|
||||
github.com/minio/kes v0.11.0 h1:8ma6OCVSxKT50b1uYXLJro3m7PmZtCLxBaTddQexI5k=
|
||||
github.com/minio/kes v0.11.0/go.mod h1:mTF1Bv8YVEtQqF/B7Felp4tLee44Pp+dgI0rhCvgNg8=
|
||||
github.com/minio/madmin-go v1.0.6/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
|
||||
github.com/minio/madmin-go v1.0.12/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
|
||||
github.com/minio/madmin-go v1.0.17 h1:VMEn4nMKf0X3uNH0u+fZcn17KSwVkQGwyER/igG556E=
|
||||
github.com/minio/madmin-go v1.0.17/go.mod h1:4nl9hvLWFnwCjkLfZSsZXEHgDODa2XSG6xGlIZyQ2oA=
|
||||
@@ -889,10 +890,10 @@ github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78/go.mod h1:mTh
|
||||
github.com/minio/minio-go/v7 v7.0.11-0.20210607181445-e162fdb8e584/go.mod h1:WoyW+ySKAKjY98B9+7ZbI8z8S3jaxaisdcvj9TGlazA=
|
||||
github.com/minio/minio-go/v7 v7.0.13-0.20210715203016-9e713532886e h1:aVnxKPpUI1gVeEf9vC+QEt8OxMXiiNMeUWcrBM62oDU=
|
||||
github.com/minio/minio-go/v7 v7.0.13-0.20210715203016-9e713532886e/go.mod h1:S23iSP5/gbMwtxeY5FM71R+TkAYyzEdoNEDDwpt8yWs=
|
||||
github.com/minio/operator v0.0.0-20210616045941-65f31f5f78ae h1:GONmqbjCi/KTEc1CGujnS/m1qeJeghcQ8dUBLh19qQo=
|
||||
github.com/minio/operator v0.0.0-20210616045941-65f31f5f78ae/go.mod h1:8/mIXK+CFdL6VqyxRn1SwD+PEX0jsN8uqjoadaw/Np0=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210604224119-7e256f98cf90 h1:Qu6j6oE7+QNuq7Kr2DLyVYq3fqMdqFd/T8NAeNp47og=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210604224119-7e256f98cf90/go.mod h1:R+38Pf3wfm+JMiyLPb/r8OMrBm0vK2hZgUT4y4aYoSY=
|
||||
github.com/minio/operator v0.0.0-20210803012017-0f43eee7fd7a h1:jvEyFZBLo1mIc5YTg+AIAieDkzoAnc9+j4yT5kZO15E=
|
||||
github.com/minio/operator v0.0.0-20210803012017-0f43eee7fd7a/go.mod h1:zQqn6VGT46xlSpVXh1I/VZRv+eSgHtVu6URdg71YKX8=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210803012017-0f43eee7fd7a h1:tnyzzgWP0PXM1nrwHtlyawuBguY+6R9/yee0bezbGDY=
|
||||
github.com/minio/operator/logsearchapi v0.0.0-20210803012017-0f43eee7fd7a/go.mod h1:R+38Pf3wfm+JMiyLPb/r8OMrBm0vK2hZgUT4y4aYoSY=
|
||||
github.com/minio/pkg v1.0.3/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8=
|
||||
github.com/minio/pkg v1.0.4/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8=
|
||||
github.com/minio/pkg v1.0.8 h1:lWQwHSeYlvnRoPpO+wS0I4mL6c00ABxBgbGjSmjwOi4=
|
||||
|
||||
@@ -227,9 +227,18 @@ type IdpConfigurationActiveDirectory struct {
|
||||
// group search filter
|
||||
GroupSearchFilter string `json:"group_search_filter,omitempty"`
|
||||
|
||||
// lookup bind dn
|
||||
LookupBindDn string `json:"lookup_bind_dn,omitempty"`
|
||||
|
||||
// lookup bind password
|
||||
LookupBindPassword string `json:"lookup_bind_password,omitempty"`
|
||||
|
||||
// server insecure
|
||||
ServerInsecure bool `json:"server_insecure,omitempty"`
|
||||
|
||||
// server start tls
|
||||
ServerStartTLS bool `json:"server_start_tls,omitempty"`
|
||||
|
||||
// skip tls verification
|
||||
SkipTLSVerification bool `json:"skip_tls_verification,omitempty"`
|
||||
|
||||
@@ -237,13 +246,20 @@ type IdpConfigurationActiveDirectory struct {
|
||||
// Required: true
|
||||
URL *string `json:"url"`
|
||||
|
||||
// user search filter
|
||||
// Required: true
|
||||
UserSearchFilter *string `json:"user_search_filter"`
|
||||
// user dn search base dn
|
||||
UserDnSearchBaseDn string `json:"user_dn_search_base_dn,omitempty"`
|
||||
|
||||
// user dn search filter
|
||||
UserDnSearchFilter string `json:"user_dn_search_filter,omitempty"`
|
||||
|
||||
// user dns
|
||||
UserDNS []string `json:"user_dns"`
|
||||
|
||||
// username format
|
||||
// Required: true
|
||||
UsernameFormat *string `json:"username_format"`
|
||||
UsernameFormat string `json:"username_format,omitempty"`
|
||||
|
||||
// username search filter
|
||||
UsernameSearchFilter string `json:"username_search_filter,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this idp configuration active directory
|
||||
@@ -254,14 +270,6 @@ func (m *IdpConfigurationActiveDirectory) Validate(formats strfmt.Registry) erro
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateUserSearchFilter(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateUsernameFormat(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
@@ -277,24 +285,6 @@ func (m *IdpConfigurationActiveDirectory) validateURL(formats strfmt.Registry) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IdpConfigurationActiveDirectory) validateUserSearchFilter(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("active_directory"+"."+"user_search_filter", "body", m.UserSearchFilter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IdpConfigurationActiveDirectory) validateUsernameFormat(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("active_directory"+"."+"username_format", "body", m.UsernameFormat); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this idp configuration active directory based on context it is used
|
||||
func (m *IdpConfigurationActiveDirectory) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
@@ -396,10 +386,24 @@ func (m *IdpConfigurationKeysItems0) UnmarshalBinary(b []byte) error {
|
||||
// swagger:model IdpConfigurationOidc
|
||||
type IdpConfigurationOidc struct {
|
||||
|
||||
// callback url
|
||||
CallbackURL string `json:"callback_url,omitempty"`
|
||||
|
||||
// claim name
|
||||
// Required: true
|
||||
ClaimName *string `json:"claim_name"`
|
||||
|
||||
// client id
|
||||
// Required: true
|
||||
ClientID *string `json:"client_id"`
|
||||
|
||||
// configuration url
|
||||
// Required: true
|
||||
ConfigurationURL *string `json:"configuration_url"`
|
||||
|
||||
// scopes
|
||||
Scopes string `json:"scopes,omitempty"`
|
||||
|
||||
// secret id
|
||||
// Required: true
|
||||
SecretID *string `json:"secret_id"`
|
||||
@@ -413,10 +417,18 @@ type IdpConfigurationOidc struct {
|
||||
func (m *IdpConfigurationOidc) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateClaimName(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateClientID(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateConfigurationURL(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSecretID(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -431,6 +443,15 @@ func (m *IdpConfigurationOidc) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IdpConfigurationOidc) validateClaimName(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("oidc"+"."+"claim_name", "body", m.ClaimName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IdpConfigurationOidc) validateClientID(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("oidc"+"."+"client_id", "body", m.ClientID); err != nil {
|
||||
@@ -440,6 +461,15 @@ func (m *IdpConfigurationOidc) validateClientID(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IdpConfigurationOidc) validateConfigurationURL(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("oidc"+"."+"configuration_url", "body", m.ConfigurationURL); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IdpConfigurationOidc) validateSecretID(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("oidc"+"."+"secret_id", "body", m.SecretID); err != nil {
|
||||
|
||||
@@ -66,8 +66,8 @@ type Tenant struct {
|
||||
// idp ad enabled
|
||||
IdpAdEnabled bool `json:"idpAdEnabled,omitempty"`
|
||||
|
||||
// idp oic enabled
|
||||
IdpOicEnabled bool `json:"idpOicEnabled,omitempty"`
|
||||
// idp oidc enabled
|
||||
IdpOidcEnabled bool `json:"idpOidcEnabled,omitempty"`
|
||||
|
||||
// image
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
@@ -2489,9 +2489,7 @@ func init() {
|
||||
"active_directory": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url",
|
||||
"username_format",
|
||||
"user_search_filter"
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"group_name_attribute": {
|
||||
@@ -2503,20 +2501,41 @@ func init() {
|
||||
"group_search_filter": {
|
||||
"type": "string"
|
||||
},
|
||||
"lookup_bind_dn": {
|
||||
"type": "string"
|
||||
},
|
||||
"lookup_bind_password": {
|
||||
"type": "string"
|
||||
},
|
||||
"server_insecure": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"server_start_tls": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"skip_tls_verification": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_search_filter": {
|
||||
"user_dn_search_base_dn": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_dn_search_filter": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_dns": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"username_format": {
|
||||
"type": "string"
|
||||
},
|
||||
"username_search_filter": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2541,14 +2560,28 @@ func init() {
|
||||
"oidc": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"configuration_url",
|
||||
"url",
|
||||
"client_id",
|
||||
"secret_id"
|
||||
"secret_id",
|
||||
"claim_name"
|
||||
],
|
||||
"properties": {
|
||||
"callback_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"claim_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"client_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"configuration_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "string"
|
||||
},
|
||||
"secret_id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -4230,7 +4263,7 @@ func init() {
|
||||
"idpAdEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"idpOicEnabled": {
|
||||
"idpOidcEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"image": {
|
||||
@@ -6441,9 +6474,7 @@ func init() {
|
||||
"IdpConfigurationActiveDirectory": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url",
|
||||
"username_format",
|
||||
"user_search_filter"
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"group_name_attribute": {
|
||||
@@ -6455,20 +6486,41 @@ func init() {
|
||||
"group_search_filter": {
|
||||
"type": "string"
|
||||
},
|
||||
"lookup_bind_dn": {
|
||||
"type": "string"
|
||||
},
|
||||
"lookup_bind_password": {
|
||||
"type": "string"
|
||||
},
|
||||
"server_insecure": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"server_start_tls": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"skip_tls_verification": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_search_filter": {
|
||||
"user_dn_search_base_dn": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_dn_search_filter": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_dns": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"username_format": {
|
||||
"type": "string"
|
||||
},
|
||||
"username_search_filter": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6490,14 +6542,28 @@ func init() {
|
||||
"IdpConfigurationOidc": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"configuration_url",
|
||||
"url",
|
||||
"client_id",
|
||||
"secret_id"
|
||||
"secret_id",
|
||||
"claim_name"
|
||||
],
|
||||
"properties": {
|
||||
"callback_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"claim_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"client_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"configuration_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "string"
|
||||
},
|
||||
"secret_id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -8073,9 +8139,7 @@ func init() {
|
||||
"active_directory": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url",
|
||||
"username_format",
|
||||
"user_search_filter"
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"group_name_attribute": {
|
||||
@@ -8087,20 +8151,41 @@ func init() {
|
||||
"group_search_filter": {
|
||||
"type": "string"
|
||||
},
|
||||
"lookup_bind_dn": {
|
||||
"type": "string"
|
||||
},
|
||||
"lookup_bind_password": {
|
||||
"type": "string"
|
||||
},
|
||||
"server_insecure": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"server_start_tls": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"skip_tls_verification": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_search_filter": {
|
||||
"user_dn_search_base_dn": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_dn_search_filter": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_dns": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"username_format": {
|
||||
"type": "string"
|
||||
},
|
||||
"username_search_filter": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8113,14 +8198,28 @@ func init() {
|
||||
"oidc": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"configuration_url",
|
||||
"url",
|
||||
"client_id",
|
||||
"secret_id"
|
||||
"secret_id",
|
||||
"claim_name"
|
||||
],
|
||||
"properties": {
|
||||
"callback_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"claim_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"client_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"configuration_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "string"
|
||||
},
|
||||
"secret_id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -9667,7 +9766,7 @@ func init() {
|
||||
"idpAdEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"idpOicEnabled": {
|
||||
"idpOidcEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"image": {
|
||||
|
||||
@@ -33,6 +33,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/console/pkg/auth/ldap"
|
||||
|
||||
"github.com/minio/console/pkg/auth/idp/oauth2"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
|
||||
"github.com/minio/console/restapi"
|
||||
@@ -435,8 +439,9 @@ func getTenantInfo(tenant *miniov2.Tenant) *models.Tenant {
|
||||
|
||||
func getTenantDetailsResponse(session *models.Principal, params operator_api.TenantDetailsParams) (*models.Tenant, *models.Error) {
|
||||
// 5 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
//ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
//defer cancel()
|
||||
ctx := context.Background()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
@@ -453,14 +458,6 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
|
||||
|
||||
info := getTenantInfo(minTenant)
|
||||
|
||||
// detect if AD is enabled
|
||||
adEnabled := false
|
||||
for _, env := range minTenant.Spec.Env {
|
||||
if env.Name == "MINIO_IDENTITY_LDAP_SERVER_ADDR" && env.Value != "" {
|
||||
adEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
// get Kubernetes Client
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
@@ -471,34 +468,51 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
|
||||
client: clientSet,
|
||||
}
|
||||
|
||||
// detect if OpenID is enabled
|
||||
tenantConfiguration := map[string][]byte{}
|
||||
|
||||
oicEnabled := false
|
||||
consoleSelector := fmt.Sprintf("%s-console", minTenant.Name)
|
||||
consoleSecretName := fmt.Sprintf("%s-secret", consoleSelector)
|
||||
consoleSecret, err := clientSet.CoreV1().Secrets(minTenant.Namespace).Get(ctx, consoleSecretName, metav1.GetOptions{})
|
||||
// we can tolerate not getting this secret
|
||||
if err != nil {
|
||||
restapi.LogError("unable to fetch existing secrets for %s: %v", minTenant.Name, err)
|
||||
for _, config := range minTenant.GetEnvVars() {
|
||||
tenantConfiguration[config.Name] = []byte(config.Value)
|
||||
}
|
||||
if consoleSecret != nil {
|
||||
if _, ok := consoleSecret.Data["CONSOLE_IDP_URL"]; ok {
|
||||
oicEnabled = true
|
||||
|
||||
if minTenant.HasCredsSecret() {
|
||||
minioSecret, err := clientSet.CoreV1().Secrets(minTenant.Namespace).Get(ctx, minTenant.Spec.CredsSecret.Name, metav1.GetOptions{})
|
||||
// we can tolerate not getting this secret
|
||||
if err != nil {
|
||||
restapi.LogError("unable to fetch existing secrets for %s: %v", minTenant.Name, err)
|
||||
}
|
||||
configFromCredsSecret := minioSecret.Data
|
||||
for key, val := range configFromCredsSecret {
|
||||
tenantConfiguration[key] = val
|
||||
}
|
||||
}
|
||||
if minTenant.HasConsoleEnabled() {
|
||||
for _, env := range minTenant.Spec.Console.Env {
|
||||
if env.Name == "CONSOLE_IDP_URL" {
|
||||
oicEnabled = true
|
||||
|
||||
if minTenant.HasConfigurationSecret() {
|
||||
minioConfigurationSecret, err := clientSet.CoreV1().Secrets(minTenant.Namespace).Get(ctx, minTenant.Spec.Configuration.Name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
configFromFile := miniov2.ParseRawConfiguration(minioConfigurationSecret.Data["config.env"])
|
||||
for key, val := range configFromFile {
|
||||
tenantConfiguration[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// detect if AD/LDAP is enabled
|
||||
ldapEnabled := false
|
||||
if string(tenantConfiguration["MINIO_IDENTITY_LDAP_SERVER_ADDR"]) != "" {
|
||||
ldapEnabled = true
|
||||
}
|
||||
|
||||
// detect if OpenID is enabled
|
||||
oidcEnabled := false
|
||||
if string(tenantConfiguration["MINIO_IDENTITY_OPENID_CONFIG_URL"]) != "" {
|
||||
oidcEnabled = true
|
||||
}
|
||||
|
||||
info.LogEnabled = minTenant.HasLogEnabled()
|
||||
info.MonitoringEnabled = minTenant.HasPrometheusEnabled()
|
||||
info.EncryptionEnabled = minTenant.HasKESEnabled()
|
||||
info.IdpAdEnabled = adEnabled
|
||||
info.IdpOicEnabled = oicEnabled
|
||||
info.IdpAdEnabled = ldapEnabled
|
||||
info.IdpOidcEnabled = oidcEnabled
|
||||
info.MinioTLS = minTenant.TLS()
|
||||
info.ConsoleTLS = minTenant.AutoCert() || minTenant.ConsoleExternalCert()
|
||||
info.ConsoleEnabled = minTenant.HasConsoleEnabled()
|
||||
@@ -607,10 +621,21 @@ func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespac
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domains := []string{}
|
||||
// append certificate domain names
|
||||
if len(cert.DNSNames) > 0 {
|
||||
domains = append(domains, cert.DNSNames...)
|
||||
}
|
||||
// append certificate IPs
|
||||
if len(cert.IPAddresses) > 0 {
|
||||
for _, ip := range cert.IPAddresses {
|
||||
domains = append(domains, ip.String())
|
||||
}
|
||||
}
|
||||
certificates = append(certificates, &models.CertificateInfo{
|
||||
SerialNumber: cert.SerialNumber.String(),
|
||||
Name: secret.Name,
|
||||
Domains: cert.DNSNames,
|
||||
Domains: domains,
|
||||
Expiry: cert.NotAfter.String(),
|
||||
})
|
||||
}
|
||||
@@ -656,7 +681,8 @@ func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov
|
||||
|
||||
func getTenantSecurityResponse(session *models.Principal, params operator_api.TenantSecurityParams) (*models.TenantSecurityResponse, *models.Error) {
|
||||
// 5 seconds timeout
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
//ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
//defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
@@ -989,6 +1015,8 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
var instanceSecret corev1.Secret
|
||||
var users []*corev1.LocalObjectReference
|
||||
|
||||
var tenantConfigurationENV string
|
||||
|
||||
// Create the secret for the root credentials
|
||||
secretName := fmt.Sprintf("%s-secret", tenantName)
|
||||
instanceSecret = corev1.Secret{
|
||||
@@ -1000,10 +1028,14 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
"accesskey": []byte(accessKey),
|
||||
"secretkey": []byte(secretKey),
|
||||
"accesskey": []byte(""),
|
||||
"secretkey": []byte(""),
|
||||
},
|
||||
}
|
||||
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_ROOT_USER=\"%s\"\n", accessKey)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_ROOT_PASSWORD=\"%s\"\n", secretKey)
|
||||
|
||||
_, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &instanceSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
@@ -1023,16 +1055,12 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
}
|
||||
}()
|
||||
|
||||
var environmentVariables []corev1.EnvVar
|
||||
// Check the Erasure Coding Parity for validity and pass it to Tenant
|
||||
if tenantReq.ErasureCodingParity > 0 {
|
||||
if tenantReq.ErasureCodingParity < 2 || tenantReq.ErasureCodingParity > 8 {
|
||||
return nil, prepareError(errorInvalidErasureCodingValue)
|
||||
}
|
||||
environmentVariables = append(environmentVariables, corev1.EnvVar{
|
||||
Name: "MINIO_STORAGE_CLASS_STANDARD",
|
||||
Value: fmt.Sprintf("EC:%d", tenantReq.ErasureCodingParity),
|
||||
})
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_STORAGE_CLASS_STANDARD=\"%s\"\n", fmt.Sprintf("EC:%d", tenantReq.ErasureCodingParity))
|
||||
}
|
||||
|
||||
//Construct a MinIO Instance with everything we are getting from parameters
|
||||
@@ -1047,87 +1075,120 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
CredsSecret: &corev1.LocalObjectReference{
|
||||
Name: secretName,
|
||||
},
|
||||
Env: environmentVariables,
|
||||
},
|
||||
}
|
||||
idpEnabled := false
|
||||
|
||||
// Enable IDP (Active Directory) for MinIO
|
||||
if tenantReq.Idp != nil && tenantReq.Idp.ActiveDirectory != nil {
|
||||
url := *tenantReq.Idp.ActiveDirectory.URL
|
||||
userNameFormat := *tenantReq.Idp.ActiveDirectory.UsernameFormat
|
||||
userSearchFilter := *tenantReq.Idp.ActiveDirectory.UserSearchFilter
|
||||
tlsSkipVerify := tenantReq.Idp.ActiveDirectory.SkipTLSVerification
|
||||
serverInsecure := tenantReq.Idp.ActiveDirectory.ServerInsecure
|
||||
groupSearchDN := tenantReq.Idp.ActiveDirectory.GroupSearchBaseDn
|
||||
groupSearchFilter := tenantReq.Idp.ActiveDirectory.GroupSearchFilter
|
||||
groupNameAttribute := tenantReq.Idp.ActiveDirectory.GroupNameAttribute
|
||||
if url != "" && userNameFormat != "" && userSearchFilter != "" {
|
||||
// CONSOLE_LDAP_ENABLED
|
||||
idpEnabled = true
|
||||
minInst.Spec.Env = append(minInst.Spec.Env, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_SERVER_ADDR",
|
||||
Value: userNameFormat,
|
||||
}, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_USERNAME_FORMAT",
|
||||
Value: userNameFormat,
|
||||
}, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_USERNAME_SEARCH_FILTER",
|
||||
Value: userSearchFilter,
|
||||
}, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_USERNAME_SEARCH_FILTER",
|
||||
Value: userSearchFilter,
|
||||
}, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN",
|
||||
Value: groupSearchDN,
|
||||
}, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER",
|
||||
Value: groupSearchFilter,
|
||||
}, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_GROUP_NAME_ATTRIBUTE",
|
||||
Value: groupNameAttribute,
|
||||
})
|
||||
if tenantReq.Idp != nil {
|
||||
// Enable IDP (Active Directory) for MinIO
|
||||
if tenantReq.Idp.ActiveDirectory != nil {
|
||||
serverAddress := *tenantReq.Idp.ActiveDirectory.URL
|
||||
userNameFormat := tenantReq.Idp.ActiveDirectory.UsernameFormat
|
||||
userNameSearchFilter := tenantReq.Idp.ActiveDirectory.UsernameSearchFilter
|
||||
groupNameAttribute := tenantReq.Idp.ActiveDirectory.GroupNameAttribute
|
||||
tlsSkipVerify := tenantReq.Idp.ActiveDirectory.SkipTLSVerification
|
||||
serverInsecure := tenantReq.Idp.ActiveDirectory.ServerInsecure
|
||||
lookupBindDN := tenantReq.Idp.ActiveDirectory.LookupBindDn
|
||||
lookupBindPassword := tenantReq.Idp.ActiveDirectory.LookupBindPassword
|
||||
userDNSearchBaseDN := tenantReq.Idp.ActiveDirectory.UserDnSearchBaseDn
|
||||
userDNSearchFilter := tenantReq.Idp.ActiveDirectory.UserDnSearchFilter
|
||||
groupSearchBaseDN := tenantReq.Idp.ActiveDirectory.GroupSearchBaseDn
|
||||
groupSearchFilter := tenantReq.Idp.ActiveDirectory.GroupSearchFilter
|
||||
serverStartTLS := tenantReq.Idp.ActiveDirectory.ServerStartTLS
|
||||
|
||||
// LDAP Server
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_SERVER_ADDR=\"%s\"\n", serverAddress)
|
||||
if tlsSkipVerify {
|
||||
minInst.Spec.Env = append(minInst.Spec.Env, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_TLS_SKIP_VERIFY",
|
||||
Value: "on",
|
||||
})
|
||||
tenantConfigurationENV += "export MINIO_IDENTITY_LDAP_TLS_SKIP_VERIFY=on\n"
|
||||
}
|
||||
if serverInsecure {
|
||||
minInst.Spec.Env = append(minInst.Spec.Env, corev1.EnvVar{
|
||||
Name: "MINIO_IDENTITY_LDAP_SERVER_INSECURE",
|
||||
Value: "on",
|
||||
})
|
||||
tenantConfigurationENV += "export MINIO_IDENTITY_LDAP_SERVER_INSECURE=on\n"
|
||||
}
|
||||
if serverStartTLS {
|
||||
tenantConfigurationENV += "export MINIO_IDENTITY_LDAP_SERVER_STARTTLS=on\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the secret any built-in user passed if no external IDP was configured
|
||||
if tenantReq.Idp != nil && len(tenantReq.Idp.Keys) > 0 && tenantReq.Idp.ActiveDirectory == nil && tenantReq.Idp.Oidc == nil {
|
||||
for i := 0; i < len(tenantReq.Idp.Keys); i++ {
|
||||
userSecretName := fmt.Sprintf("%s-user-%d", tenantName, i)
|
||||
users = append(users, &corev1.LocalObjectReference{Name: userSecretName})
|
||||
userSecret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: userSecretName,
|
||||
Labels: map[string]string{
|
||||
miniov2.TenantLabel: tenantName,
|
||||
// LDAP Username
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USERNAME_FORMAT=\"%s\"\n", userNameFormat)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USERNAME_SEARCH_FILTER=\"%s\"\n", userNameSearchFilter)
|
||||
|
||||
// LDAP Lookup
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN=\"%s\"\n", lookupBindDN)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD=\"%s\"\n", lookupBindPassword)
|
||||
|
||||
// LDAP User DN
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN=\"%s\"\n", userDNSearchBaseDN)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER=\"%s\"\n", userDNSearchFilter)
|
||||
|
||||
// LDAP Group
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_GROUP_NAME_ATTRIBUTE=\"%s\"\n", groupNameAttribute)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN=\"%s\"\n", groupSearchBaseDN)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER=\"%s\"\n", groupSearchFilter)
|
||||
|
||||
// Attach the list of LDAP user DNs that will be administrator for the Tenant
|
||||
for i, userDN := range tenantReq.Idp.ActiveDirectory.UserDNS {
|
||||
userSecretName := fmt.Sprintf("%s-user-%d", tenantName, i)
|
||||
users = append(users, &corev1.LocalObjectReference{Name: userSecretName})
|
||||
userSecret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: userSecretName,
|
||||
Labels: map[string]string{
|
||||
miniov2.TenantLabel: tenantName,
|
||||
},
|
||||
},
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
"CONSOLE_ACCESS_KEY": []byte(*tenantReq.Idp.Keys[i].AccessKey),
|
||||
"CONSOLE_SECRET_KEY": []byte(*tenantReq.Idp.Keys[i].SecretKey),
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
"CONSOLE_ACCESS_KEY": []byte(userDN),
|
||||
},
|
||||
}
|
||||
_, err := clientSet.CoreV1().Secrets(ns).Create(ctx, &userSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
}
|
||||
_, err := clientSet.CoreV1().Secrets(ns).Create(ctx, &userSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
// attach the users to the tenant
|
||||
minInst.Spec.Users = users
|
||||
|
||||
} else if tenantReq.Idp.Oidc != nil {
|
||||
// Enable IDP (OIDC) for MinIO
|
||||
url := *tenantReq.Idp.Oidc.ConfigurationURL
|
||||
clientID := *tenantReq.Idp.Oidc.ClientID
|
||||
secretID := *tenantReq.Idp.Oidc.SecretID
|
||||
claimName := *tenantReq.Idp.Oidc.ClaimName
|
||||
scopes := tenantReq.Idp.Oidc.Scopes
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CONFIG_URL=\"%s\"\n", url)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CLIENT_ID=\"%s\"\n", clientID)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CLIENT_SECRET=\"%s\"\n", secretID)
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_CLAIM_NAME=\"%s\"\n", claimName)
|
||||
if scopes == "" {
|
||||
scopes = "openid,profile,email"
|
||||
}
|
||||
tenantConfigurationENV += fmt.Sprintf("export MINIO_IDENTITY_OPENID_SCOPES=\"%s\"\n", scopes)
|
||||
} else if len(tenantReq.Idp.Keys) > 0 {
|
||||
// Create the secret any built-in user passed if no external IDP was configured
|
||||
for i := 0; i < len(tenantReq.Idp.Keys); i++ {
|
||||
userSecretName := fmt.Sprintf("%s-user-%d", tenantName, i)
|
||||
users = append(users, &corev1.LocalObjectReference{Name: userSecretName})
|
||||
userSecret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: userSecretName,
|
||||
Labels: map[string]string{
|
||||
miniov2.TenantLabel: tenantName,
|
||||
},
|
||||
},
|
||||
Immutable: &imm,
|
||||
Data: map[string][]byte{
|
||||
"CONSOLE_ACCESS_KEY": []byte(*tenantReq.Idp.Keys[i].AccessKey),
|
||||
"CONSOLE_SECRET_KEY": []byte(*tenantReq.Idp.Keys[i].SecretKey),
|
||||
},
|
||||
}
|
||||
_, err := clientSet.CoreV1().Secrets(ns).Create(ctx, &userSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
}
|
||||
// attach the users to the tenant
|
||||
minInst.Spec.Users = users
|
||||
}
|
||||
// attach the users to the tenant
|
||||
minInst.Spec.Users = users
|
||||
}
|
||||
|
||||
isEncryptionEnabled := false
|
||||
@@ -1225,7 +1286,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
consoleSecretData[restapi.ConsoleSubnetLicense] = []byte(license)
|
||||
}
|
||||
imm := true
|
||||
instanceSecret := corev1.Secret{
|
||||
consoleSecret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: consoleSecretName,
|
||||
Labels: map[string]string{
|
||||
@@ -1262,28 +1323,35 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
|
||||
// If IDP is not already enabled via LDAP (Active Directory) and OIDC configuration is present then
|
||||
// enable oidc for console
|
||||
if !idpEnabled && tenantReq.Idp != nil && tenantReq.Idp.Oidc != nil {
|
||||
url := *tenantReq.Idp.Oidc.URL
|
||||
clientID := *tenantReq.Idp.Oidc.ClientID
|
||||
secretID := *tenantReq.Idp.Oidc.SecretID
|
||||
if url != "" && clientID != "" && secretID != "" {
|
||||
instanceSecret.Data["CONSOLE_IDP_URL"] = []byte(url)
|
||||
instanceSecret.Data["CONSOLE_IDP_CLIENT_ID"] = []byte(clientID)
|
||||
instanceSecret.Data["CONSOLE_IDP_SECRET"] = []byte(secretID)
|
||||
consoleScheme := "http"
|
||||
consolePort := 9090
|
||||
// If Console will be deployed with TLS enabled (using AutoCert or External certificates)
|
||||
if consoleHasTLS {
|
||||
consoleScheme = "https"
|
||||
consolePort = 9443
|
||||
if tenantReq.Idp != nil {
|
||||
if tenantReq.Idp.ActiveDirectory != nil {
|
||||
consoleSecret.Data[ldap.ConsoleLDAPEnabled] = []byte("on")
|
||||
} else if tenantReq.Idp.Oidc != nil {
|
||||
url := *tenantReq.Idp.Oidc.URL
|
||||
clientID := *tenantReq.Idp.Oidc.ClientID
|
||||
secretID := *tenantReq.Idp.Oidc.SecretID
|
||||
callbackURL := tenantReq.Idp.Oidc.CallbackURL
|
||||
if url != "" && clientID != "" && secretID != "" {
|
||||
consoleSecret.Data[oauth2.ConsoleIdpURL] = []byte(url)
|
||||
consoleSecret.Data[oauth2.ConsoleIdpClientID] = []byte(clientID)
|
||||
consoleSecret.Data[oauth2.ConsoleIdpSecret] = []byte(secretID)
|
||||
consoleScheme := "http"
|
||||
consolePort := miniov2.ConsolePort
|
||||
// If Console will be deployed with TLS enabled (using AutoCert or External certificates)
|
||||
if consoleHasTLS {
|
||||
consoleScheme = "https"
|
||||
consolePort = miniov2.ConsoleTLSPort
|
||||
}
|
||||
// default callback url is https://localhost:9443/oauth_callback
|
||||
consoleSecret.Data[oauth2.ConsoleIdpCallbackURL] = []byte(fmt.Sprintf("%s://localhost:%d/oauth_callback", consoleScheme, consolePort))
|
||||
if callbackURL != "" {
|
||||
consoleSecret.Data[oauth2.ConsoleIdpCallbackURL] = []byte(callbackURL)
|
||||
}
|
||||
}
|
||||
// https://[HOSTNAME]:9443 will be replaced by javascript in the browser to use the actual hostname
|
||||
// assigned to Console, eg: https://localhost:9443
|
||||
instanceSecret.Data["CONSOLE_IDP_CALLBACK"] = []byte(fmt.Sprintf("%s://[HOSTNAME]:%d/oauth_callback", consoleScheme, consolePort))
|
||||
}
|
||||
}
|
||||
|
||||
_, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &instanceSecret, metav1.CreateOptions{})
|
||||
_, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &consoleSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, prepareError(restapi.ErrorGeneric)
|
||||
}
|
||||
@@ -1463,13 +1531,26 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
|
||||
}
|
||||
|
||||
// expose services
|
||||
if tenantReq.ExposeMinio || tenantReq.ExposeConsole {
|
||||
minInst.Spec.ExposeServices = &miniov2.ExposeServices{
|
||||
MinIO: tenantReq.ExposeMinio,
|
||||
Console: tenantReq.ExposeConsole,
|
||||
}
|
||||
minInst.Spec.ExposeServices = &miniov2.ExposeServices{
|
||||
MinIO: tenantReq.ExposeMinio,
|
||||
Console: tenantReq.ExposeConsole,
|
||||
}
|
||||
|
||||
// write tenant configuration to secret that contains config.env
|
||||
tenantConfigurationName := fmt.Sprintf("%s-env-configuration", tenantName)
|
||||
_, err = createOrReplaceSecrets(ctx, &k8sClient, ns, []tenantSecret{
|
||||
{
|
||||
Name: tenantConfigurationName,
|
||||
Content: map[string][]byte{
|
||||
"config.env": []byte(tenantConfigurationENV),
|
||||
},
|
||||
},
|
||||
}, tenantName)
|
||||
if err != nil {
|
||||
return nil, prepareError(restapi.ErrorGeneric, nil, err)
|
||||
}
|
||||
minInst.Spec.Configuration = &corev1.LocalObjectReference{Name: tenantConfigurationName}
|
||||
|
||||
opClient, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.8cfac526.chunk.css",
|
||||
"main.js": "/static/js/main.68952acf.chunk.js",
|
||||
"main.js.map": "/static/js/main.68952acf.chunk.js.map",
|
||||
"main.js": "/static/js/main.ab419c40.chunk.js",
|
||||
"main.js.map": "/static/js/main.ab419c40.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.43a31377.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.43a31377.js.map",
|
||||
"static/css/2.60e04a19.chunk.css": "/static/css/2.60e04a19.chunk.css",
|
||||
"static/js/2.d3eeac57.chunk.js": "/static/js/2.d3eeac57.chunk.js",
|
||||
"static/js/2.d3eeac57.chunk.js.map": "/static/js/2.d3eeac57.chunk.js.map",
|
||||
"static/js/2.c9598ac3.chunk.js": "/static/js/2.c9598ac3.chunk.js",
|
||||
"static/js/2.c9598ac3.chunk.js.map": "/static/js/2.c9598ac3.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/2.60e04a19.chunk.css.map": "/static/css/2.60e04a19.chunk.css.map",
|
||||
"static/css/main.8cfac526.chunk.css.map": "/static/css/main.8cfac526.chunk.css.map",
|
||||
"static/js/2.d3eeac57.chunk.js.LICENSE.txt": "/static/js/2.d3eeac57.chunk.js.LICENSE.txt",
|
||||
"static/js/2.c9598ac3.chunk.js.LICENSE.txt": "/static/js/2.c9598ac3.chunk.js.LICENSE.txt",
|
||||
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
|
||||
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.43a31377.js",
|
||||
"static/css/2.60e04a19.chunk.css",
|
||||
"static/js/2.d3eeac57.chunk.js",
|
||||
"static/js/2.c9598ac3.chunk.js",
|
||||
"static/css/main.8cfac526.chunk.css",
|
||||
"static/js/main.68952acf.chunk.js"
|
||||
"static/js/main.ab419c40.chunk.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link href="/styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.d3eeac57.chunk.js"></script><script src="/static/js/main.68952acf.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link href="/styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.c9598ac3.chunk.js"></script><script src="/static/js/main.ab419c40.chunk.js"></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/main.ab419c40.chunk.js
Normal file
2
portal-ui/build/static/js/main.ab419c40.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/main.ab419c40.chunk.js.map
Normal file
1
portal-ui/build/static/js/main.ab419c40.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -256,10 +256,16 @@ export interface IActiveDirectoryConfiguration {
|
||||
url: string;
|
||||
skip_tls_verification: boolean;
|
||||
server_insecure: boolean;
|
||||
user_search_filter: string;
|
||||
server_start_tls: boolean;
|
||||
username_search_filter: string;
|
||||
group_Search_base_dn: string;
|
||||
group_search_filter: string;
|
||||
group_name_attribute: string;
|
||||
user_dns: string[];
|
||||
lookup_bind_dn: string;
|
||||
lookup_bind_password: string;
|
||||
user_dn_search_base_dn: string;
|
||||
user_dn_search_filter: string;
|
||||
}
|
||||
|
||||
export interface IStorageDistribution {
|
||||
|
||||
@@ -103,15 +103,28 @@ const AddTenant = ({
|
||||
const exposeConsole = fields.configure.exposeConsole;
|
||||
const idpSelection = fields.identityProvider.idpSelection;
|
||||
const openIDURL = fields.identityProvider.openIDURL;
|
||||
const openIDConfigurationURL =
|
||||
fields.identityProvider.openIDConfigurationURL;
|
||||
const openIDClientID = fields.identityProvider.openIDClientID;
|
||||
const openIDClaimName = fields.identityProvider.openIDClaimName;
|
||||
const openIDCallbackURL = fields.identityProvider.openIDCallbackURL;
|
||||
const openIDScopes = fields.identityProvider.openIDScopes;
|
||||
const openIDSecretID = fields.identityProvider.openIDSecretID;
|
||||
const ADURL = fields.identityProvider.ADURL;
|
||||
const ADSkipTLS = fields.identityProvider.ADSkipTLS;
|
||||
const ADServerInsecure = fields.identityProvider.ADServerInsecure;
|
||||
const ADUserNameFilter = fields.identityProvider.ADUserNameFilter;
|
||||
const ADGroupBaseDN = fields.identityProvider.ADGroupBaseDN;
|
||||
const ADUserNameSearchFilter =
|
||||
fields.identityProvider.ADUserNameSearchFilter;
|
||||
const ADGroupSearchBaseDN = fields.identityProvider.ADGroupSearchBaseDN;
|
||||
const ADGroupSearchFilter = fields.identityProvider.ADGroupSearchFilter;
|
||||
const ADNameAttribute = fields.identityProvider.ADNameAttribute;
|
||||
const ADGroupNameAttribute = fields.identityProvider.ADGroupNameAttribute;
|
||||
const ADUserDNs = fields.identityProvider.ADUserDNs;
|
||||
const ADUserNameFormat = fields.identityProvider.ADUserNameFormat;
|
||||
const ADLookupBindDN = fields.identityProvider.ADLookupBindDN;
|
||||
const ADLookupBindPassword = fields.identityProvider.ADLookupBindPassword;
|
||||
const ADUserDNSearchBaseDN = fields.identityProvider.ADUserDNSearchBaseDN;
|
||||
const ADUserDNSearchFilter = fields.identityProvider.ADUserDNSearchFilter;
|
||||
const ADServerStartTLS = fields.identityProvider.ADServerStartTLS;
|
||||
const accessKeys = fields.identityProvider.accessKeys;
|
||||
const secretKeys = fields.identityProvider.secretKeys;
|
||||
const minioCertificates = certificates.minioCertificates;
|
||||
@@ -503,8 +516,12 @@ const AddTenant = ({
|
||||
dataIDP = {
|
||||
oidc: {
|
||||
url: openIDURL,
|
||||
configuration_url: openIDConfigurationURL,
|
||||
client_id: openIDClientID,
|
||||
secret_id: openIDSecretID,
|
||||
claim_name: openIDClaimName,
|
||||
callback_url: openIDCallbackURL,
|
||||
scopes: openIDScopes,
|
||||
},
|
||||
};
|
||||
break;
|
||||
@@ -514,11 +531,17 @@ const AddTenant = ({
|
||||
url: ADURL,
|
||||
skip_tls_verification: ADSkipTLS,
|
||||
server_insecure: ADServerInsecure,
|
||||
username_format: "",
|
||||
user_search_filter: ADUserNameFilter,
|
||||
group_search_base_dn: ADGroupBaseDN,
|
||||
username_format: ADUserNameFormat,
|
||||
username_search_filter: ADUserNameSearchFilter,
|
||||
group_search_base_dn: ADGroupSearchBaseDN,
|
||||
group_search_filter: ADGroupSearchFilter,
|
||||
group_name_attribute: ADNameAttribute,
|
||||
group_name_attribute: ADGroupNameAttribute,
|
||||
user_dns: ADUserDNs,
|
||||
lookup_bind_dn: ADLookupBindDN,
|
||||
lookup_bind_password: ADLookupBindPassword,
|
||||
user_dn_search_base_dn: ADUserDNSearchBaseDN,
|
||||
user_dn_search_filter: ADUserDNSearchFilter,
|
||||
server_start_tls: ADServerStartTLS,
|
||||
},
|
||||
};
|
||||
break;
|
||||
@@ -528,7 +551,6 @@ const AddTenant = ({
|
||||
...dataSend,
|
||||
idp: { ...dataIDP },
|
||||
};
|
||||
|
||||
api
|
||||
.invoke("POST", `/api/v1/tenants`, dataSend)
|
||||
.then((res) => {
|
||||
|
||||
@@ -42,15 +42,26 @@ interface IIdentityProviderProps {
|
||||
accessKeys: string[];
|
||||
secretKeys: string[];
|
||||
openIDURL: string;
|
||||
openIDConfigurationURL: string;
|
||||
openIDClientID: string;
|
||||
openIDSecretID: string;
|
||||
openIDCallbackURL: string;
|
||||
openIDClaimName: string;
|
||||
openIDScopes: string;
|
||||
ADURL: string;
|
||||
ADSkipTLS: boolean;
|
||||
ADServerInsecure: boolean;
|
||||
ADUserNameFilter: string;
|
||||
ADGroupBaseDN: string;
|
||||
ADUserNameSearchFilter: string;
|
||||
ADGroupSearchBaseDN: string;
|
||||
ADGroupSearchFilter: string;
|
||||
ADNameAttribute: string;
|
||||
ADGroupNameAttribute: string;
|
||||
ADUserDNs: string[];
|
||||
ADUserNameFormat: string;
|
||||
ADLookupBindDN: string;
|
||||
ADLookupBindPassword: string;
|
||||
ADUserDNSearchBaseDN: string;
|
||||
ADUserDNSearchFilter: string;
|
||||
ADServerStartTLS: boolean;
|
||||
updateAddField: typeof updateAddField;
|
||||
isPageValid: typeof isPageValid;
|
||||
}
|
||||
@@ -82,15 +93,26 @@ const IdentityProvider = ({
|
||||
accessKeys,
|
||||
secretKeys,
|
||||
openIDURL,
|
||||
openIDConfigurationURL,
|
||||
openIDClientID,
|
||||
openIDSecretID,
|
||||
openIDCallbackURL,
|
||||
openIDClaimName,
|
||||
openIDScopes,
|
||||
ADURL,
|
||||
ADSkipTLS,
|
||||
ADServerInsecure,
|
||||
ADUserNameFilter,
|
||||
ADGroupBaseDN,
|
||||
ADUserNameSearchFilter,
|
||||
ADGroupSearchBaseDN,
|
||||
ADGroupSearchFilter,
|
||||
ADNameAttribute,
|
||||
ADGroupNameAttribute,
|
||||
ADUserDNs,
|
||||
ADUserNameFormat,
|
||||
ADLookupBindDN,
|
||||
ADLookupBindPassword,
|
||||
ADUserDNSearchBaseDN,
|
||||
ADUserDNSearchFilter,
|
||||
ADServerStartTLS,
|
||||
updateAddField,
|
||||
isPageValid,
|
||||
}: IIdentityProviderProps) => {
|
||||
@@ -112,7 +134,11 @@ const IdentityProvider = ({
|
||||
newUserField[index] = value;
|
||||
updateField("secretKeys", newUserField);
|
||||
};
|
||||
|
||||
const updateADUserField = (index: number, value: string) => {
|
||||
const newADUserDNsField = [...ADUserDNs];
|
||||
newADUserDNsField[index] = value;
|
||||
updateField("ADUserDNs", newADUserDNsField);
|
||||
};
|
||||
const cleanValidation = (fieldName: string) => {
|
||||
setValidationErrors(clearValidationError(validationErrors, fieldName));
|
||||
};
|
||||
@@ -150,6 +176,11 @@ const IdentityProvider = ({
|
||||
required: true,
|
||||
value: openIDURL,
|
||||
},
|
||||
{
|
||||
fieldKey: "openID_CONFIGURATION_URL",
|
||||
required: true,
|
||||
value: openIDConfigurationURL,
|
||||
},
|
||||
{
|
||||
fieldKey: "openID_clientID",
|
||||
required: true,
|
||||
@@ -160,6 +191,11 @@ const IdentityProvider = ({
|
||||
required: true,
|
||||
value: openIDSecretID,
|
||||
},
|
||||
{
|
||||
fieldKey: "openID_claimName",
|
||||
required: true,
|
||||
value: openIDClaimName,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -171,27 +207,15 @@ const IdentityProvider = ({
|
||||
required: true,
|
||||
value: ADURL,
|
||||
},
|
||||
{
|
||||
fieldKey: "ad_userNameFilter",
|
||||
required: true,
|
||||
value: ADUserNameFilter,
|
||||
},
|
||||
{
|
||||
fieldKey: "ad_groupBaseDN",
|
||||
required: true,
|
||||
value: ADGroupBaseDN,
|
||||
},
|
||||
{
|
||||
fieldKey: "ad_groupSearchFilter",
|
||||
required: true,
|
||||
value: ADGroupSearchFilter,
|
||||
},
|
||||
{
|
||||
fieldKey: "ad_nameAttribute",
|
||||
required: true,
|
||||
value: ADNameAttribute,
|
||||
},
|
||||
];
|
||||
// validate user DNs
|
||||
for (let i = 0; i < ADUserDNs.length; i++) {
|
||||
customIDPValidation.push({
|
||||
fieldKey: `ad-userdn-${i.toString()}`,
|
||||
required: true,
|
||||
value: ADUserDNs[i],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const commonVal = commonFormValidation(customIDPValidation);
|
||||
@@ -207,10 +231,11 @@ const IdentityProvider = ({
|
||||
openIDClientID,
|
||||
openIDSecretID,
|
||||
ADURL,
|
||||
ADUserNameFilter,
|
||||
ADGroupBaseDN,
|
||||
ADUserNameSearchFilter,
|
||||
ADGroupSearchBaseDN,
|
||||
ADGroupSearchFilter,
|
||||
ADNameAttribute,
|
||||
ADGroupNameAttribute,
|
||||
ADUserDNs,
|
||||
isPageValid,
|
||||
]);
|
||||
let inputs = null;
|
||||
@@ -296,6 +321,60 @@ const IdentityProvider = ({
|
||||
);
|
||||
});
|
||||
}
|
||||
if (idpSelection === "AD") {
|
||||
inputs = ADUserDNs.map((_, index) => {
|
||||
return (
|
||||
<Fragment key={`identityField-${index.toString()}`}>
|
||||
<div className={classes.shortened}>
|
||||
<InputBoxWrapper
|
||||
id={`ad-userdn-${index.toString()}`}
|
||||
label={""}
|
||||
placeholder=""
|
||||
name={`ad-userdn-${index.toString()}`}
|
||||
value={ADUserDNs[index]}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateADUserField(index, e.target.value);
|
||||
cleanValidation(`ad-userdn-${index.toString()}`);
|
||||
}}
|
||||
index={index}
|
||||
key={`csv-ad-userdn-${index.toString()}`}
|
||||
error={validationErrors[`ad-userdn-${index.toString()}`] || ""}
|
||||
/>
|
||||
<div className={classes.buttonTray}>
|
||||
<Tooltip title="Add User" aria-label="add">
|
||||
<IconButton
|
||||
size={"small"}
|
||||
onClick={() => {
|
||||
ADUserDNs.push("");
|
||||
updateADUserField(ADUserDNs.length - 1, "");
|
||||
}}
|
||||
>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Remove" aria-label="add">
|
||||
<IconButton
|
||||
size={"small"}
|
||||
style={{ marginLeft: 16 }}
|
||||
onClick={() => {
|
||||
if (ADUserDNs.length > 1) {
|
||||
ADUserDNs.splice(index, 1);
|
||||
updateUserField(
|
||||
ADUserDNs.length - 1,
|
||||
ADUserDNs[ADUserDNs.length - 1]
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
});
|
||||
}
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={classes.headerElement}>
|
||||
@@ -320,9 +399,13 @@ const IdentityProvider = ({
|
||||
{ label: "Active Directory", value: "AD" },
|
||||
]}
|
||||
/>
|
||||
Add additional users
|
||||
</Grid>{" "}
|
||||
{idpSelection === "Built-in" && <Fragment>{inputs}</Fragment>}
|
||||
</Grid>
|
||||
{idpSelection === "Built-in" && (
|
||||
<Fragment>
|
||||
Add additional users
|
||||
{inputs}
|
||||
</Fragment>
|
||||
)}
|
||||
{idpSelection === "OpenID" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12}>
|
||||
@@ -335,10 +418,26 @@ const IdentityProvider = ({
|
||||
}}
|
||||
label="URL"
|
||||
value={openIDURL}
|
||||
placeholder="https://your-identity-provider.com/"
|
||||
error={validationErrors["openID_URL"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="openID_CONFIGURATION_URL"
|
||||
name="openID_CONFIGURATION_URL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("openIDConfigurationURL", e.target.value);
|
||||
cleanValidation("openID_CONFIGURATION_URL");
|
||||
}}
|
||||
label="Configuration URL"
|
||||
value={openIDConfigurationURL}
|
||||
placeholder="https://your-identity-provider.com/.well-known/openid-configuration"
|
||||
error={validationErrors["openID_CONFIGURATION_URL"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="openID_clientID"
|
||||
@@ -367,6 +466,46 @@ const IdentityProvider = ({
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="openID_callbackURL"
|
||||
name="openID_callbackURL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("openIDCallbackURL", e.target.value);
|
||||
cleanValidation("openID_callbackURL");
|
||||
}}
|
||||
label="Callback URL"
|
||||
value={openIDCallbackURL}
|
||||
placeholder="https://your-console-endpoint:9443/oauth_callback"
|
||||
error={validationErrors["openID_callbackURL"] || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="openID_claimName"
|
||||
name="openID_claimName"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("openIDClaimName", e.target.value);
|
||||
cleanValidation("openID_claimName");
|
||||
}}
|
||||
label="Claim Name"
|
||||
value={openIDClaimName}
|
||||
error={validationErrors["openID_claimName"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="openID_scopes"
|
||||
name="openID_scopes"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("openIDScopes", e.target.value);
|
||||
cleanValidation("openID_scopes");
|
||||
}}
|
||||
label="Scopes"
|
||||
value={openIDScopes}
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
{idpSelection === "AD" && (
|
||||
@@ -379,8 +518,9 @@ const IdentityProvider = ({
|
||||
updateField("ADURL", e.target.value);
|
||||
cleanValidation("AD_URL");
|
||||
}}
|
||||
label="URL"
|
||||
label="LDAP Server Address"
|
||||
value={ADURL}
|
||||
placeholder="ldap-server:636"
|
||||
error={validationErrors["AD_URL"] || ""}
|
||||
required
|
||||
/>
|
||||
@@ -394,7 +534,6 @@ const IdentityProvider = ({
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
|
||||
updateField("ADSkipTLS", checked);
|
||||
}}
|
||||
label={"Skip TLS Verification"}
|
||||
@@ -409,7 +548,6 @@ const IdentityProvider = ({
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
|
||||
updateField("ADServerInsecure", checked);
|
||||
}}
|
||||
label={"Server Insecure"}
|
||||
@@ -429,31 +567,53 @@ const IdentityProvider = ({
|
||||
</Grid>
|
||||
) : null}
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userNameFilter"
|
||||
name="ad_userNameFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADUserNameFilter", e.target.value);
|
||||
cleanValidation("ad_userNameFilter");
|
||||
<FormSwitchWrapper
|
||||
value="ad_serverStartTLS"
|
||||
id="ad_serverStartTLS"
|
||||
name="ad_serverStartTLS"
|
||||
checked={ADServerStartTLS}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
updateField("ADServerStartTLS", checked);
|
||||
}}
|
||||
label="User Search Filter"
|
||||
value={ADUserNameFilter}
|
||||
error={validationErrors["ad_userNameFilter"] || ""}
|
||||
required
|
||||
label={"Start TLS connection to AD/LDAP server"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_groupBaseDN"
|
||||
name="ad_groupBaseDN"
|
||||
id="ad_userNameFormat"
|
||||
name="ad_userNameFormat"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADGroupBaseDN", e.target.value);
|
||||
cleanValidation("ad_groupBaseDN");
|
||||
updateField("ADUserNameFormat", e.target.value);
|
||||
}}
|
||||
label="Username Format"
|
||||
value={ADUserNameFormat}
|
||||
placeholder="uid=%s,cn=accounts,dc=myldapserver,dc=com"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userNameFilter"
|
||||
name="ad_userNameFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADUserNameSearchFilter", e.target.value);
|
||||
}}
|
||||
label="Username Search Filter"
|
||||
value={ADUserNameSearchFilter}
|
||||
placeholder="(|(objectclass=posixAccount)(uid=%s))"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_groupSearchBaseDN"
|
||||
name="ad_groupSearchBaseDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADGroupSearchBaseDN", e.target.value);
|
||||
}}
|
||||
label="Group Search Base DN"
|
||||
value={ADGroupBaseDN}
|
||||
error={validationErrors["ad_groupBaseDN"] || ""}
|
||||
required
|
||||
value={ADGroupSearchBaseDN}
|
||||
placeholder="ou=hwengg,dc=min,dc=io;ou=swengg,dc=min,dc=io"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
@@ -462,28 +622,76 @@ const IdentityProvider = ({
|
||||
name="ad_groupSearchFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADGroupSearchFilter", e.target.value);
|
||||
cleanValidation("ad_groupSearchFilter");
|
||||
}}
|
||||
label="Group Search Filter"
|
||||
value={ADGroupSearchFilter}
|
||||
error={validationErrors["ad_groupSearchFilter"] || ""}
|
||||
required
|
||||
placeholder="(&(objectclass=groupOfNames)(member=%s))"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_nameAttribute"
|
||||
name="ad_nameAttribute"
|
||||
id="ad_groupNameAttribute"
|
||||
name="ad_groupNameAttribute"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADNameAttribute", e.target.value);
|
||||
cleanValidation("ad_nameAttribute");
|
||||
updateField("ADGroupNameAttribute", e.target.value);
|
||||
}}
|
||||
label="Group Name Attribute"
|
||||
value={ADNameAttribute}
|
||||
error={validationErrors["ad_nameAttribute"] || ""}
|
||||
required
|
||||
value={ADGroupNameAttribute}
|
||||
placeholder="cn"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_lookupBindDN"
|
||||
name="ad_lookupBindDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADLookupBindDN", e.target.value);
|
||||
}}
|
||||
label="Lookup Bind DN"
|
||||
value={ADLookupBindDN}
|
||||
placeholder="cn=admin,dc=min,dc=io"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_lookupBindPassword"
|
||||
name="ad_lookupBindPassword"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADLookupBindPassword", e.target.value);
|
||||
}}
|
||||
label="Lookup Bind Password"
|
||||
value={ADLookupBindPassword}
|
||||
placeholder="admin"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userDNSearchBaseDN"
|
||||
name="ad_userDNSearchBaseDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADUserDNSearchBaseDN", e.target.value);
|
||||
}}
|
||||
label="User DN Search Base DN"
|
||||
value={ADUserDNSearchBaseDN}
|
||||
placeholder="dc=min,dc=io"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userDNSearchFilter"
|
||||
name="ad_userDNSearchFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("ADUserDNSearchFilter", e.target.value);
|
||||
}}
|
||||
label="User DN Search Filter"
|
||||
value={ADUserDNSearchFilter}
|
||||
placeholder="(uid=%s)"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
List of user DNs (Distinguished Names) to be Tenant Administrators
|
||||
{inputs}
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
</Fragment>
|
||||
@@ -495,22 +703,42 @@ const mapState = (state: AppState) => ({
|
||||
accessKeys: state.tenants.createTenant.fields.identityProvider.accessKeys,
|
||||
secretKeys: state.tenants.createTenant.fields.identityProvider.secretKeys,
|
||||
openIDURL: state.tenants.createTenant.fields.identityProvider.openIDURL,
|
||||
openIDConfigurationURL:
|
||||
state.tenants.createTenant.fields.identityProvider.openIDConfigurationURL,
|
||||
openIDClientID:
|
||||
state.tenants.createTenant.fields.identityProvider.openIDClientID,
|
||||
openIDSecretID:
|
||||
state.tenants.createTenant.fields.identityProvider.openIDSecretID,
|
||||
openIDCallbackURL:
|
||||
state.tenants.createTenant.fields.identityProvider.openIDCallbackURL,
|
||||
openIDClaimName:
|
||||
state.tenants.createTenant.fields.identityProvider.openIDClaimName,
|
||||
openIDScopes: state.tenants.createTenant.fields.identityProvider.openIDScopes,
|
||||
ADURL: state.tenants.createTenant.fields.identityProvider.ADURL,
|
||||
ADSkipTLS: state.tenants.createTenant.fields.identityProvider.ADSkipTLS,
|
||||
ADServerInsecure:
|
||||
state.tenants.createTenant.fields.identityProvider.ADServerInsecure,
|
||||
ADUserNameFilter:
|
||||
state.tenants.createTenant.fields.identityProvider.ADUserNameFilter,
|
||||
ADGroupBaseDN:
|
||||
state.tenants.createTenant.fields.identityProvider.ADGroupBaseDN,
|
||||
ADUserNameSearchFilter:
|
||||
state.tenants.createTenant.fields.identityProvider.ADUserNameSearchFilter,
|
||||
ADGroupSearchBaseDN:
|
||||
state.tenants.createTenant.fields.identityProvider.ADGroupSearchBaseDN,
|
||||
ADGroupSearchFilter:
|
||||
state.tenants.createTenant.fields.identityProvider.ADGroupSearchFilter,
|
||||
ADNameAttribute:
|
||||
state.tenants.createTenant.fields.identityProvider.ADNameAttribute,
|
||||
ADGroupNameAttribute:
|
||||
state.tenants.createTenant.fields.identityProvider.ADGroupNameAttribute,
|
||||
ADUserDNs: state.tenants.createTenant.fields.identityProvider.ADUserDNs,
|
||||
ADUserNameFormat:
|
||||
state.tenants.createTenant.fields.identityProvider.ADUserNameFormat,
|
||||
ADLookupBindDN:
|
||||
state.tenants.createTenant.fields.identityProvider.ADLookupBindDN,
|
||||
ADLookupBindPassword:
|
||||
state.tenants.createTenant.fields.identityProvider.ADLookupBindPassword,
|
||||
ADUserDNSearchBaseDN:
|
||||
state.tenants.createTenant.fields.identityProvider.ADUserDNSearchBaseDN,
|
||||
ADUserDNSearchFilter:
|
||||
state.tenants.createTenant.fields.identityProvider.ADUserDNSearchFilter,
|
||||
ADServerStartTLS:
|
||||
state.tenants.createTenant.fields.identityProvider.ADServerStartTLS,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
|
||||
@@ -90,6 +90,7 @@ const Security = ({
|
||||
addFileToConsoleCaCertificates,
|
||||
deleteConsoleCaCertificate,
|
||||
addConsoleCaCertificate,
|
||||
addConsoleCertificate,
|
||||
addKeyPair,
|
||||
addFileToKeyPair,
|
||||
deleteKeyPair,
|
||||
@@ -195,23 +196,6 @@ const Security = ({
|
||||
</Grid>
|
||||
{minioCertificates.map((keyPair: KeyPair) => (
|
||||
<Fragment key={keyPair.id}>
|
||||
<Grid item xs={5}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) => {
|
||||
addFileToKeyPair(
|
||||
keyPair.id,
|
||||
"key",
|
||||
fileName,
|
||||
encodedValue
|
||||
);
|
||||
}}
|
||||
accept=".key,.pem"
|
||||
id="tlsKey"
|
||||
name="tlsKey"
|
||||
label="Key"
|
||||
value={keyPair.key}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={5}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) => {
|
||||
@@ -229,6 +213,23 @@ const Security = ({
|
||||
value={keyPair.cert}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={5}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) => {
|
||||
addFileToKeyPair(
|
||||
keyPair.id,
|
||||
"key",
|
||||
fileName,
|
||||
encodedValue
|
||||
);
|
||||
}}
|
||||
accept=".key,.pem"
|
||||
id="tlsKey"
|
||||
name="tlsKey"
|
||||
label="Key"
|
||||
value={keyPair.key}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
@@ -310,18 +311,6 @@ const Security = ({
|
||||
Console Certificates
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) => {
|
||||
addConsoleCertificate("key", fileName, encodedValue);
|
||||
}}
|
||||
accept=".key,.pem"
|
||||
id="consoleKey"
|
||||
name="consoleKey"
|
||||
label="Key"
|
||||
value={consoleCertificate.key}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) => {
|
||||
@@ -334,6 +323,18 @@ const Security = ({
|
||||
value={consoleCertificate.cert}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) => {
|
||||
addConsoleCertificate("key", fileName, encodedValue);
|
||||
}}
|
||||
accept=".key,.pem"
|
||||
id="consoleKey"
|
||||
name="consoleKey"
|
||||
label="Key"
|
||||
value={consoleCertificate.key}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
|
||||
@@ -98,7 +98,7 @@ export interface ITenant {
|
||||
consoleTLS: boolean;
|
||||
consoleEnabled: boolean;
|
||||
idpAdEnabled: boolean;
|
||||
idpOicEnabled: boolean;
|
||||
idpOidcEnabled: boolean;
|
||||
health_status: string;
|
||||
status?: ITenantStatus;
|
||||
// computed
|
||||
|
||||
@@ -93,9 +93,9 @@ const mapState = (state: AppState) => ({
|
||||
false
|
||||
),
|
||||
adEnabled: get(state.tenants.tenantDetails.tenantInfo, "idpAdEnabled", false),
|
||||
oicEnabled: get(
|
||||
oidcEnabled: get(
|
||||
state.tenants.tenantDetails.tenantInfo,
|
||||
"idpOicEnabled",
|
||||
"idpOidcEnabled",
|
||||
false
|
||||
),
|
||||
});
|
||||
|
||||
@@ -503,9 +503,10 @@ const TenantSecurity = ({
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
{certificateInfo.domains &&
|
||||
certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
@@ -616,9 +617,10 @@ const TenantSecurity = ({
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
{certificateInfo.domains &&
|
||||
certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
@@ -731,9 +733,10 @@ const TenantSecurity = ({
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
{certificateInfo.domains &&
|
||||
certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
@@ -829,9 +832,10 @@ const TenantSecurity = ({
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
{certificateInfo.domains &&
|
||||
certificateInfo.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
|
||||
@@ -45,7 +45,7 @@ interface ITenantsSummary {
|
||||
consoleTLS: boolean;
|
||||
consoleEnabled: boolean;
|
||||
adEnabled: boolean;
|
||||
oicEnabled: boolean;
|
||||
oidcEnabled: boolean;
|
||||
loadingTenant: boolean;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ const TenantSummary = ({
|
||||
consoleTLS,
|
||||
consoleEnabled,
|
||||
adEnabled,
|
||||
oicEnabled,
|
||||
oidcEnabled,
|
||||
loadingTenant,
|
||||
}: ITenantsSummary) => {
|
||||
const [capacity, setCapacity] = useState<number>(0);
|
||||
@@ -421,36 +421,28 @@ const TenantSummary = ({
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
{adEnabled ||
|
||||
(!adEnabled && !oicEnabled && (
|
||||
<React.Fragment>
|
||||
<td className={classes.titleCol}>
|
||||
Active Directory:
|
||||
</td>
|
||||
<td>
|
||||
<Button
|
||||
color="primary"
|
||||
className={classes.anchorButton}
|
||||
>
|
||||
{adEnabled ? "Enabled" : "Disabled"}
|
||||
</Button>
|
||||
</td>
|
||||
</React.Fragment>
|
||||
))}
|
||||
{oicEnabled ||
|
||||
(!oicEnabled && !adEnabled && (
|
||||
<React.Fragment>
|
||||
<td className={classes.titleCol}>OpenID:</td>
|
||||
<td>
|
||||
<Button
|
||||
color="primary"
|
||||
className={classes.anchorButton}
|
||||
>
|
||||
{oicEnabled ? "Enabled" : "Disabled"}
|
||||
</Button>
|
||||
</td>
|
||||
</React.Fragment>
|
||||
))}
|
||||
<React.Fragment>
|
||||
<td className={classes.titleCol}>Active Directory:</td>
|
||||
<td>
|
||||
<Button
|
||||
color="primary"
|
||||
className={classes.anchorButton}
|
||||
>
|
||||
{adEnabled ? "Enabled" : "Disabled"}
|
||||
</Button>
|
||||
</td>
|
||||
</React.Fragment>
|
||||
<React.Fragment>
|
||||
<td className={classes.titleCol}>OpenID:</td>
|
||||
<td>
|
||||
<Button
|
||||
color="primary"
|
||||
className={classes.anchorButton}
|
||||
>
|
||||
{oidcEnabled ? "Enabled" : "Disabled"}
|
||||
</Button>
|
||||
</td>
|
||||
</React.Fragment>
|
||||
</tr>
|
||||
</Fragment>
|
||||
)}
|
||||
@@ -486,9 +478,9 @@ const mapState = (state: AppState) => ({
|
||||
false
|
||||
),
|
||||
adEnabled: get(state.tenants.tenantDetails.tenantInfo, "idpAdEnabled", false),
|
||||
oicEnabled: get(
|
||||
oidcEnabled: get(
|
||||
state.tenants.tenantDetails.tenantInfo,
|
||||
"idpOicEnabled",
|
||||
"idpOidcEnabled",
|
||||
false
|
||||
),
|
||||
});
|
||||
|
||||
@@ -88,15 +88,26 @@ const initialState: ITenantState = {
|
||||
accessKeys: [getRandomString(16)],
|
||||
secretKeys: [getRandomString(32)],
|
||||
openIDURL: "",
|
||||
openIDConfigurationURL: "",
|
||||
openIDClientID: "",
|
||||
openIDSecretID: "",
|
||||
openIDCallbackURL: "",
|
||||
openIDClaimName: "",
|
||||
openIDScopes: "",
|
||||
ADURL: "",
|
||||
ADSkipTLS: false,
|
||||
ADServerInsecure: false,
|
||||
ADUserNameFilter: "",
|
||||
ADGroupBaseDN: "",
|
||||
ADUserNameSearchFilter: "",
|
||||
ADGroupSearchBaseDN: "",
|
||||
ADGroupSearchFilter: "",
|
||||
ADNameAttribute: "",
|
||||
ADGroupNameAttribute: "",
|
||||
ADUserDNs: [""],
|
||||
ADUserNameFormat: "",
|
||||
ADLookupBindDN: "",
|
||||
ADLookupBindPassword: "",
|
||||
ADUserDNSearchBaseDN: "",
|
||||
ADUserDNSearchFilter: "",
|
||||
ADServerStartTLS: false,
|
||||
},
|
||||
security: {
|
||||
enableAutoCert: true,
|
||||
@@ -545,15 +556,26 @@ export function tenantsReducer(
|
||||
accessKeys: [getRandomString(16)],
|
||||
secretKeys: [getRandomString(32)],
|
||||
openIDURL: "",
|
||||
openIDConfigurationURL: "",
|
||||
openIDClientID: "",
|
||||
openIDSecretID: "",
|
||||
openIDCallbackURL: "",
|
||||
openIDClaimName: "",
|
||||
openIDScopes: "",
|
||||
ADURL: "",
|
||||
ADSkipTLS: false,
|
||||
ADServerInsecure: false,
|
||||
ADUserNameFilter: "",
|
||||
ADGroupBaseDN: "",
|
||||
ADUserNameSearchFilter: "",
|
||||
ADGroupSearchBaseDN: "",
|
||||
ADGroupSearchFilter: "",
|
||||
ADNameAttribute: "",
|
||||
ADGroupNameAttribute: "",
|
||||
ADUserDNs: [""],
|
||||
ADUserNameFormat: "",
|
||||
ADLookupBindDN: "",
|
||||
ADLookupBindPassword: "",
|
||||
ADUserDNSearchBaseDN: "",
|
||||
ADUserDNSearchFilter: "",
|
||||
ADServerStartTLS: false,
|
||||
},
|
||||
security: {
|
||||
enableAutoCert: true,
|
||||
|
||||
@@ -150,15 +150,26 @@ export interface IIdentityProviderFields {
|
||||
accessKeys: string[];
|
||||
secretKeys: string[];
|
||||
openIDURL: string;
|
||||
openIDConfigurationURL: string;
|
||||
openIDClientID: string;
|
||||
openIDSecretID: string;
|
||||
openIDCallbackURL: string;
|
||||
openIDClaimName: string;
|
||||
openIDScopes: string;
|
||||
ADURL: string;
|
||||
ADSkipTLS: boolean;
|
||||
ADServerInsecure: boolean;
|
||||
ADUserNameFilter: string;
|
||||
ADGroupBaseDN: string;
|
||||
ADUserNameSearchFilter: string;
|
||||
ADUserNameFormat: string;
|
||||
ADGroupSearchBaseDN: string;
|
||||
ADGroupSearchFilter: string;
|
||||
ADNameAttribute: string;
|
||||
ADGroupNameAttribute: string;
|
||||
ADUserDNs: string[];
|
||||
ADLookupBindDN: string;
|
||||
ADLookupBindPassword: string;
|
||||
ADUserDNSearchBaseDN: string;
|
||||
ADUserDNSearchFilter: string;
|
||||
ADServerStartTLS: boolean;
|
||||
}
|
||||
|
||||
export interface ISecurityFields {
|
||||
|
||||
@@ -347,10 +347,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
||||
</Typography>
|
||||
<Button
|
||||
component={"a"}
|
||||
href={loginStrategy.redirect.replace(
|
||||
"%5BHOSTNAME%5D",
|
||||
window.location.hostname
|
||||
)}
|
||||
href={loginStrategy.redirect}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
|
||||
@@ -3240,8 +3240,6 @@ definitions:
|
||||
type: object
|
||||
required:
|
||||
- url
|
||||
- username_format
|
||||
- user_search_filter
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
|
||||
@@ -2066,7 +2066,7 @@ definitions:
|
||||
type: boolean
|
||||
idpAdEnabled:
|
||||
type: boolean
|
||||
idpOicEnabled:
|
||||
idpOidcEnabled:
|
||||
type: boolean
|
||||
encryptionEnabled:
|
||||
type: boolean
|
||||
@@ -2285,16 +2285,26 @@ definitions:
|
||||
oidc:
|
||||
type: object
|
||||
required:
|
||||
- configuration_url
|
||||
- url
|
||||
- client_id
|
||||
- secret_id
|
||||
- claim_name
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
configuration_url:
|
||||
type: string
|
||||
client_id:
|
||||
type: string
|
||||
secret_id:
|
||||
type: string
|
||||
callback_url:
|
||||
type: string
|
||||
claim_name:
|
||||
type: string
|
||||
scopes:
|
||||
type: string
|
||||
keys:
|
||||
type: array
|
||||
items:
|
||||
@@ -2311,14 +2321,12 @@ definitions:
|
||||
type: object
|
||||
required:
|
||||
- url
|
||||
- username_format
|
||||
- user_search_filter
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
username_format:
|
||||
type: string
|
||||
user_search_filter:
|
||||
username_search_filter:
|
||||
type: string
|
||||
group_search_base_dn:
|
||||
type: string
|
||||
@@ -2330,6 +2338,20 @@ definitions:
|
||||
type: boolean
|
||||
server_insecure:
|
||||
type: boolean
|
||||
server_start_tls:
|
||||
type: boolean
|
||||
lookup_bind_dn:
|
||||
type: string
|
||||
lookup_bind_password:
|
||||
type: string
|
||||
user_dn_search_base_dn:
|
||||
type: string
|
||||
user_dn_search_filter:
|
||||
type: string
|
||||
user_dns:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
consoleConfiguration:
|
||||
allOf:
|
||||
|
||||
Reference in New Issue
Block a user