github.com/greenpau/go-authcrunch@v1.1.4/server.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 authcrunch
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  
    21  	"github.com/greenpau/go-authcrunch/pkg/authn"
    22  	"github.com/greenpau/go-authcrunch/pkg/authproxy"
    23  	"github.com/greenpau/go-authcrunch/pkg/authz"
    24  	"github.com/greenpau/go-authcrunch/pkg/errors"
    25  	"github.com/greenpau/go-authcrunch/pkg/idp"
    26  	"github.com/greenpau/go-authcrunch/pkg/ids"
    27  	"github.com/greenpau/go-authcrunch/pkg/registry"
    28  	"github.com/greenpau/go-authcrunch/pkg/sso"
    29  	"go.uber.org/zap"
    30  )
    31  
    32  type refMap struct {
    33  	portals           map[string]*authn.Portal
    34  	gatekeepers       map[string]*authz.Gatekeeper
    35  	identityStores    map[string]ids.IdentityStore
    36  	identityProviders map[string]idp.IdentityProvider
    37  	ssoProviders      map[string]sso.SingleSignOnProvider
    38  	userRegistries    map[string]registry.UserRegistry
    39  }
    40  
    41  // Server represents AAA SF server.
    42  type Server struct {
    43  	config            *Config
    44  	portals           []*authn.Portal
    45  	gatekeepers       []*authz.Gatekeeper
    46  	identityStores    []ids.IdentityStore
    47  	identityProviders []idp.IdentityProvider
    48  	ssoProviders      []sso.SingleSignOnProvider
    49  	userRegistries    []registry.UserRegistry
    50  	nameRefs          refMap
    51  	realmRefs         refMap
    52  	logger            *zap.Logger
    53  }
    54  
    55  func newRefMap() refMap {
    56  	return refMap{
    57  		portals:           make(map[string]*authn.Portal),
    58  		gatekeepers:       make(map[string]*authz.Gatekeeper),
    59  		identityStores:    make(map[string]ids.IdentityStore),
    60  		identityProviders: make(map[string]idp.IdentityProvider),
    61  		ssoProviders:      make(map[string]sso.SingleSignOnProvider),
    62  		userRegistries:    make(map[string]registry.UserRegistry),
    63  	}
    64  }
    65  
    66  // NewServer returns an instance of Server.
    67  func NewServer(config *Config, logger *zap.Logger) (*Server, error) {
    68  	var authenticators []authproxy.Authenticator
    69  	if err := config.Validate(); err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	srv := &Server{
    74  		config:    config,
    75  		logger:    logger,
    76  		nameRefs:  newRefMap(),
    77  		realmRefs: newRefMap(),
    78  	}
    79  
    80  	for _, cfg := range config.IdentityProviders {
    81  		provider, err := idp.NewIdentityProvider(cfg, logger)
    82  		if err != nil {
    83  			return nil, errors.ErrNewServer.WithArgs("failed initializing identity provider", err)
    84  		}
    85  		if _, exists := srv.nameRefs.identityProviders[provider.GetName()]; exists {
    86  			return nil, errors.ErrNewServer.WithArgs("duplicate identity provider name", provider.GetName())
    87  		}
    88  		if _, exists := srv.realmRefs.identityProviders[provider.GetRealm()]; exists {
    89  			return nil, errors.ErrNewServer.WithArgs("duplicate identity provider realm", provider.GetRealm())
    90  		}
    91  		if err := provider.Configure(); err != nil {
    92  			return nil, errors.ErrNewServer.WithArgs("failed configuring identity provider", err)
    93  		}
    94  		srv.nameRefs.identityProviders[provider.GetName()] = provider
    95  		srv.realmRefs.identityProviders[provider.GetRealm()] = provider
    96  		srv.identityProviders = append(srv.identityProviders, provider)
    97  	}
    98  
    99  	for _, cfg := range config.IdentityStores {
   100  		store, err := ids.NewIdentityStore(cfg, logger)
   101  		if err != nil {
   102  			return nil, errors.ErrNewServer.WithArgs("failed initializing identity store", err)
   103  		}
   104  		if _, exists := srv.nameRefs.identityStores[store.GetName()]; exists {
   105  			return nil, errors.ErrNewServer.WithArgs("duplicate identity store name", store.GetName())
   106  		}
   107  		if _, exists := srv.realmRefs.identityStores[store.GetRealm()]; exists {
   108  			return nil, errors.ErrNewServer.WithArgs("duplicate identity store realm", store.GetRealm())
   109  		}
   110  		if err := store.Configure(); err != nil {
   111  			return nil, errors.ErrNewServer.WithArgs("failed configuring identity store", err)
   112  		}
   113  		srv.nameRefs.identityStores[store.GetName()] = store
   114  		srv.realmRefs.identityStores[store.GetRealm()] = store
   115  		srv.identityStores = append(srv.identityStores, store)
   116  	}
   117  
   118  	for _, cfg := range config.SingleSignOnProviders {
   119  		provider, err := sso.NewSingleSignOnProvider(cfg, logger)
   120  		if err != nil {
   121  			return nil, errors.ErrNewServer.WithArgs("failed initializing sso provider", err)
   122  		}
   123  		if _, exists := srv.nameRefs.ssoProviders[provider.GetName()]; exists {
   124  			return nil, errors.ErrNewServer.WithArgs("duplicate sso provider name", provider.GetName())
   125  		}
   126  		if err := provider.Configure(); err != nil {
   127  			return nil, errors.ErrNewServer.WithArgs("failed configuring sso provider", err)
   128  		}
   129  		srv.nameRefs.ssoProviders[provider.GetName()] = provider
   130  		srv.ssoProviders = append(srv.ssoProviders, provider)
   131  	}
   132  
   133  	for _, cfg := range config.UserRegistries {
   134  		userRegistry, err := registry.NewUserRegistry(cfg, logger)
   135  		if err != nil {
   136  			return nil, errors.ErrNewServer.WithArgs("failed initializing user registry", err)
   137  		}
   138  		if _, exists := srv.nameRefs.userRegistries[userRegistry.GetName()]; exists {
   139  			return nil, errors.ErrNewServer.WithArgs("duplicate user registry name", userRegistry.GetName())
   140  		}
   141  		srv.nameRefs.userRegistries[userRegistry.GetName()] = userRegistry
   142  		srv.userRegistries = append(srv.userRegistries, userRegistry)
   143  	}
   144  
   145  	for _, cfg := range config.AuthenticationPortals {
   146  		params := authn.PortalParameters{
   147  			Config:                cfg,
   148  			Logger:                logger,
   149  			IdentityStores:        srv.identityStores,
   150  			IdentityProviders:     srv.identityProviders,
   151  			SingleSignOnProviders: srv.ssoProviders,
   152  		}
   153  
   154  		portal, err := authn.NewPortal(params)
   155  		if err != nil {
   156  			return nil, err
   157  		}
   158  
   159  		if _, exists := srv.nameRefs.portals[cfg.Name]; exists {
   160  			return nil, errors.ErrNewServer.WithArgs("duplicate authentication portal name", cfg.Name)
   161  		}
   162  
   163  		srv.nameRefs.portals[cfg.Name] = portal
   164  		srv.portals = append(srv.portals, portal)
   165  		authenticators = append(authenticators, portal)
   166  	}
   167  
   168  	for _, cfg := range config.AuthorizationPolicies {
   169  		gatekeeper, err := authz.NewGatekeeper(cfg, logger)
   170  		if err != nil {
   171  			return nil, err
   172  		}
   173  
   174  		if _, exists := srv.nameRefs.gatekeepers[cfg.Name]; exists {
   175  			return nil, errors.ErrNewServer.WithArgs("duplicate authorization policy name", cfg.Name)
   176  		}
   177  		srv.nameRefs.gatekeepers[cfg.Name] = gatekeeper
   178  		srv.gatekeepers = append(srv.gatekeepers, gatekeeper)
   179  	}
   180  
   181  	for _, gatekeeper := range srv.gatekeepers {
   182  		if err := gatekeeper.AddAuthenticators(authenticators); err != nil {
   183  			return nil, err
   184  		}
   185  	}
   186  
   187  	for _, portal := range srv.portals {
   188  		enabledIdentityStores := portal.GetIdentityStoreNames()
   189  		for _, userRegistry := range srv.userRegistries {
   190  			if _, exists := enabledIdentityStores[userRegistry.GetIdentityStoreName()]; !exists {
   191  				continue
   192  			}
   193  			if err := portal.AddUserRegistry(userRegistry); err != nil {
   194  				return nil, errors.ErrNewServer.WithArgs("failed adding registry to portal", err)
   195  			}
   196  		}
   197  	}
   198  
   199  	return srv, nil
   200  }
   201  
   202  // GetConfig returns Server configuration.
   203  func (srv *Server) GetConfig() map[string]interface{} {
   204  	var m map[string]interface{}
   205  	b, _ := json.Marshal(srv.config)
   206  	json.Unmarshal(b, &m)
   207  	return m
   208  }
   209  
   210  // GetPortalByName returns an instance of authn.Portal based on its name.
   211  func (srv *Server) GetPortalByName(s string) (*authn.Portal, error) {
   212  	if portal, exists := srv.nameRefs.portals[s]; exists {
   213  		return portal, nil
   214  	}
   215  	return nil, fmt.Errorf("portal not found")
   216  }
   217  
   218  // GetGatekeeperByName returns an instance of authz.Gatekeeper based on its name.
   219  func (srv *Server) GetGatekeeperByName(s string) (*authz.Gatekeeper, error) {
   220  	if gatekeeper, exists := srv.nameRefs.gatekeepers[s]; exists {
   221  		return gatekeeper, nil
   222  	}
   223  	return nil, fmt.Errorf("gatekeeper not found")
   224  }