github.com/greenpau/go-authcrunch@v1.0.50/server_test.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  	"fmt"
    19  	"github.com/google/go-cmp/cmp"
    20  	"github.com/greenpau/go-authcrunch/internal/tests"
    21  	"github.com/greenpau/go-authcrunch/internal/testutils"
    22  	"github.com/greenpau/go-authcrunch/pkg/acl"
    23  	"github.com/greenpau/go-authcrunch/pkg/authn"
    24  	// "github.com/greenpau/go-authcrunch/pkg/authn/registration"
    25  	"github.com/greenpau/go-authcrunch/pkg/authz"
    26  	"github.com/greenpau/go-authcrunch/pkg/credentials"
    27  	// "github.com/greenpau/go-authcrunch/pkg/errors"
    28  	"github.com/greenpau/go-authcrunch/pkg/idp"
    29  	"github.com/greenpau/go-authcrunch/pkg/ids"
    30  	"github.com/greenpau/go-authcrunch/pkg/messaging"
    31  	logutil "github.com/greenpau/go-authcrunch/pkg/util/log"
    32  	"go.uber.org/zap"
    33  	"testing"
    34  )
    35  
    36  func TestNewServer(t *testing.T) {
    37  	db, err := testutils.CreateTestDatabase("TestNewPortal")
    38  	if err != nil {
    39  		t.Fatalf("failed to create temp dir: %v", err)
    40  	}
    41  	dbPath := db.GetPath()
    42  	// t.Logf("%v", dbPath)
    43  
    44  	var testcases = []struct {
    45  		name   string
    46  		logger *zap.Logger
    47  
    48  		identityStores    []*ids.IdentityStoreConfig
    49  		identityProviders []*idp.IdentityProviderConfig
    50  		credentials       []credentials.Credential
    51  		messaging         []messaging.Provider
    52  		portals           []*authn.PortalConfig
    53  		policies          []*authz.PolicyConfig
    54  
    55  		want string
    56  
    57  		shouldErr bool
    58  		err       error
    59  	}{
    60  		{
    61  			name:      "test server without portals and gatekeepers",
    62  			logger:    logutil.NewLogger(),
    63  			shouldErr: true,
    64  			err:       fmt.Errorf("no portals and gatekeepers found"),
    65  		},
    66  		{
    67  			name:   "test server with valid local auth config",
    68  			logger: logutil.NewLogger(),
    69  			credentials: []credentials.Credential{
    70  				&credentials.Generic{
    71  					Name:     "foobar",
    72  					Username: "foo",
    73  					Password: "bar",
    74  				},
    75  			},
    76  			messaging: []messaging.Provider{
    77  				&messaging.EmailProvider{
    78  					Name:        "default",
    79  					Address:     "localhost",
    80  					Protocol:    "smtp",
    81  					Credentials: "foobar",
    82  					SenderEmail: "root@localhost",
    83  				},
    84  			},
    85  			identityStores: []*ids.IdentityStoreConfig{
    86  				{
    87  					Name: "localdb",
    88  					Kind: "local",
    89  					Params: map[string]interface{}{
    90  						"realm": "local",
    91  						"path":  dbPath,
    92  					},
    93  				},
    94  			},
    95  			identityProviders: []*idp.IdentityProviderConfig{
    96  				{
    97  					Name: "contoso",
    98  					Kind: "oauth",
    99  					Params: map[string]interface{}{
   100  						"base_auth_url":         "https://localhost/oauth",
   101  						"token_url":             "https://localhost/oauth/access_token",
   102  						"authorization_url":     "https://localhost/oauth/authorize",
   103  						"client_id":             "foo",
   104  						"client_secret":         "bar",
   105  						"driver":                "generic",
   106  						"realm":                 "contoso",
   107  						"required_token_fields": []interface{}{"access_token"},
   108  						"response_type":         []interface{}{"code"},
   109  
   110  						"tls_insecure_skip_verify":  true,
   111  						"key_verification_disabled": true,
   112  						"jwks_keys": map[string]string{
   113  							"87329db33bf": "testdata/oauth/87329db33bf_pub.pem",
   114  						},
   115  					},
   116  				},
   117  			},
   118  			portals: []*authn.PortalConfig{
   119  				{
   120  					Name: "myportal",
   121  					IdentityStores: []string{
   122  						"localdb",
   123  					},
   124  				},
   125  			},
   126  			policies: []*authz.PolicyConfig{
   127  				{
   128  					Name: "mygatekeeper",
   129  					AccessListRules: []*acl.RuleConfiguration{
   130  						{
   131  							Conditions: []string{
   132  								"match roles authp/admin authp/user",
   133  							},
   134  							Action: "allow stop",
   135  						},
   136  					},
   137  					AuthRedirectDisabled: true,
   138  				},
   139  			},
   140  			want: `{
   141                "config": {
   142                  "authentication_portals": [
   143                    {
   144                      "access_list_configs": [
   145                        {
   146                          "action": "allow stop",
   147                          "conditions": [
   148                            "match roles authp/admin authp/user authp/guest superuser superadmin"
   149                          ]
   150                        }
   151                      ],
   152                      "identity_stores": [
   153                        "localdb"
   154                      ],
   155                      "name": "myportal",
   156                      "token_validator_options": {
   157                        "validate_bearer_header": true
   158                      },
   159                      "ui": {
   160                        "theme": "basic"
   161                      }
   162                    }
   163                  ],
   164                  "authorization_policies": [
   165                    {
   166                      "access_list_rules": [
   167                        {
   168                          "action": "allow stop",
   169                          "conditions": [
   170                            "match roles authp/admin authp/user"
   171                          ]
   172                        }
   173                      ],
   174                      "auth_redirect_query_param": "redirect_url",
   175                      "auth_redirect_status_code": 302,
   176                      "auth_url_path": "/auth",
   177                      "disable_auth_redirect": true,
   178                      "name": "mygatekeeper"
   179                    }
   180                  ],
   181                  "credentials": {
   182                    "generic": [
   183                      {
   184                        "name": "foobar",
   185                        "password": "bar",
   186                        "username": "foo"
   187                      }
   188                    ]
   189                  },
   190                  "identity_providers": [
   191                    {
   192                      "kind": "oauth",
   193                      "name": "contoso",
   194                      "params": {
   195                        "authorization_url": "https://localhost/oauth/authorize",
   196                        "base_auth_url": "https://localhost/oauth",
   197                        "client_id": "foo",
   198                        "client_secret": "bar",
   199                        "driver": "generic",
   200                        "jwks_keys": {
   201                          "87329db33bf": "testdata/oauth/87329db33bf_pub.pem"
   202                        },
   203                        "key_verification_disabled": true,
   204                        "realm": "contoso",
   205                        "required_token_fields": [
   206                          "access_token"
   207                        ],
   208                        "response_type": [
   209                          "code"
   210                        ],
   211                        "tls_insecure_skip_verify": true,
   212                        "token_url": "https://localhost/oauth/access_token"
   213                      }
   214                    }
   215                  ],
   216                  "identity_stores": [
   217                    {
   218                      "kind": "local",
   219                      "name": "localdb",
   220                      "params": {
   221                        "path": "` + dbPath + `",
   222                        "realm": "local"
   223                      }
   224                    }
   225                  ],
   226                  "messaging": {
   227                    "email_providers": [
   228                      {
   229                        "address": "localhost",
   230                        "credentials": "foobar",
   231                        "name": "default",
   232                        "protocol": "smtp",
   233                        "sender_email": "root@localhost"
   234                      }
   235                    ]
   236                  }
   237                }
   238  		    }`,
   239  		},
   240  	}
   241  
   242  	for _, tc := range testcases {
   243  		t.Run(tc.name, func(t *testing.T) {
   244  
   245  			cfg := NewConfig()
   246  
   247  			for _, item := range tc.credentials {
   248  				if err := cfg.AddCredential(item); err != nil {
   249  					t.Fatal(err)
   250  				}
   251  			}
   252  
   253  			for _, item := range tc.messaging {
   254  				if err := cfg.AddMessagingProvider(item); err != nil {
   255  					t.Fatal(err)
   256  				}
   257  			}
   258  
   259  			for _, item := range tc.identityStores {
   260  				if err := cfg.AddIdentityStore(item.Name, item.Kind, item.Params); err != nil {
   261  					t.Fatal(err)
   262  				}
   263  			}
   264  
   265  			for _, item := range tc.identityProviders {
   266  				if err := cfg.AddIdentityProvider(item.Name, item.Kind, item.Params); err != nil {
   267  					t.Fatal(err)
   268  				}
   269  			}
   270  
   271  			for _, item := range tc.portals {
   272  				if err := cfg.AddAuthenticationPortal(item); err != nil {
   273  					t.Fatal(err)
   274  				}
   275  			}
   276  
   277  			for _, item := range tc.policies {
   278  				if err := cfg.AddAuthorizationPolicy(item); err != nil {
   279  					t.Fatal(err)
   280  				}
   281  			}
   282  
   283  			server, err := NewServer(cfg, tc.logger)
   284  			if err != nil {
   285  				if !tc.shouldErr {
   286  					t.Fatalf("expected success, got: %v", err)
   287  				}
   288  				if diff := cmp.Diff(err.Error(), tc.err.Error()); diff != "" {
   289  					t.Fatalf("unexpected error: %v, want: %v", err, tc.err)
   290  				}
   291  				return
   292  			}
   293  			if tc.shouldErr {
   294  				t.Fatalf("unexpected success, want: %v", tc.err)
   295  			}
   296  
   297  			got := make(map[string]interface{})
   298  			got["config"] = server.GetConfig()
   299  			want := tests.Unpack(t, tc.want)
   300  
   301  			if diff := cmp.Diff(want, got); diff != "" {
   302  				t.Logf("JSON: %s", tests.UnpackJSON(t, got))
   303  				t.Errorf("NewServer() config mismatch (-want +got):\n%s", diff)
   304  			}
   305  		})
   306  	}
   307  }