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