github.com/go-kivik/kivik/v4@v4.3.2/x/kivikd/authdb/authgroup/authgroup_test.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 //go:build !js 14 15 package authgroup 16 17 import ( 18 "context" 19 "fmt" 20 "net/http" 21 "reflect" 22 "testing" 23 24 "github.com/go-kivik/kivik/v4" 25 _ "github.com/go-kivik/kivik/v4/couchdb" 26 "github.com/go-kivik/kivik/v4/kiviktest/kt" 27 "github.com/go-kivik/kivik/v4/x/kivikd/authdb" 28 "github.com/go-kivik/kivik/v4/x/kivikd/authdb/confadmin" 29 "github.com/go-kivik/kivik/v4/x/kivikd/authdb/usersdb" 30 "github.com/go-kivik/kivik/v4/x/kivikd/conf" 31 ) 32 33 type tuser struct { 34 ID string `json:"_id"` 35 Name string `json:"name"` 36 Type string `json:"type"` 37 Roles []string `json:"roles"` 38 Password string `json:"password"` 39 } 40 41 func TestConfAdminAuth(t *testing.T) { 42 t.Skip("Reconfigure test not to require Docker") 43 // Set up first auth backend 44 c1 := conf.New() 45 c1.Set("admins.bob", "-pbkdf2-792221164f257de22ad72a8e94760388233e5714,7897f3451f59da741c87ec5f10fe7abe,10") 46 auth1 := confadmin.New(c1) 47 48 // Set up second auth backend 49 client := kt.GetClient(t) 50 db := client.DB("_users") 51 if e := db.Err(); e != nil { 52 t.Fatalf("Failed to connect to db: %s", e) 53 } 54 name := kt.TestDBName(t) 55 user := &tuser{ 56 ID: kivik.UserPrefix + name, 57 Name: name, 58 Type: "user", 59 Roles: []string{"coolguy"}, 60 Password: "abc123", 61 } 62 rev, e := db.Put(context.Background(), user.ID, user) 63 if e != nil { 64 t.Fatalf("Failed to create user: %s", e) 65 } 66 defer db.Delete(context.Background(), user.ID, rev) // nolint: errcheck 67 auth2 := usersdb.New(db) 68 69 auth := New(auth1, auth2) 70 71 t.Run("sync", func(t *testing.T) { 72 t.Run("Validate", func(t *testing.T) { 73 t.Parallel() 74 t.Run("BobValid", func(t *testing.T) { 75 t.Parallel() 76 uCtx, err := auth.Validate(context.Background(), "bob", "abc123") 77 if err != nil { 78 t.Errorf("Validation failure for bob/good password: %s", err) 79 } 80 if uCtx == nil { 81 t.Errorf("User should have been validated") 82 } 83 }) 84 t.Run("BobInvalid", func(t *testing.T) { 85 t.Parallel() 86 uCtx, err := auth.Validate(context.Background(), "bob", "foobar") 87 if kivik.HTTPStatus(err) != http.StatusUnauthorized { 88 t.Errorf("Expected Unauthorized for bad password, got %s", err) 89 } 90 if uCtx != nil { 91 t.Errorf("User should not have been validated with wrong password") 92 } 93 }) 94 t.Run("TestUserValid", func(t *testing.T) { 95 t.Parallel() 96 uCtx, err := auth.Validate(context.Background(), user.Name, "abc123") 97 if err != nil { 98 t.Errorf("Validation failure for good password: %s", err) 99 } 100 if uCtx == nil { 101 t.Errorf("User should have been validated") 102 } 103 }) 104 t.Run("TestUserInvalid", func(t *testing.T) { 105 t.Parallel() 106 uCtx, err := auth.Validate(context.Background(), user.Name, "foobar") 107 if kivik.HTTPStatus(err) != http.StatusUnauthorized { 108 t.Errorf("Expected Unauthorized for bad password, got %s", err) 109 } 110 if uCtx != nil { 111 t.Errorf("User should not have been validated with wrong password") 112 } 113 }) 114 t.Run("MissingUser", func(t *testing.T) { 115 t.Parallel() 116 uCtx, err := auth.Validate(context.Background(), "nobody", "foo") 117 if kivik.HTTPStatus(err) != http.StatusUnauthorized { 118 t.Errorf("Expected Unauthorized for bad username, got %s", err) 119 } 120 if uCtx != nil { 121 t.Errorf("User should not have been validated with wrong username") 122 } 123 }) 124 }) 125 t.Run("Context", func(t *testing.T) { 126 t.Parallel() 127 t.Run("TestUser", func(t *testing.T) { 128 uCtx, err := auth.UserCtx(context.Background(), user.Name) 129 if err != nil { 130 t.Errorf("Failed to get roles for valid user: %s", err) 131 } 132 uCtx.Salt = "" // It's random, so don't fail if it doesn't match 133 if !reflect.DeepEqual(uCtx, &authdb.UserContext{Name: user.Name, Roles: []string{"coolguy"}}) { 134 t.Errorf("Got unexpected context: %v", uCtx) 135 } 136 }) 137 t.Run("Bob", func(t *testing.T) { 138 t.Parallel() 139 uCtx, err := auth.UserCtx(context.Background(), "bob") 140 if err != nil { 141 t.Errorf("Failed to get roles for valid user: %s", err) 142 } 143 if !reflect.DeepEqual(uCtx, &authdb.UserContext{Name: "bob", Roles: []string{"_admin"}, Salt: "7897f3451f59da741c87ec5f10fe7abe"}) { 144 t.Errorf("Got unexpected context: %v", uCtx) 145 } 146 }) 147 t.Run("MissingUser", func(t *testing.T) { 148 _, err := auth.UserCtx(context.Background(), "nobody") 149 if kivik.HTTPStatus(err) != http.StatusNotFound { 150 var msg string 151 if err != nil { 152 msg = fmt.Sprintf(" Got: %s", err) 153 } 154 t.Errorf("Expected Not Found fetching roles for bad username.%s", msg) 155 } 156 }) 157 }) 158 }) 159 }