Skip to content

Commit

Permalink
refactor auth proxy for basic and api key auth
Browse files Browse the repository at this point in the history
  • Loading branch information
greenpau committed Apr 2, 2022
1 parent d65b464 commit 0ae8adf
Show file tree
Hide file tree
Showing 28 changed files with 351 additions and 273 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ clean:
qtest:
@echo "Perform quick tests ..."
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out -run TestNewConfig ./*.go
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out -run TestNewServer ./*.go
@time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out -run TestNewServer ./*.go
@#time richgo test -v -coverprofile=.coverage/coverage.out internal/tag/*.go
@### time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out -run TestAuthorize ./pkg/authz/validator/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out -run TestAddProviders ./pkg/messaging/...
@time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/messaging/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/messaging/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/credentials/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/errors/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/requests/...
Expand Down Expand Up @@ -115,7 +115,7 @@ qtest:
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out -run TestNewAclRuleCondition ./pkg/acl/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out -run TestMatchAclRuleCondition ./pkg/acl/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/user/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/shared/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/authproxy/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/identity/...
@#time richgo test $(VERBOSE) $(TEST) -coverprofile=.coverage/coverage.out ./pkg/authn/backends/...
@go tool cover -html=.coverage/coverage.out -o .coverage/coverage.html
Expand Down
107 changes: 101 additions & 6 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ import (
"github.com/greenpau/go-authcrunch/pkg/authn"
"github.com/greenpau/go-authcrunch/pkg/authz"
"github.com/greenpau/go-authcrunch/pkg/credentials"
"github.com/greenpau/go-authcrunch/pkg/errors"
"github.com/greenpau/go-authcrunch/pkg/idp"
"github.com/greenpau/go-authcrunch/pkg/ids"
"github.com/greenpau/go-authcrunch/pkg/messaging"
)

// Config is a configuration of Server.
type Config struct {
Credentials *credentials.Config `json:"credentials,omitempty" xml:"credentials,omitempty" yaml:"credentials,omitempty"`
AuthenticationPortals []*authn.PortalConfig `json:"authentication_portals,omitempty" xml:"authentication_portals,omitempty" yaml:"authentication_portals,omitempty"`
AuthorizationPolicies []*authz.PolicyConfig `json:"authorization_policies,omitempty" xml:"authorization_policies,omitempty" yaml:"authorization_policies,omitempty"`
Messaging *messaging.Config `json:"messaging,omitempty" xml:"messaging,omitempty" yaml:"messaging,omitempty"`
IdentityStores []*ids.IdentityStoreConfig `json:"identity_stores,omitempty" xml:"identity_stores,omitempty" yaml:"identity_stores,omitempty"`
IdentityProviders []*idp.IdentityProviderConfig `json:"identity_providers,omitempty" xml:"identity_providers,omitempty" yaml:"identity_providers,omitempty"`
Credentials *credentials.Config `json:"credentials,omitempty" xml:"credentials,omitempty" yaml:"credentials,omitempty"`
AuthenticationPortals []*authn.PortalConfig `json:"authentication_portals,omitempty" xml:"authentication_portals,omitempty" yaml:"authentication_portals,omitempty"`
AuthorizationPolicies []*authz.PolicyConfig `json:"authorization_policies,omitempty" xml:"authorization_policies,omitempty" yaml:"authorization_policies,omitempty"`
Messaging *messaging.Config `json:"messaging,omitempty" xml:"messaging,omitempty" yaml:"messaging,omitempty"`
IdentityStores []*ids.IdentityStoreConfig `json:"identity_stores,omitempty" xml:"identity_stores,omitempty" yaml:"identity_stores,omitempty"`
IdentityProviders []*idp.IdentityProviderConfig `json:"identity_providers,omitempty" xml:"identity_providers,omitempty" yaml:"identity_providers,omitempty"`
disabledIdentityStores map[string]interface{}
disabledIdentityProviders map[string]interface{}
}

// NewConfig returns an instance of Config.
Expand Down Expand Up @@ -106,10 +109,37 @@ func (cfg *Config) Validate() error {
return err
}

// If there are no excplicitly specified identity stores and providers in a portal, add all of them.
if len(portalCfg.IdentityStores) == 0 && len(portalCfg.IdentityProviders) == 0 {
for _, entry := range cfg.IdentityStores {
portalCfg.IdentityStores = append(portalCfg.IdentityStores, entry.Name)
}
for _, entry := range cfg.IdentityProviders {
portalCfg.IdentityProviders = append(portalCfg.IdentityProviders, entry.Name)
}
}

if len(portalCfg.IdentityStores) == 0 && len(portalCfg.IdentityProviders) == 0 {
return errors.ErrPortalConfigBackendsNotFound
}

// Filter out disabled identity store names.
portalCfg.IdentityStores = cfg.filterDisabledIdentityStores(portalCfg.IdentityStores)

// Vealidate that there are no duplicate or overlapping identity store and providers.
authByName := make(map[string]string)
authByRealm := make(map[string]string)

for _, storeName := range portalCfg.IdentityStores {
if v, exists := authByName[storeName]; exists {
return fmt.Errorf(
"identity store %q has the same name as %s",
storeName, v,
)
}

authByName[storeName] = "another identity store"

var storeConfig *ids.IdentityStoreConfig
for _, entry := range cfg.IdentityStores {
storeConfig = entry
Expand All @@ -132,10 +162,24 @@ func (cfg *Config) Validate() error {
)
}
authByRealm[realmName] = storeName
authByName[storeName] = "identity store in " + realmName + " realm"
}

}

// Filter out disabled identity store names.
portalCfg.IdentityProviders = cfg.filterDisabledIdentityProviders(portalCfg.IdentityProviders)

for _, providerName := range portalCfg.IdentityProviders {
if v, exists := authByName[providerName]; exists {
return fmt.Errorf(
"identity provider %q has the same name as %s",
providerName, v,
)
}

authByName[providerName] = "another identity provider"

var providerConfig *idp.IdentityProviderConfig
for _, entry := range cfg.IdentityProviders {
providerConfig = entry
Expand All @@ -158,9 +202,60 @@ func (cfg *Config) Validate() error {
)
}
authByRealm[realmName] = providerName
authByName[providerName] = "identity provider in " + realmName + " realm"
}
}
}

return nil
}

// AddDisabledIdentityStore adds the names of disabled identity stores.
func (cfg *Config) AddDisabledIdentityStore(s string) {
if cfg.disabledIdentityStores == nil {
cfg.disabledIdentityStores = map[string]interface{}{
s: true,
}
return
}
cfg.disabledIdentityStores[s] = true
}

// AddDisabledIdentityProvider adds the names of disabled identity providers.
func (cfg *Config) AddDisabledIdentityProvider(s string) {
if cfg.disabledIdentityProviders == nil {
cfg.disabledIdentityProviders = map[string]interface{}{
s: true,
}
return
}
cfg.disabledIdentityProviders[s] = true
}

func (cfg *Config) filterDisabledIdentityStores(arr []string) []string {
var output []string
if len(arr) == 0 || cfg.disabledIdentityStores == nil {
return arr
}
for _, s := range arr {
if _, exists := cfg.disabledIdentityStores[s]; exists {
continue
}
output = append(output, s)
}
return output
}

func (cfg *Config) filterDisabledIdentityProviders(arr []string) []string {
var output []string
if len(arr) == 0 || cfg.disabledIdentityProviders == nil {
return arr
}
for _, s := range arr {
if _, exists := cfg.disabledIdentityProviders[s]; exists {
continue
}
output = append(output, s)
}
return output
}
2 changes: 1 addition & 1 deletion config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func TestNewConfig(t *testing.T) {
},
},
shouldErr: true,
errPhase: "AddAuthenticationPortal",
errPhase: "Validate",
err: errors.ErrPortalConfigBackendsNotFound,
},
{
Expand Down
46 changes: 28 additions & 18 deletions internal/tag/tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/greenpau/go-authcrunch/pkg/authn/registration"
"github.com/greenpau/go-authcrunch/pkg/authn/transformer"
"github.com/greenpau/go-authcrunch/pkg/authn/ui"
"github.com/greenpau/go-authcrunch/pkg/authproxy"
"github.com/greenpau/go-authcrunch/pkg/authz"
"github.com/greenpau/go-authcrunch/pkg/authz/bypass"
"github.com/greenpau/go-authcrunch/pkg/authz/cache"
Expand All @@ -36,7 +37,7 @@ import (
"github.com/greenpau/go-authcrunch/pkg/credentials"
"github.com/greenpau/go-authcrunch/pkg/identity"
"github.com/greenpau/go-authcrunch/pkg/identity/qr"
idpp "github.com/greenpau/go-authcrunch/pkg/idp"
"github.com/greenpau/go-authcrunch/pkg/idp"
"github.com/greenpau/go-authcrunch/pkg/idp/oauth"
"github.com/greenpau/go-authcrunch/pkg/idp/saml"
"github.com/greenpau/go-authcrunch/pkg/ids"
Expand All @@ -45,7 +46,6 @@ import (
"github.com/greenpau/go-authcrunch/pkg/kms"
"github.com/greenpau/go-authcrunch/pkg/messaging"
"github.com/greenpau/go-authcrunch/pkg/requests"
"github.com/greenpau/go-authcrunch/pkg/shared/idp"
"github.com/greenpau/go-authcrunch/pkg/user"
"github.com/greenpau/go-authcrunch/pkg/util"
"github.com/greenpau/go-authcrunch/pkg/util/cfg"
Expand All @@ -65,14 +65,29 @@ func TestTagCompliance(t *testing.T) {
shouldErr bool
err error
}{
{
name: "test messaging.FileProvider struct",
entry: &messaging.FileProvider{},
opts: &Options{},
},
{
name: "test messaging.FileProviderSendInput struct",
entry: &messaging.FileProviderSendInput{},
opts: &Options{},
},
{
name: "test messaging.EmailProviderSendInput struct",
entry: &messaging.EmailProviderSendInput{},
opts: &Options{},
},
{
name: "test authn.PortalParameters struct",
entry: &authn.PortalParameters{},
opts: &Options{},
},
{
name: "test idp.IdentityProviderConfig struct",
entry: &idpp.IdentityProviderConfig{},
entry: &idp.IdentityProviderConfig{},
opts: &Options{},
},
{
Expand Down Expand Up @@ -385,8 +400,8 @@ func TestTagCompliance(t *testing.T) {
opts: &Options{},
},
{
name: "test idp.BasicAuthConfig struct",
entry: &idp.BasicAuthConfig{},
name: "test authproxy.BasicAuthConfig struct",
entry: &authproxy.BasicAuthConfig{},
opts: &Options{},
},
{
Expand Down Expand Up @@ -537,8 +552,8 @@ func TestTagCompliance(t *testing.T) {
opts: &Options{},
},
{
name: "test idp.IdentityProviderConfig struct",
entry: &idp.IdentityProviderConfig{},
name: "test authproxy.Config struct",
entry: &authproxy.Config{},
opts: &Options{},
},
{
Expand Down Expand Up @@ -595,8 +610,8 @@ func TestTagCompliance(t *testing.T) {
opts: &Options{},
},
{
name: "test idp.ProviderResponse struct",
entry: &idp.ProviderResponse{},
name: "test authproxy.Response struct",
entry: &authproxy.Response{},
opts: &Options{},
},
{
Expand All @@ -617,8 +632,8 @@ func TestTagCompliance(t *testing.T) {
},
},
{
name: "test idp.ProviderRequest struct",
entry: &idp.ProviderRequest{},
name: "test authproxy.Request struct",
entry: &authproxy.Request{},
opts: &Options{},
},
{
Expand All @@ -631,11 +646,6 @@ func TestTagCompliance(t *testing.T) {
entry: &options.TokenValidatorOptions{},
opts: &Options{},
},
{
name: "test idp.ProviderCatalog struct",
entry: &idp.ProviderCatalog{},
opts: &Options{},
},
{
name: "test ldap.Backend struct",
entry: &ldap.IdentityStore{},
Expand Down Expand Up @@ -677,8 +687,8 @@ func TestTagCompliance(t *testing.T) {
},
},
{
name: "test idp.APIKeyAuthConfig struct",
entry: &idp.APIKeyAuthConfig{},
name: "test authproxy.APIKeyAuthConfig struct",
entry: &authproxy.APIKeyAuthConfig{},
opts: &Options{},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ import (
"context"
"encoding/base64"
"github.com/greenpau/go-authcrunch/pkg/authn/enums/operator"
"github.com/greenpau/go-authcrunch/pkg/authproxy"
"github.com/greenpau/go-authcrunch/pkg/errors"
"github.com/greenpau/go-authcrunch/pkg/requests"
"github.com/greenpau/go-authcrunch/pkg/shared/idp"
"github.com/greenpau/go-authcrunch/pkg/user"
"go.uber.org/zap"
"strings"
"time"
)

// BasicAuth performs API key authentication.
func (p *Portal) BasicAuth(r *idp.ProviderRequest) error {
func (p *Portal) BasicAuth(r *authproxy.Request) error {
if r.Realm == "" {
r.Realm = "local"
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/authn/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@ func (cfg *PortalConfig) Validate() error {
if cfg.Name == "" {
return errors.ErrPortalConfigNameNotFound
}
if len(cfg.IdentityStores) == 0 && len(cfg.IdentityProviders) == 0 {
return errors.ErrPortalConfigBackendsNotFound
}

// if len(cfg.IdentityStores) == 0 && len(cfg.IdentityProviders) == 0 {
// return errors.ErrPortalConfigBackendsNotFound
// }

if err := cfg.parseRawCryptoConfigs(); err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions pkg/authn/idp_apikey_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ package authn
import (
"context"
"github.com/greenpau/go-authcrunch/pkg/authn/enums/operator"
"github.com/greenpau/go-authcrunch/pkg/authproxy"
"github.com/greenpau/go-authcrunch/pkg/errors"
"github.com/greenpau/go-authcrunch/pkg/requests"
"github.com/greenpau/go-authcrunch/pkg/shared/idp"
"github.com/greenpau/go-authcrunch/pkg/user"
"go.uber.org/zap"
"time"
)

// APIKeyAuth performs API key authentication.
func (p *Portal) APIKeyAuth(r *idp.ProviderRequest) error {
func (p *Portal) APIKeyAuth(r *authproxy.Request) error {
if r.Realm == "" {
r.Realm = "local"
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/authn/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,14 @@ func (p *Portal) notify(data map[string]string) error {
r := strings.NewReplacer("\r", "", "\n", " ")
qpEmailSubj = strings.TrimSpace(r.Replace(qpEmailSubj))

if err := provider.Send(providerCred, rcpts, qpEmailSubj, qpEmailBody); err != nil {
sendInput := &messaging.EmailProviderSendInput{
Subject: qpEmailSubj,
Body: qpEmailBody,
Recipients: rcpts,
Credentials: providerCred,
}

if err := provider.Send(sendInput); err != nil {
return errors.ErrNotifyRequestEmail.WithArgs(providerName, err)
}
default:
Expand Down
9 changes: 6 additions & 3 deletions pkg/authn/portal.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ func NewPortal(params PortalParameters) (*Portal, error) {
}

if len(p.identityStores) < 1 && len(p.identityProviders) < 1 {
return nil, errors.ErrNewPortal.WithArgs(
fmt.Errorf("no identity providers or stores found"),
)
return nil, errors.ErrNewPortal.WithArgs(errors.ErrPortalConfigBackendsNotFound)
}

if err := p.configure(); err != nil {
Expand All @@ -142,6 +140,11 @@ func NewPortal(params PortalParameters) (*Portal, error) {
return p, nil
}

// GetName returns the configuration name of the Portal.
func (p *Portal) GetName() string {
return p.config.Name
}

func (p *Portal) configure() error {
if err := p.configureEssentials(); err != nil {
return err
Expand Down
Loading

0 comments on commit 0ae8adf

Please sign in to comment.