github.com/greenpau/go-authcrunch@v1.0.50/pkg/authn/config.go (about)

     1  // Copyright 2022 Paul Greenberg greenpau@outlook.com
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package authn
    16  
    17  import (
    18  	"strings"
    19  
    20  	"github.com/greenpau/go-authcrunch/pkg/acl"
    21  	"github.com/greenpau/go-authcrunch/pkg/authn/cookie"
    22  	"github.com/greenpau/go-authcrunch/pkg/authn/transformer"
    23  	"github.com/greenpau/go-authcrunch/pkg/authn/ui"
    24  	"github.com/greenpau/go-authcrunch/pkg/authz/options"
    25  	"github.com/greenpau/go-authcrunch/pkg/errors"
    26  	"github.com/greenpau/go-authcrunch/pkg/kms"
    27  	"github.com/greenpau/go-authcrunch/pkg/redirects"
    28  	cfgutil "github.com/greenpau/go-authcrunch/pkg/util/cfg"
    29  )
    30  
    31  // PortalConfig represents Portal configuration.
    32  type PortalConfig struct {
    33  	Name string `json:"name,omitempty" xml:"name,omitempty" yaml:"name,omitempty"`
    34  	// UI holds the configuration for the user interface.
    35  	UI *ui.Parameters `json:"ui,omitempty" xml:"ui,omitempty" yaml:"ui,omitempty"`
    36  	// UserTransformerConfig holds the configuration for the user transformer.
    37  	UserTransformerConfigs []*transformer.Config `json:"user_transformer_configs,omitempty" xml:"user_transformer_configs,omitempty" yaml:"user_transformer_configs,omitempty"`
    38  	// CookieConfig holds the configuration for the cookies issues by Authenticator.
    39  	CookieConfig *cookie.Config `json:"cookie_config,omitempty" xml:"cookie_config,omitempty" yaml:"cookie_config,omitempty"`
    40  	// The names of identity stores.
    41  	IdentityStores []string `json:"identity_stores,omitempty" xml:"identity_stores,omitempty" yaml:"identity_stores,omitempty"`
    42  	// The names of identity providers.
    43  	IdentityProviders []string `json:"identity_providers,omitempty" xml:"identity_providers,omitempty" yaml:"identity_providers,omitempty"`
    44  	// The names of SSO providers.
    45  	SingleSignOnProviders []string `json:"sso_providers,omitempty" xml:"sso_providers,omitempty" yaml:"sso_providers,omitempty"`
    46  	// The names of user registries.
    47  	UserRegistries []string `json:"user_registries,omitempty" xml:"user_registries,omitempty" yaml:"user_registries,omitempty"`
    48  	// AccessListConfigs hold the configurations for the ACL of the token validator.
    49  	AccessListConfigs []*acl.RuleConfiguration `json:"access_list_configs,omitempty" xml:"access_list_configs,omitempty" yaml:"access_list_configs,omitempty"`
    50  	// TokenValidatorOptions holds the configuration for the token validator.
    51  	TokenValidatorOptions *options.TokenValidatorOptions `json:"token_validator_options,omitempty" xml:"token_validator_options,omitempty" yaml:"token_validator_options,omitempty"`
    52  	// CryptoKeyConfigs hold the configurations for the keys used to issue and validate user tokens.
    53  	CryptoKeyConfigs []*kms.CryptoKeyConfig `json:"crypto_key_configs,omitempty" xml:"crypto_key_configs,omitempty" yaml:"crypto_key_configs,omitempty"`
    54  	// CryptoKeyStoreConfig hold the default configuration for the keys, e.g. token name and lifetime.
    55  	CryptoKeyStoreConfig map[string]interface{} `json:"crypto_key_store_config,omitempty" xml:"crypto_key_store_config,omitempty" yaml:"crypto_key_store_config,omitempty"`
    56  	// TokenGrantorOptions holds the configuration for the tokens issues by Authenticator.
    57  	TokenGrantorOptions *options.TokenGrantorOptions `json:"token_grantor_options,omitempty" xml:"token_grantor_options,omitempty" yaml:"token_grantor_options,omitempty"`
    58  	// TrustedLogoutRedirectURIConfigs holds the configuration of trusted logout redirect URIs.
    59  	TrustedLogoutRedirectURIConfigs []*redirects.RedirectURIMatchConfig `json:"trusted_logout_redirect_uri_configs,omitempty" xml:"trusted_logout_redirect_uri_configs,omitempty" yaml:"trusted_logout_redirect_uri_configs,omitempty"`
    60  
    61  	// API holds the configuration for API endpoints.
    62  	API *APIConfig `json:"api,omitempty" xml:"api,omitempty" yaml:"api,omitempty"`
    63  
    64  	// Holds raw crypto configuration.
    65  	cryptoRawConfigs []string
    66  
    67  	// Indicated that the config was successfully validated.
    68  	validated bool
    69  }
    70  
    71  // AddRawCryptoConfigs adds raw crypto configs.
    72  func (cfg *PortalConfig) AddRawCryptoConfigs(s string) {
    73  	cfg.cryptoRawConfigs = append(cfg.cryptoRawConfigs, s)
    74  }
    75  
    76  // parseRawCryptoConfigs parses raw crypto configs into CryptoKeyConfigs
    77  // and CryptoKeyStoreConfig.
    78  func (cfg *PortalConfig) parseRawCryptoConfigs() error {
    79  	var cryptoKeyConfig, cryptoKeyStoreConfig []string
    80  	var cryptoKeyConfigFound, cryptoKeyStoreConfigFound bool
    81  	for _, encodedArgs := range cfg.cryptoRawConfigs {
    82  		args, err := cfgutil.DecodeArgs(encodedArgs)
    83  		if err != nil {
    84  			return errors.ErrConfigDirectiveFail.WithArgs("crypto", encodedArgs, err)
    85  		}
    86  		if len(args) < 3 {
    87  			return errors.ErrConfigDirectiveShort.WithArgs("crypto", args)
    88  		}
    89  		cryptoKeyConfig = append(cryptoKeyConfig, encodedArgs)
    90  		switch args[0] {
    91  		case "key":
    92  			cryptoKeyConfigFound = true
    93  		case "default":
    94  			cryptoKeyStoreConfig = append(cryptoKeyStoreConfig, encodedArgs)
    95  			cryptoKeyStoreConfigFound = true
    96  		default:
    97  			return errors.ErrConfigDirectiveValueUnsupported.WithArgs("crypto", args)
    98  		}
    99  	}
   100  
   101  	if cryptoKeyConfigFound {
   102  		configs, err := kms.ParseCryptoKeyConfigs(strings.Join(cryptoKeyConfig, "\n"))
   103  		if err != nil {
   104  			return errors.ErrConfigDirectiveFail.WithArgs("crypto.key", cryptoKeyConfig, err)
   105  		}
   106  		cfg.CryptoKeyConfigs = configs
   107  	}
   108  
   109  	if cryptoKeyStoreConfigFound {
   110  		configs, err := kms.ParseCryptoKeyStoreConfig(strings.Join(cryptoKeyStoreConfig, "\n"))
   111  		if err != nil {
   112  			return errors.ErrConfigDirectiveFail.WithArgs("crypto.keystore", cryptoKeyStoreConfig, err)
   113  		}
   114  		cfg.CryptoKeyStoreConfig = configs
   115  	}
   116  	return nil
   117  }
   118  
   119  // Validate validates PortalConfig.
   120  func (cfg *PortalConfig) Validate() error {
   121  	if cfg.validated {
   122  		return nil
   123  	}
   124  	if cfg.Name == "" {
   125  		return errors.ErrPortalConfigNameNotFound
   126  	}
   127  
   128  	// if len(cfg.IdentityStores) == 0 && len(cfg.IdentityProviders) == 0 {
   129  	//	  return errors.ErrPortalConfigBackendsNotFound
   130  	// }
   131  
   132  	if err := cfg.parseRawCryptoConfigs(); err != nil {
   133  		return err
   134  	}
   135  
   136  	for _, redirURIConfig := range cfg.TrustedLogoutRedirectURIConfigs {
   137  		if err := redirURIConfig.Validate(); err != nil {
   138  			return err
   139  		}
   140  	}
   141  
   142  	// Inialize user interface settings
   143  	if cfg.UI == nil {
   144  		cfg.UI = &ui.Parameters{}
   145  	}
   146  
   147  	if cfg.UI.Templates == nil {
   148  		cfg.UI.Templates = make(map[string]string)
   149  	}
   150  
   151  	cfg.validated = true
   152  	return nil
   153  }