github.com/greenpau/go-authcrunch@v1.1.4/pkg/authn/portal_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 authn 16 17 import ( 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 "github.com/greenpau/go-authcrunch/internal/tests" 22 "github.com/greenpau/go-authcrunch/internal/testutils" 23 "github.com/greenpau/go-authcrunch/pkg/acl" 24 "github.com/greenpau/go-authcrunch/pkg/authn/cookie" 25 "github.com/greenpau/go-authcrunch/pkg/authn/transformer" 26 "github.com/greenpau/go-authcrunch/pkg/authn/ui" 27 "github.com/greenpau/go-authcrunch/pkg/authz/options" 28 "github.com/greenpau/go-authcrunch/pkg/errors" 29 "github.com/greenpau/go-authcrunch/pkg/ids" 30 logutil "github.com/greenpau/go-authcrunch/pkg/util/log" 31 "go.uber.org/zap" 32 ) 33 34 func TestNewPortal(t *testing.T) { 35 db, err := testutils.CreateTestDatabase("TestNewPortal") 36 if err != nil { 37 t.Fatalf("failed to create temp dir: %v", err) 38 } 39 dbPath := db.GetPath() 40 t.Logf("%v", dbPath) 41 42 var testcases = []struct { 43 name string 44 disabled bool 45 want string 46 shouldErr bool 47 err error 48 49 loggerFunc func() *zap.Logger 50 configFunc func() *PortalConfig 51 52 // Portal Config fields. 53 uiConfig *ui.Parameters 54 userTransformerConfigs []*transformer.Config 55 cookieConfig *cookie.Config 56 identityStoreConfigs []*ids.IdentityStoreConfig 57 aclConfigs []*acl.RuleConfiguration 58 tokenValidatorOptions *options.TokenValidatorOptions 59 tokenGrantorOptions *options.TokenGrantorOptions 60 cryptoRawConfigs []string 61 }{ 62 { 63 name: "test new portal without logger", 64 loggerFunc: func() *zap.Logger { 65 return nil 66 }, 67 configFunc: func() *PortalConfig { 68 return nil 69 }, 70 shouldErr: true, 71 err: errors.ErrNewPortalLoggerNil, 72 }, 73 { 74 name: "test new portal without config", 75 loggerFunc: func() *zap.Logger { 76 return logutil.NewLogger() 77 }, 78 configFunc: func() *PortalConfig { 79 return nil 80 }, 81 shouldErr: true, 82 err: errors.ErrNewPortalConfigNil, 83 }, 84 { 85 name: "test new portal without name", 86 loggerFunc: func() *zap.Logger { 87 return logutil.NewLogger() 88 }, 89 configFunc: func() *PortalConfig { 90 return &PortalConfig{} 91 }, 92 shouldErr: true, 93 err: errors.ErrNewPortal.WithArgs(errors.ErrPortalConfigNameNotFound), 94 }, 95 { 96 name: "test new portal without backends", 97 loggerFunc: func() *zap.Logger { 98 return logutil.NewLogger() 99 }, 100 configFunc: func() *PortalConfig { 101 return &PortalConfig{ 102 Name: "myportal", 103 } 104 }, 105 shouldErr: true, 106 err: errors.ErrNewPortal.WithArgs(errors.ErrPortalConfigBackendsNotFound), 107 }, 108 { 109 name: "test new portal backed by local database", 110 loggerFunc: func() *zap.Logger { 111 return logutil.NewLogger() 112 }, 113 configFunc: func() *PortalConfig { 114 return &PortalConfig{ 115 Name: "myportal", 116 IdentityStores: []string{ 117 "local_backend", 118 }, 119 } 120 }, 121 identityStoreConfigs: []*ids.IdentityStoreConfig{ 122 { 123 Name: "local_backend", 124 Kind: "local", 125 Params: map[string]interface{}{ 126 "path": dbPath, 127 "realm": "local", 128 }, 129 }, 130 }, 131 want: `{ 132 "config": { 133 "name": "myportal", 134 "ui": { 135 "theme": "basic" 136 }, 137 "portal_admin_roles": { 138 "authp/admin": true 139 }, 140 "portal_user_roles": { 141 "authp/user": true 142 }, 143 "portal_guest_roles": { 144 "authp/guest": true 145 }, 146 "token_validator_options": { 147 "validate_bearer_header": true 148 }, 149 "access_list_configs": [ 150 { 151 "action": "allow stop", 152 "comment": "admin role name match", 153 "conditions": ["match role authp/admin"] 154 }, 155 { 156 "action": "allow stop", 157 "comment": "user role name match", 158 "conditions": ["match role authp/user"] 159 }, 160 { 161 "action": "allow stop", 162 "comment": "guest role name match", 163 "conditions": ["match role authp/guest"] 164 } 165 ], 166 "identity_stores": ["local_backend"] 167 } 168 }`, 169 }, 170 } 171 172 for _, tc := range testcases { 173 t.Run(tc.name, func(t *testing.T) { 174 if tc.disabled { 175 return 176 } 177 cfg := tc.configFunc() 178 if cfg != nil { 179 if tc.uiConfig != nil { 180 cfg.UI = tc.uiConfig 181 } 182 if len(tc.userTransformerConfigs) > 0 { 183 cfg.UserTransformerConfigs = tc.userTransformerConfigs 184 } 185 if tc.cookieConfig != nil { 186 cfg.CookieConfig = tc.cookieConfig 187 } 188 if len(tc.aclConfigs) > 0 { 189 cfg.AccessListConfigs = tc.aclConfigs 190 } 191 if tc.tokenValidatorOptions != nil { 192 cfg.TokenValidatorOptions = tc.tokenValidatorOptions 193 } 194 if tc.tokenGrantorOptions != nil { 195 cfg.TokenGrantorOptions = tc.tokenGrantorOptions 196 } 197 for _, s := range tc.cryptoRawConfigs { 198 cfg.AddRawCryptoConfigs(s) 199 } 200 } 201 202 params := PortalParameters{ 203 Config: cfg, 204 Logger: tc.loggerFunc(), 205 } 206 207 for _, storeCfg := range tc.identityStoreConfigs { 208 store, err := ids.NewIdentityStore(storeCfg, logutil.NewLogger()) 209 if err != nil { 210 t.Fatal(err) 211 } 212 if err := store.Configure(); err != nil { 213 t.Fatal(err) 214 } 215 params.IdentityStores = append(params.IdentityStores, store) 216 } 217 218 portal, err := NewPortal(params) 219 if err != nil { 220 if !tc.shouldErr { 221 t.Fatalf("expected success, got: %v", err) 222 } 223 if diff := cmp.Diff(err.Error(), tc.err.Error()); diff != "" { 224 t.Fatalf("unexpected error: %v, want: %v", err, tc.err) 225 } 226 return 227 } 228 if tc.shouldErr { 229 t.Fatalf("unexpected success, want: %v", tc.err) 230 } 231 232 got := make(map[string]interface{}) 233 got["config"] = tests.Unpack(t, portal.config) 234 want := tests.Unpack(t, tc.want) 235 236 if diff := cmp.Diff(want, got); diff != "" { 237 t.Logf("JSON: %s", tests.UnpackJSON(t, got)) 238 t.Errorf("NewPortal() config mismatch (-want +got):\n%s", diff) 239 } 240 }) 241 } 242 }