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