eintopf.info@v0.13.16/service/auth/auth_test.go (about) 1 // Copyright (C) 2022 The Eintopf authors 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 package auth_test 17 18 import ( 19 "context" 20 "fmt" 21 "testing" 22 "time" 23 24 "eintopf.info/service/auth" 25 ) 26 27 var privateKey = []byte(`-----BEGIN RSA PRIVATE KEY----- 28 MIICXAIBAAKBgQCGGYYvHAZvjOVC6NtJNu42nwb1tvl1bhmgpwxg5gpnce0cuGK8 29 N4kky86sOpuUDmRCCoXCyR8l5wEE+XOluf0NOIEg8cA0w1+je60bVztDCK/IAlI9 30 szfdV7s0sFVgvb+SqoR6ADxmdPKnsIpqQfAYOSzwjMm/yinReyUO0mDXNQIDAQAB 31 AoGAFiMyjqZevZ2R32jXgo+p5aR9HqU1K1igrG/HUFvJjeg1z4705cN5RXTLyozm 32 UBvMG0bnbA+Nr9EhzvNrTwmUJ5H/7cXHEs0wOVO6y86bYO8XtP6Dfj2CvB704Zff 33 mcjfROuGolt4PUODlJnZh71ZK4FXnBXfugfcSzj7Og8K1+ECQQD0+p6FEiICLM9l 34 HrvZ85yFgZuRlzLo3AHuNIzpzhx4rRd1aijWhIGdlyg4hm0LJ0oCWK9YEJ0ce0yE 35 W2vbmg69AkEAjCHtaGCK543eMWLSdDBy5O/Ye2oTi5uKWm32ezsnZBF3/oZibw7J 36 kJBtYXx2Y+8MAeTzNE09GFe5lPtNZUHN2QJBAOAyECrGWntVGQR46P/g06jW4VGP 37 Zxb2aYnfa+p5J1NFTYe1/OO9ZoWblUKNu3OOpEubb/UPV0l+iZtDs2TJC50CQD/Y 38 WVUb301+aoRvtNjxFffOewBHpR4PQKrQvOMKYXkLKHOTgJd+0kEGPH+U+E+xovPd 39 /xyOME698TS6hlmi8IkCQCfRNndp4oBTtxoZVETxWw/6zZzoRduR7Ut2Yo3VSckf 40 rf7FI8Mzm5QV0eQOdwmHWKn1RRlJv+bOXBFttsrpgJo= 41 -----END RSA PRIVATE KEY-----`) 42 43 var publicKey = []byte(`-----BEGIN PUBLIC KEY----- 44 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGGYYvHAZvjOVC6NtJNu42nwb1 45 tvl1bhmgpwxg5gpnce0cuGK8N4kky86sOpuUDmRCCoXCyR8l5wEE+XOluf0NOIEg 46 8cA0w1+je60bVztDCK/IAlI9szfdV7s0sFVgvb+SqoR6ADxmdPKnsIpqQfAYOSzw 47 jMm/yinReyUO0mDXNQIDAQAB 48 -----END PUBLIC KEY-----`) 49 50 type mockedAuthenticator struct{} 51 52 func (m *mockedAuthenticator) Validate(ctx context.Context, email, password string) (string, error) { 53 if email == "admin@example.com" && password == "password" { 54 return "id", nil 55 } 56 57 if email == "error" || password == "error" { 58 return "", fmt.Errorf("error") 59 } 60 61 return "", nil 62 } 63 64 type mockedAuthorizer struct{} 65 66 func (m *mockedAuthorizer) Role(ctx context.Context, id string) (auth.Role, error) { 67 switch id { 68 case "admin": 69 return auth.RoleAdmin, nil 70 case "normal": 71 return auth.RoleNormal, nil 72 case "error": 73 return auth.RoleNormal, fmt.Errorf("error") 74 default: 75 return "", nil 76 } 77 } 78 79 func TestAuthService(t *testing.T) { 80 authService, err := auth.NewService(&mockedAuthenticator{}, &mockedAuthorizer{}, privateKey, publicKey, time.UTC) 81 if err != nil { 82 t.Fatalf("expected auth.NewService to succeed. got %s", err) 83 } 84 85 t.Run("invalid private/public keys", func(tt *testing.T) { 86 _, err := auth.NewService(&mockedAuthenticator{}, &mockedAuthorizer{}, []byte(""), []byte(""), time.UTC) 87 if err == nil { 88 tt.Fatal("expected auth.NewService to return an error") 89 } 90 }) 91 92 t.Run("login/authentication with invalid credentials", func(tt *testing.T) { 93 token, err := authService.Login(context.Background(), "foo", "bar") 94 if err != auth.ErrInvalidCredentials { 95 tt.Fatal("expected Login to return an err") 96 } 97 if token != "" { 98 tt.Fatal("expected token to be empty") 99 } 100 101 id, err := authService.Authenticate(token) 102 if err != nil { 103 tt.Fatalf("expected Authenticate not return an error. got %s", err) 104 } 105 if id != "" { 106 tt.Fatal("expected token to not be authenticated") 107 } 108 }) 109 110 t.Run("login with valid credentials", func(tt *testing.T) { 111 token, err := authService.Login(context.Background(), "admin@example.com", "password") 112 if err != nil { 113 tt.Fatalf("expected Login not return an error. got %s", err) 114 } 115 if token == "" { 116 tt.Fatal("expected token to not be empty") 117 } 118 119 id, err := authService.Authenticate(token) 120 if err != nil { 121 tt.Fatalf("expected Authenticate not return an error. got %s", err) 122 } 123 if id == "" { 124 tt.Fatal("expected token to be authenticated") 125 } 126 }) 127 128 t.Run("Authorize calls authorizer", func(tt *testing.T) { 129 role, err := authService.Authorize(context.Background(), "admin") 130 if err != nil { 131 tt.Fatalf("expected Authorize not return an error. got %s", err) 132 } 133 if role != auth.RoleAdmin { 134 tt.Fatalf("expected role to be 'admin'. got %s", role) 135 } 136 }) 137 }