github.com/greenpau/go-authcrunch@v1.0.50/pkg/ids/local/authenticator.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 local 16 17 import ( 18 "github.com/google/uuid" 19 "github.com/greenpau/go-authcrunch/pkg/identity" 20 "github.com/greenpau/go-authcrunch/pkg/requests" 21 "go.uber.org/zap" 22 "os" 23 "sync" 24 ) 25 26 // Authenticator represents database connector. 27 type Authenticator struct { 28 db *identity.Database 29 mux sync.Mutex 30 path string 31 logger *zap.Logger 32 } 33 34 // NewAuthenticator returns an instance of Authenticator. 35 func NewAuthenticator() *Authenticator { 36 return &Authenticator{} 37 } 38 39 // Configure check database connectivity and required tables. 40 func (sa *Authenticator) Configure(fp string, users []*User) error { 41 sa.mux.Lock() 42 defer sa.mux.Unlock() 43 sa.logger.Info( 44 "identity store authenticator configuration", 45 zap.String("kind", storeKind), 46 zap.String("db_path", fp), 47 ) 48 sa.path = fp 49 50 db, err := identity.NewDatabase(fp) 51 if err != nil { 52 return err 53 } 54 sa.db = db 55 56 if len(users) > 0 { 57 for _, user := range users { 58 // Check whether user exists. 59 userFound, err := sa.db.UserExists(user.Username, user.EmailAddress) 60 if err != nil { 61 return err 62 } 63 if !userFound { 64 sa.logger.Debug( 65 "creating statically-defined identity store user", 66 zap.String("user", user.Username), 67 zap.String("email", user.EmailAddress), 68 ) 69 // Create user. 70 req := &requests.Request{ 71 User: requests.User{ 72 Username: user.Username, 73 Password: user.Password, 74 Email: user.EmailAddress, 75 Roles: user.Roles, 76 FullName: user.Name, 77 }, 78 } 79 if err := sa.db.AddUser(req); err != nil { 80 return err 81 } 82 } else { 83 if user.PasswordOverwriteEnabled { 84 sa.logger.Debug( 85 "updating password for statically-defined identity store user", 86 zap.String("user", user.Username), 87 zap.String("email", user.EmailAddress), 88 ) 89 // Update password (if overwrite is enabled). 90 req := &requests.Request{ 91 User: requests.User{ 92 Username: user.Username, 93 Password: user.Password, 94 Email: user.EmailAddress, 95 }, 96 } 97 if err := sa.db.UpdateUserPassword(req); err != nil { 98 return err 99 } 100 } 101 } 102 } 103 } 104 105 if sa.db.GetAdminUserCount() < 1 { 106 req := &requests.Request{ 107 User: requests.User{ 108 Username: os.Getenv("AUTHP_ADMIN_USER"), 109 Password: os.Getenv("AUTHP_ADMIN_SECRET"), 110 Email: os.Getenv("AUTHP_ADMIN_EMAIL"), 111 Roles: []string{"authp/admin"}, 112 }, 113 } 114 115 if req.User.Username == "" { 116 req.User.Username = "webadmin" 117 } 118 119 if req.User.Password == "" { 120 req.User.Password = uuid.New().String() 121 } 122 123 if req.User.Email == "" { 124 req.User.Email = "webadmin@localdomain.local" 125 } 126 127 if err := sa.db.AddUser(req); err != nil { 128 return err 129 } 130 sa.logger.Info("created default admin user for the database", 131 zap.String("username", req.User.Username), 132 zap.String("email", req.User.Email), 133 zap.String("secret", req.User.Password), 134 zap.Any("roles", req.User.Roles), 135 ) 136 } 137 return nil 138 } 139 140 // AuthenticateUser checks the database for the presence of a username/email 141 // and password and returns user claims. 142 func (sa *Authenticator) AuthenticateUser(r *requests.Request) error { 143 sa.mux.Lock() 144 defer sa.mux.Unlock() 145 return sa.db.AuthenticateUser(r) 146 } 147 148 // AddUser adds a user to database. 149 func (sa *Authenticator) AddUser(r *requests.Request) error { 150 sa.mux.Lock() 151 defer sa.mux.Unlock() 152 return sa.db.AddUser(r) 153 } 154 155 // GetUsers retrieves users from database. 156 func (sa *Authenticator) GetUsers(r *requests.Request) error { 157 sa.mux.Lock() 158 defer sa.mux.Unlock() 159 return sa.db.GetUsers(r) 160 } 161 162 // GetUser retrieves a specific user from database. 163 func (sa *Authenticator) GetUser(r *requests.Request) error { 164 sa.mux.Lock() 165 defer sa.mux.Unlock() 166 return sa.db.GetUser(r) 167 } 168 169 // DeleteUser delete a specific user from database. 170 func (sa *Authenticator) DeleteUser(r *requests.Request) error { 171 sa.mux.Lock() 172 defer sa.mux.Unlock() 173 return sa.db.DeleteUser(r) 174 } 175 176 // ChangePassword changes password for a user. 177 func (sa *Authenticator) ChangePassword(r *requests.Request) error { 178 sa.mux.Lock() 179 defer sa.mux.Unlock() 180 return sa.db.ChangeUserPassword(r) 181 } 182 183 // AddPublicKey adds public key, e.g. GPG or SSH, for a user. 184 func (sa *Authenticator) AddPublicKey(r *requests.Request) error { 185 sa.mux.Lock() 186 defer sa.mux.Unlock() 187 return sa.db.AddPublicKey(r) 188 } 189 190 // DeletePublicKey removes a public key, e.g. GPG or SSH, associated with the user. 191 func (sa *Authenticator) DeletePublicKey(r *requests.Request) error { 192 sa.mux.Lock() 193 defer sa.mux.Unlock() 194 return sa.db.DeletePublicKey(r) 195 } 196 197 // GetPublicKeys returns a list of public keys associated with a user. 198 func (sa *Authenticator) GetPublicKeys(r *requests.Request) error { 199 sa.mux.Lock() 200 defer sa.mux.Unlock() 201 return sa.db.GetPublicKeys(r) 202 } 203 204 // AddAPIKey adds API key for a user. 205 func (sa *Authenticator) AddAPIKey(r *requests.Request) error { 206 sa.mux.Lock() 207 defer sa.mux.Unlock() 208 return sa.db.AddAPIKey(r) 209 } 210 211 // DeleteAPIKey removes API key associated with the user. 212 func (sa *Authenticator) DeleteAPIKey(r *requests.Request) error { 213 sa.mux.Lock() 214 defer sa.mux.Unlock() 215 return sa.db.DeleteAPIKey(r) 216 } 217 218 // GetAPIKeys returns a list of API keys associated with a user. 219 func (sa *Authenticator) GetAPIKeys(r *requests.Request) error { 220 sa.mux.Lock() 221 defer sa.mux.Unlock() 222 return sa.db.GetAPIKeys(r) 223 } 224 225 // AddMfaToken adds MFA token to a user. 226 func (sa *Authenticator) AddMfaToken(r *requests.Request) error { 227 sa.mux.Lock() 228 defer sa.mux.Unlock() 229 return sa.db.AddMfaToken(r) 230 } 231 232 // DeleteMfaToken removes MFA token associated with the user. 233 func (sa *Authenticator) DeleteMfaToken(r *requests.Request) error { 234 sa.mux.Lock() 235 defer sa.mux.Unlock() 236 return sa.db.DeleteMfaToken(r) 237 } 238 239 // GetMfaTokens returns a list of MFA token associated with a user. 240 func (sa *Authenticator) GetMfaTokens(r *requests.Request) error { 241 sa.mux.Lock() 242 defer sa.mux.Unlock() 243 return sa.db.GetMfaTokens(r) 244 } 245 246 // IdentifyUser returns user challenges. 247 func (sa *Authenticator) IdentifyUser(r *requests.Request) error { 248 sa.mux.Lock() 249 defer sa.mux.Unlock() 250 return sa.db.IdentifyUser(r) 251 } 252 253 // LookupAPIKey performs user lookup based on an API key. 254 func (sa *Authenticator) LookupAPIKey(r *requests.Request) error { 255 sa.mux.Lock() 256 defer sa.mux.Unlock() 257 return sa.db.LookupAPIKey(r) 258 }