github.com/greenpau/go-authcrunch@v1.0.50/internal/tag/tag_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 tag
    16  
    17  import (
    18  	"bufio"
    19  	"fmt"
    20  	"github.com/greenpau/go-authcrunch"
    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"
    25  	authncache "github.com/greenpau/go-authcrunch/pkg/authn/cache"
    26  	"github.com/greenpau/go-authcrunch/pkg/authn/cookie"
    27  	"github.com/greenpau/go-authcrunch/pkg/authn/icons"
    28  	"github.com/greenpau/go-authcrunch/pkg/authn/transformer"
    29  	"github.com/greenpau/go-authcrunch/pkg/authn/ui"
    30  	"github.com/greenpau/go-authcrunch/pkg/authproxy"
    31  	"github.com/greenpau/go-authcrunch/pkg/authz"
    32  	"github.com/greenpau/go-authcrunch/pkg/authz/bypass"
    33  	"github.com/greenpau/go-authcrunch/pkg/authz/cache"
    34  	"github.com/greenpau/go-authcrunch/pkg/authz/injector"
    35  	"github.com/greenpau/go-authcrunch/pkg/authz/options"
    36  	"github.com/greenpau/go-authcrunch/pkg/authz/validator"
    37  	"github.com/greenpau/go-authcrunch/pkg/credentials"
    38  	"github.com/greenpau/go-authcrunch/pkg/identity"
    39  	"github.com/greenpau/go-authcrunch/pkg/identity/qr"
    40  	"github.com/greenpau/go-authcrunch/pkg/idp"
    41  	"github.com/greenpau/go-authcrunch/pkg/idp/oauth"
    42  	"github.com/greenpau/go-authcrunch/pkg/idp/saml"
    43  	"github.com/greenpau/go-authcrunch/pkg/ids"
    44  	"github.com/greenpau/go-authcrunch/pkg/ids/ldap"
    45  	"github.com/greenpau/go-authcrunch/pkg/ids/local"
    46  	"github.com/greenpau/go-authcrunch/pkg/kms"
    47  	"github.com/greenpau/go-authcrunch/pkg/messaging"
    48  	"github.com/greenpau/go-authcrunch/pkg/redirects"
    49  	"github.com/greenpau/go-authcrunch/pkg/registry"
    50  	"github.com/greenpau/go-authcrunch/pkg/requests"
    51  	"github.com/greenpau/go-authcrunch/pkg/sso"
    52  	"github.com/greenpau/go-authcrunch/pkg/user"
    53  	"github.com/greenpau/go-authcrunch/pkg/util"
    54  	"github.com/greenpau/go-authcrunch/pkg/util/cfg"
    55  	"strings"
    56  	"unicode"
    57  
    58  	"os"
    59  	"path/filepath"
    60  	"testing"
    61  )
    62  
    63  func TestTagCompliance(t *testing.T) {
    64  	testcases := []struct {
    65  		name      string
    66  		entry     interface{}
    67  		opts      *Options
    68  		shouldErr bool
    69  		err       error
    70  	}{
    71  		{
    72  			name:  "test sso.KeyInfo struct",
    73  			entry: &sso.KeyInfo{},
    74  			opts: &Options{
    75  				Disabled: true,
    76  			},
    77  		},
    78  		{
    79  			name:  "test sso.SingleSignOnService struct",
    80  			entry: &sso.SingleSignOnService{},
    81  			opts: &Options{
    82  				Disabled: true,
    83  			},
    84  		},
    85  		{
    86  			name:  "test sso.EntityDescriptor struct",
    87  			entry: &sso.EntityDescriptor{},
    88  			opts: &Options{
    89  				Disabled: true,
    90  			},
    91  		},
    92  		{
    93  			name:  "test sso.X509Data struct",
    94  			entry: &sso.X509Data{},
    95  			opts: &Options{
    96  				Disabled: true,
    97  			},
    98  		},
    99  		{
   100  			name:  "test sso.IDPEntityDescriptor struct",
   101  			entry: &sso.IDPEntityDescriptor{},
   102  			opts: &Options{
   103  				Disabled: true,
   104  			},
   105  		},
   106  		{
   107  			name:  "test sso.Service struct",
   108  			entry: &sso.Service{},
   109  			opts: &Options{
   110  				Disabled: true,
   111  			},
   112  		},
   113  		{
   114  			name:  "test sso.IDPSSODescriptor struct",
   115  			entry: &sso.IDPSSODescriptor{},
   116  			opts: &Options{
   117  				Disabled: true,
   118  			},
   119  		},
   120  		{
   121  			name:  "test sso.KeyDescriptor struct",
   122  			entry: &sso.KeyDescriptor{},
   123  			opts: &Options{
   124  				Disabled: true,
   125  			},
   126  		},
   127  		{
   128  			name:  "test sso.Provider struct",
   129  			entry: &sso.Provider{},
   130  			opts:  &Options{},
   131  		},
   132  		{
   133  			name:  "test sso.SingleSignOnProviderConfig struct",
   134  			entry: &sso.SingleSignOnProviderConfig{},
   135  			opts:  &Options{},
   136  		},
   137  		{
   138  			name:  "test sso.Request struct",
   139  			entry: &sso.Request{},
   140  			opts:  &Options{},
   141  		},
   142  		{
   143  			name:  "test ui.NavigationItem struct",
   144  			entry: &ui.NavigationItem{},
   145  			opts:  &Options{},
   146  		},
   147  		{
   148  			name:  "test requests.IdentityTokenCookie struct",
   149  			entry: &requests.IdentityTokenCookie{},
   150  			opts:  &Options{},
   151  		},
   152  		{
   153  			name:  "test icons.LoginIcon struct",
   154  			entry: &icons.LoginIcon{},
   155  			opts:  &Options{},
   156  		},
   157  		{
   158  			name:  "test registry.LocaUserRegistry struct",
   159  			entry: &registry.LocaUserRegistry{},
   160  			opts:  &Options{},
   161  		},
   162  		{
   163  			name:  "test messaging.FileProvider struct",
   164  			entry: &messaging.FileProvider{},
   165  			opts:  &Options{},
   166  		},
   167  		{
   168  			name:  "test messaging.FileProviderSendInput struct",
   169  			entry: &messaging.FileProviderSendInput{},
   170  			opts:  &Options{},
   171  		},
   172  		{
   173  			name:  "test messaging.EmailProviderSendInput struct",
   174  			entry: &messaging.EmailProviderSendInput{},
   175  			opts:  &Options{},
   176  		},
   177  		{
   178  			name:  "test authn.PortalParameters struct",
   179  			entry: &authn.PortalParameters{},
   180  			opts: &Options{
   181  				AllowFieldMismatch: true,
   182  				AllowedFields: map[string]interface{}{
   183  					"sso_providers": true,
   184  				},
   185  			},
   186  		},
   187  		{
   188  			name:  "test idp.IdentityProviderConfig struct",
   189  			entry: &idp.IdentityProviderConfig{},
   190  			opts:  &Options{},
   191  		},
   192  		{
   193  			name:  "test ids.IdentityStoreConfig struct",
   194  			entry: &ids.IdentityStoreConfig{},
   195  			opts:  &Options{},
   196  		},
   197  		{
   198  			name:  "test util.Browser struct",
   199  			entry: &util.Browser{},
   200  			opts:  &Options{},
   201  		},
   202  		{
   203  			name:  "test authn.APIConfig struct",
   204  			entry: &authn.APIConfig{},
   205  			opts:  &Options{},
   206  		},
   207  		{
   208  			name:  "test cookie.DomainConfig struct",
   209  			entry: &cookie.DomainConfig{},
   210  			opts:  &Options{},
   211  		},
   212  		{
   213  			name:  "test registry.RegistrationCache struct",
   214  			entry: &registry.RegistrationCache{},
   215  			opts:  &Options{},
   216  		},
   217  		{
   218  			name:  "test registry.RegistrationCacheEntry struct",
   219  			entry: &registry.RegistrationCacheEntry{},
   220  			opts:  &Options{},
   221  		},
   222  		{
   223  			name:  "test messaging.EmailProvider struct",
   224  			entry: &messaging.EmailProvider{},
   225  			opts:  &Options{},
   226  		},
   227  		{
   228  			name:  "test messaging.Config struct",
   229  			entry: &messaging.Config{},
   230  			opts:  &Options{},
   231  		},
   232  		{
   233  			name:  "test requests.Query struct",
   234  			entry: &requests.Query{},
   235  			opts:  &Options{},
   236  		},
   237  		{
   238  			name:  "test requests.User struct",
   239  			entry: &requests.User{},
   240  			opts:  &Options{},
   241  		},
   242  		{
   243  			name:  "test requests.Key struct",
   244  			entry: &requests.Key{},
   245  			opts:  &Options{},
   246  		},
   247  		{
   248  			name:  "test requests.MfaToken struct",
   249  			entry: &requests.MfaToken{},
   250  			opts:  &Options{},
   251  		},
   252  		{
   253  			name:  "test requests.Request struct",
   254  			entry: &requests.Request{},
   255  			opts:  &Options{},
   256  		},
   257  		{
   258  			name:  "test requests.Upstream struct",
   259  			entry: &requests.Upstream{},
   260  			opts:  &Options{},
   261  		},
   262  		{
   263  			name:  "test requests.Flags struct",
   264  			entry: &requests.Flags{},
   265  			opts:  &Options{},
   266  		},
   267  		{
   268  			name:  "test requests.Response struct",
   269  			entry: &requests.Response{},
   270  			opts:  &Options{},
   271  		},
   272  		{
   273  			name:  "test requests.Sandbox struct",
   274  			entry: &requests.Sandbox{},
   275  			opts:  &Options{},
   276  		},
   277  		{
   278  			name:  "test requests.WebAuthn struct",
   279  			entry: &requests.WebAuthn{},
   280  			opts:  &Options{},
   281  		},
   282  		{
   283  			name:  "test public key",
   284  			entry: &identity.PublicKey{},
   285  		},
   286  		{
   287  			name:  "test AttestationObject struct",
   288  			entry: &identity.AttestationObject{},
   289  			opts: &Options{
   290  				DisableTagMismatch: true,
   291  			},
   292  		},
   293  		{
   294  			name:  "test AttestationStatement struct",
   295  			entry: &identity.AttestationStatement{},
   296  			opts: &Options{
   297  				DisableTagMismatch: true,
   298  			},
   299  		},
   300  		{
   301  			name:  "test AuthData struct",
   302  			entry: &identity.AuthData{},
   303  			opts: &Options{
   304  				DisableTagMismatch: true,
   305  			},
   306  		},
   307  		{
   308  			name:  "test ClientData struct",
   309  			entry: &identity.ClientData{},
   310  			opts: &Options{
   311  				DisableTagMismatch: true,
   312  			},
   313  		},
   314  		{
   315  			name:  "test CredentialData struct",
   316  			entry: &identity.CredentialData{},
   317  			opts: &Options{
   318  				DisableTagMismatch: true,
   319  			},
   320  		},
   321  		{
   322  			name:  "test CreditCard struct",
   323  			entry: &identity.CreditCard{},
   324  		},
   325  		{
   326  			name:  "test CreditCardAssociation struct",
   327  			entry: &identity.CreditCardAssociation{},
   328  		},
   329  		{
   330  			name:  "test CreditCardIssuer struct",
   331  			entry: &identity.CreditCardIssuer{},
   332  		},
   333  		{
   334  			name:  "test Database struct",
   335  			entry: &identity.Database{},
   336  		},
   337  		{
   338  			name:  "test Device struct",
   339  			entry: &identity.Device{},
   340  		},
   341  		{
   342  			name:  "test EmailAddress struct",
   343  			entry: &identity.EmailAddress{},
   344  		},
   345  		{
   346  			name:  "test Handle struct",
   347  			entry: &identity.Handle{},
   348  		},
   349  		{
   350  			name:  "test Image struct",
   351  			entry: &identity.Image{},
   352  		},
   353  		{
   354  			name:  "test Location struct",
   355  			entry: &identity.Location{},
   356  		},
   357  		{
   358  			name:  "test LockoutState struct",
   359  			entry: &identity.LockoutState{},
   360  		},
   361  		{
   362  			name:  "test MfaDevice struct",
   363  			entry: &identity.MfaDevice{},
   364  		},
   365  		{
   366  			name:  "test MfaToken struct",
   367  			entry: &identity.MfaToken{},
   368  		},
   369  		{
   370  			name:  "test MfaTokenBundle struct",
   371  			entry: &identity.MfaTokenBundle{},
   372  		},
   373  		{
   374  			name:  "test Name struct",
   375  			entry: &identity.Name{},
   376  		},
   377  		{
   378  			name:  "test Organization struct",
   379  			entry: &identity.Organization{},
   380  		},
   381  		{
   382  			name:  "test Password struct",
   383  			entry: &identity.Password{},
   384  		},
   385  		{
   386  			name:  "test PublicKey struct",
   387  			entry: &identity.PublicKey{},
   388  		},
   389  		{
   390  			name:  "test PublicKeyBundle struct",
   391  			entry: &identity.PublicKeyBundle{},
   392  		},
   393  		{
   394  			name:  "test Registration struct",
   395  			entry: &identity.Registration{},
   396  		},
   397  		{
   398  			name:  "test Request struct",
   399  			entry: &requests.Request{},
   400  		},
   401  		{
   402  			name:  "test Role struct",
   403  			entry: &identity.Role{},
   404  		},
   405  		{
   406  			name:  "test User struct",
   407  			entry: &identity.User{},
   408  		},
   409  		{
   410  			name:  "test Policy struct",
   411  			entry: &identity.Policy{},
   412  		},
   413  		{
   414  			name:  "test UserPolicy struct",
   415  			entry: &identity.UserPolicy{},
   416  			opts: &Options{
   417  				DisableTagOnEmpty: true,
   418  			},
   419  		},
   420  		{
   421  			name:  "test PasswordPolicy struct",
   422  			entry: &identity.PasswordPolicy{},
   423  			opts: &Options{
   424  				DisableTagOnEmpty: true,
   425  			},
   426  		},
   427  		{
   428  			name:  "test WebAuthnRegisterRequest struct",
   429  			entry: &identity.WebAuthnRegisterRequest{},
   430  			opts: &Options{
   431  				DisableTagMismatch: true,
   432  			},
   433  		},
   434  		{
   435  			name:  "test identity.UserMetadata struct",
   436  			entry: &identity.UserMetadata{},
   437  			opts:  &Options{},
   438  		},
   439  		{
   440  			name:  "test identity.UserMetadataBundle struct",
   441  			entry: &identity.UserMetadataBundle{},
   442  			opts:  &Options{},
   443  		},
   444  		{
   445  			name:  "test qr.Code struct",
   446  			entry: &qr.Code{},
   447  			opts:  &Options{},
   448  		},
   449  		{
   450  			name:  "test identity.WebAuthnAuthenticateRequest struct",
   451  			entry: &identity.WebAuthnAuthenticateRequest{},
   452  			opts:  &Options{},
   453  		},
   454  		{
   455  			name:  "test identity.APIKeyBundle struct",
   456  			entry: &identity.APIKeyBundle{},
   457  			opts:  &Options{},
   458  		},
   459  		{
   460  			name:  "test identity.APIKey struct",
   461  			entry: &identity.APIKey{},
   462  			opts:  &Options{},
   463  		},
   464  		{
   465  			name:  "test authn.PortalConfig struct",
   466  			entry: &authn.PortalConfig{},
   467  			opts: &Options{
   468  				AllowFieldMismatch: true,
   469  				AllowedFields: map[string]interface{}{
   470  					"sso_providers": true,
   471  				},
   472  			},
   473  		},
   474  		{
   475  			name:  "test requests.AuthorizationRequest struct",
   476  			entry: &requests.AuthorizationRequest{},
   477  			opts:  &Options{},
   478  		},
   479  		{
   480  			name:  "test ui.Link struct",
   481  			entry: &ui.Link{},
   482  			opts:  &Options{},
   483  		},
   484  		{
   485  			name:  "test ui.Args struct",
   486  			entry: &ui.Args{},
   487  			opts:  &Options{},
   488  		},
   489  		{
   490  			name:  "test requests.AuthorizationResponse struct",
   491  			entry: &requests.AuthorizationResponse{},
   492  			opts: &Options{
   493  				Disabled: true,
   494  			},
   495  		},
   496  		{
   497  			name:  "test cache.SessionCache struct",
   498  			entry: &authncache.SessionCache{},
   499  			opts:  &Options{},
   500  		},
   501  		{
   502  			name:  "test ui.Template struct",
   503  			entry: &ui.Template{},
   504  			opts:  &Options{},
   505  		},
   506  		{
   507  			name:  "test authproxy.BasicAuthConfig struct",
   508  			entry: &authproxy.BasicAuthConfig{},
   509  			opts:  &Options{},
   510  		},
   511  		{
   512  			name:  "test user.Claims struct",
   513  			entry: &user.Claims{},
   514  			opts: &Options{
   515  				DisableTagMismatch: true,
   516  			},
   517  		},
   518  		{
   519  			name:  "test acl.RuleConfiguration struct",
   520  			entry: &acl.RuleConfiguration{},
   521  			opts:  &Options{},
   522  		},
   523  		{
   524  			name:  "test ldap.Authenticator struct",
   525  			entry: &ldap.Authenticator{},
   526  			opts:  &Options{},
   527  		},
   528  		{
   529  			name:  "test kms.CryptoKeyOperator struct",
   530  			entry: &kms.CryptoKeyOperator{},
   531  			opts:  &Options{},
   532  		},
   533  		{
   534  			name:  "test cache.SandboxCacheEntry struct",
   535  			entry: &authncache.SandboxCacheEntry{},
   536  			opts:  &Options{},
   537  		},
   538  		{
   539  			name:  "test local.Config struct",
   540  			entry: &local.Config{},
   541  			opts:  &Options{},
   542  		},
   543  		{
   544  			name:  "test local.User struct",
   545  			entry: &local.User{},
   546  			opts:  &Options{},
   547  		},
   548  		{
   549  			name:  "test credentials.Config struct",
   550  			entry: &credentials.Config{},
   551  			opts:  &Options{},
   552  		},
   553  		{
   554  			name:  "test registry.UserRegistryConfig struct",
   555  			entry: &registry.UserRegistryConfig{},
   556  			opts: &Options{
   557  				AllowFieldMismatch: true,
   558  				AllowedFields: map[string]interface{}{
   559  					"require_domain_mx": true,
   560  				},
   561  			},
   562  		},
   563  		{
   564  			name:  "test ui.UserRealm struct",
   565  			entry: &ui.UserRealm{},
   566  			opts:  &Options{},
   567  		},
   568  		{
   569  			name:  "test ui.Parameters struct",
   570  			entry: &ui.Parameters{},
   571  			opts:  &Options{},
   572  		},
   573  		{
   574  			name:  "test ui.StaticAsset struct",
   575  			entry: &ui.StaticAsset{},
   576  			opts:  &Options{},
   577  		},
   578  		{
   579  			name:  "test local.Backend struct",
   580  			entry: &local.IdentityStore{},
   581  			opts:  &Options{},
   582  		},
   583  		{
   584  			name:  "test local.Authenticator struct",
   585  			entry: &local.Authenticator{},
   586  			opts:  &Options{},
   587  		},
   588  		{
   589  			name:  "test options.TokenGrantorOptions struct",
   590  			entry: &options.TokenGrantorOptions{},
   591  			opts:  &Options{},
   592  		},
   593  		{
   594  			name:  "test oauth.Config struct",
   595  			entry: &oauth.Config{},
   596  			opts: &Options{
   597  				AllowFieldMismatch: true,
   598  				AllowedFields: map[string]interface{}{
   599  					"user_roles": true,
   600  				},
   601  			},
   602  		},
   603  		{
   604  			name:  "test cookie.Factory struct",
   605  			entry: &cookie.Factory{},
   606  			opts:  &Options{},
   607  		},
   608  		{
   609  			name:  "test user.Checkpoint struct",
   610  			entry: &user.Checkpoint{},
   611  			opts:  &Options{},
   612  		},
   613  		{
   614  			name:  "test transformer.Factory struct",
   615  			entry: &transformer.Factory{},
   616  			opts:  &Options{},
   617  		},
   618  		{
   619  			name:  "test user.AccessListClaim struct",
   620  			entry: &user.AccessListClaim{},
   621  			opts:  &Options{},
   622  		},
   623  		{
   624  			name:  "test testutils.InjectedTestToken struct",
   625  			entry: &testutils.InjectedTestToken{},
   626  			opts:  &Options{},
   627  		},
   628  		{
   629  			name:  "test kms.CryptoKey struct",
   630  			entry: &kms.CryptoKey{},
   631  			opts:  &Options{},
   632  		},
   633  		{
   634  			name:  "test cache.SandboxCache struct",
   635  			entry: &authncache.SandboxCache{},
   636  			opts:  &Options{},
   637  		},
   638  		{
   639  			name:  "test cookie.Config struct",
   640  			entry: &cookie.Config{},
   641  			opts:  &Options{},
   642  		},
   643  		{
   644  			name:  "test ldap.UserAttributes struct",
   645  			entry: &ldap.UserAttributes{},
   646  			opts:  &Options{},
   647  		},
   648  		{
   649  			name:  "test ui.StaticAssetLibrary struct",
   650  			entry: &ui.StaticAssetLibrary{},
   651  			opts:  &Options{},
   652  		},
   653  		{
   654  			name:  "test credentials.Generic struct",
   655  			entry: &credentials.Generic{},
   656  			opts:  &Options{},
   657  		},
   658  		{
   659  			name:  "test oauth.Backend struct",
   660  			entry: &oauth.IdentityProvider{},
   661  			opts:  &Options{},
   662  		},
   663  		{
   664  			name:  "test authproxy.Config struct",
   665  			entry: &authproxy.Config{},
   666  			opts:  &Options{},
   667  		},
   668  		{
   669  			name:  "test kms.CryptoKeyStore struct",
   670  			entry: &kms.CryptoKeyStore{},
   671  			opts:  &Options{},
   672  		},
   673  		{
   674  			name:  "test kms.CryptoKeyConfig struct",
   675  			entry: &kms.CryptoKeyConfig{},
   676  			opts: &Options{
   677  				AllowFieldMismatch: true,
   678  				AllowedFields: map[string]interface{}{
   679  					"token_secret":      true,
   680  					"token_sign_method": true,
   681  					"token_eval_expr":   true,
   682  				},
   683  			},
   684  		},
   685  		{
   686  			name:  "test cache.SessionCacheEntry struct",
   687  			entry: &authncache.SessionCacheEntry{},
   688  			opts:  &Options{},
   689  		},
   690  		{
   691  			name:  "test saml.Backend struct",
   692  			entry: &saml.IdentityProvider{},
   693  			opts:  &Options{},
   694  		},
   695  		{
   696  			name:  "test transformer.Config struct",
   697  			entry: &transformer.Config{},
   698  			opts:  &Options{},
   699  		},
   700  		{
   701  			name:  "test authcrunch.Config struct",
   702  			entry: &authcrunch.Config{},
   703  			opts: &Options{
   704  				AllowFieldMismatch: true,
   705  				AllowedFields: map[string]interface{}{
   706  					"auth_portal_configs":  true,
   707  					"authz_policy_configs": true,
   708  					"sso_providers":        true,
   709  				},
   710  			},
   711  		},
   712  		{
   713  			name:  "test cache.TokenCache struct",
   714  			entry: &cache.TokenCache{},
   715  			opts:  &Options{},
   716  		},
   717  		{
   718  			name:  "test ui.Factory struct",
   719  			entry: &ui.Factory{},
   720  			opts:  &Options{},
   721  		},
   722  		{
   723  			name:  "test authproxy.Response struct",
   724  			entry: &authproxy.Response{},
   725  			opts:  &Options{},
   726  		},
   727  		{
   728  			name:  "test user.Authenticator struct",
   729  			entry: &user.Authenticator{},
   730  			opts:  &Options{},
   731  		},
   732  		{
   733  			name:  "test cfg.ArgRule struct",
   734  			entry: &cfg.ArgRule{},
   735  			opts:  &Options{},
   736  		},
   737  		{
   738  			name:  "test oauth.JwksKey struct",
   739  			entry: &oauth.JwksKey{},
   740  			opts: &Options{
   741  				DisableTagMismatch: true,
   742  			},
   743  		},
   744  		{
   745  			name:  "test authproxy.Request struct",
   746  			entry: &authproxy.Request{},
   747  			opts:  &Options{},
   748  		},
   749  		{
   750  			name:  "test kms.CryptoKeyTokenOperator struct",
   751  			entry: &kms.CryptoKeyTokenOperator{},
   752  			opts:  &Options{},
   753  		},
   754  		{
   755  			name:  "test options.TokenValidatorOptions struct",
   756  			entry: &options.TokenValidatorOptions{},
   757  			opts:  &Options{},
   758  		},
   759  		{
   760  			name:  "test ldap.Backend struct",
   761  			entry: &ldap.IdentityStore{},
   762  			opts:  &Options{},
   763  		},
   764  		{
   765  			name:  "test validator.TokenValidator struct",
   766  			entry: &validator.TokenValidator{},
   767  			opts:  &Options{},
   768  		},
   769  		{
   770  			name:  "test saml.Config struct",
   771  			entry: &saml.Config{},
   772  			opts: &Options{
   773  				AllowFieldMismatch: true,
   774  				AllowedFields: map[string]interface{}{
   775  					"acs_urls": true,
   776  				},
   777  			},
   778  		},
   779  		{
   780  			name:  "test ldap.AuthServer struct",
   781  			entry: &ldap.AuthServer{},
   782  			opts:  &Options{},
   783  		},
   784  		{
   785  			name:  "test user.User struct",
   786  			entry: &user.User{},
   787  			opts:  &Options{},
   788  		},
   789  		{
   790  			name:  "test ldap.UserGroup struct",
   791  			entry: &ldap.UserGroup{},
   792  			opts: &Options{
   793  				AllowFieldMismatch: true,
   794  				AllowedFields: map[string]interface{}{
   795  					"dn": true,
   796  				},
   797  			},
   798  		},
   799  		{
   800  			name:  "test authproxy.APIKeyAuthConfig struct",
   801  			entry: &authproxy.APIKeyAuthConfig{},
   802  			opts:  &Options{},
   803  		},
   804  		{
   805  			name:  "test ldap.Config struct",
   806  			entry: &ldap.Config{},
   807  			opts:  &Options{},
   808  		},
   809  		{
   810  			name:  "test acl.AccessList struct",
   811  			entry: &acl.AccessList{},
   812  			opts:  &Options{},
   813  		},
   814  		{
   815  			name:  "test authz.PolicyConfig struct",
   816  			entry: &authz.PolicyConfig{},
   817  			opts: &Options{
   818  				AllowFieldMismatch: true,
   819  				AllowedFields: map[string]interface{}{
   820  					"disable_auth_redirect":       true,
   821  					"disable_auth_redirect_query": true,
   822  					"auth_redirect_query_param":   true,
   823  				},
   824  			},
   825  		},
   826  		{
   827  			name:  "test bypass.Config struct",
   828  			entry: &bypass.Config{},
   829  			opts:  &Options{},
   830  		},
   831  		{
   832  			name:  "test injector.Config struct",
   833  			entry: &injector.Config{},
   834  			opts:  &Options{},
   835  		},
   836  		{
   837  			name:  "test authn.AuthRequest struct",
   838  			entry: &authn.AuthRequest{},
   839  			opts:  &Options{},
   840  		},
   841  		{
   842  			name:  "test authn.AccessDeniedResponse struct",
   843  			entry: &authn.AccessDeniedResponse{},
   844  			opts:  &Options{},
   845  		},
   846  		{
   847  			name:  "test authn.Portal struct",
   848  			entry: &authn.Portal{},
   849  			opts:  &Options{},
   850  		},
   851  		{
   852  			name:  "test authn.AuthResponse struct",
   853  			entry: &authn.AuthResponse{},
   854  			opts:  &Options{},
   855  		},
   856  		{
   857  			name:  "test authcrunch.Server struct",
   858  			entry: &authcrunch.Server{},
   859  			opts:  &Options{},
   860  		},
   861  		{
   862  			name:  "test requests.RedirectResponse struct",
   863  			entry: &requests.RedirectResponse{},
   864  			opts:  &Options{},
   865  		},
   866  		{
   867  			name:  "test authz.Gatekeeper struct",
   868  			entry: &authz.Gatekeeper{},
   869  			opts:  &Options{},
   870  		},
   871  		{
   872  			name:  "test requests.AuthorizationToken struct",
   873  			entry: &requests.AuthorizationToken{},
   874  			opts:  &Options{},
   875  		},
   876  		{
   877  			name:  "test redirects.RedirectURIMatchConfig struct",
   878  			entry: &redirects.RedirectURIMatchConfig{},
   879  			opts:  &Options{},
   880  		},
   881  	}
   882  
   883  	for _, tc := range testcases {
   884  		t.Run(tc.name, func(t *testing.T) {
   885  			msgs, err := GetTagCompliance(tc.entry, tc.opts)
   886  			if tests.EvalErrWithLog(t, err, nil, tc.shouldErr, tc.err, msgs) {
   887  				return
   888  			}
   889  		})
   890  	}
   891  }
   892  
   893  func TestStructTagCompliance(t *testing.T) {
   894  	var files []string
   895  	structMap := make(map[string]bool)
   896  	walkFn := func(path string, fileInfo os.FileInfo, err error) error {
   897  		if err != nil {
   898  			return err
   899  		}
   900  		if fileInfo.IsDir() {
   901  			return nil
   902  		}
   903  		fileName := filepath.Base(path)
   904  		fileExt := filepath.Ext(fileName)
   905  		if fileExt != ".go" {
   906  			return nil
   907  		}
   908  		if strings.Contains(fileName, "_test.go") {
   909  			return nil
   910  		}
   911  		if strings.Contains(path, "/tag/") || strings.Contains(path, "/errors/") {
   912  			return nil
   913  		}
   914  		// t.Logf("%s %d", path, fileInfo.Size())
   915  		files = append(files, path)
   916  		return nil
   917  	}
   918  	if err := filepath.Walk("../../", walkFn); err != nil {
   919  		t.Error(err)
   920  	}
   921  
   922  	excludedFiles := []string{
   923  		"authn/ui/content.go",
   924  		"cmd/authdbctl/user.go",
   925  		"cmd/authdbctl/config.go",
   926  	}
   927  
   928  	for _, fp := range files {
   929  		// t.Logf("file %s", fp)
   930  		var skip bool
   931  		for _, excludedFile := range excludedFiles {
   932  			if strings.HasSuffix(fp, excludedFile) {
   933  				skip = true
   934  				break
   935  			}
   936  		}
   937  		if skip {
   938  			continue
   939  		}
   940  
   941  		var pkgFound bool
   942  		var pkgName string
   943  		fh, _ := os.Open(fp)
   944  		defer fh.Close()
   945  		scanner := bufio.NewScanner(fh)
   946  		for scanner.Scan() {
   947  			line := strings.TrimSpace(scanner.Text())
   948  			if strings.HasPrefix(line, "package ") {
   949  				pkgFound = true
   950  				pkgName = strings.Split(line, " ")[1]
   951  				// t.Logf("package %s", pkgName)
   952  				continue
   953  			}
   954  			if !pkgFound {
   955  				continue
   956  			}
   957  			if strings.HasPrefix(line, "type") && strings.Contains(line, "struct") {
   958  				structName := strings.Split(line, " ")[1]
   959  				// t.Logf("%s.%s", pkgName, structName)
   960  				if !unicode.IsUpper(rune(structName[0])) {
   961  					// Skip unexported structs.
   962  					continue
   963  				}
   964  				structMap[pkgName+"."+structName] = false
   965  			}
   966  
   967  			//fmt.Println(scanner.Text())
   968  		}
   969  		if err := scanner.Err(); err != nil {
   970  			t.Errorf("failed reading %q: %v", fp, err)
   971  		}
   972  	}
   973  
   974  	fp := "../../internal/tag/tag_test.go"
   975  	fh, _ := os.Open(fp)
   976  	defer fh.Close()
   977  	scanner := bufio.NewScanner(fh)
   978  	for scanner.Scan() {
   979  		line := strings.TrimSpace(scanner.Text())
   980  		for k := range structMap {
   981  			if strings.Contains(line, k+"{}") {
   982  				structMap[k] = true
   983  			}
   984  		}
   985  	}
   986  	if err := scanner.Err(); err != nil {
   987  		t.Errorf("failed reading %q: %v", fp, err)
   988  	}
   989  
   990  	if len(structMap) > 0 {
   991  		var msgs []string
   992  		for k, v := range structMap {
   993  			if v == false {
   994  				t.Logf("Found struct %s", k)
   995  				msgs = append(msgs, fmt.Sprintf("{\nname: \"test %s struct\",\nentry: &%s{},\nopts: &Options{},\n},", k, k))
   996  			}
   997  		}
   998  		if len(msgs) > 0 {
   999  			t.Logf("Add the following tests:\n" + strings.Join(msgs, "\n"))
  1000  			t.Fatal("Fix above structs")
  1001  		}
  1002  	}
  1003  }