mirror of https://github.com/goharbor/harbor.git
123 lines
3.4 KiB
Go
123 lines
3.4 KiB
Go
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package auth
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/vmware/harbor/src/common/models"
|
|
"github.com/vmware/harbor/src/common/utils/log"
|
|
"github.com/vmware/harbor/src/ui/config"
|
|
)
|
|
|
|
// 1.5 seconds
|
|
const frozenTime time.Duration = 1500 * time.Millisecond
|
|
|
|
const (
|
|
// DBAuth is the database auth mode.
|
|
DBAuth = "db_auth"
|
|
// LDAPAuth is the ldap auth mode.
|
|
LDAPAuth = "ldap_auth"
|
|
// UAAAuth is the uaa auth mode.
|
|
UAAAuth = "uaa_auth"
|
|
)
|
|
|
|
var lock = NewUserLock(frozenTime)
|
|
|
|
// AuthenticateHelper provides interface for user management in different auth modes.
|
|
type AuthenticateHelper interface {
|
|
|
|
// Authenticate ...
|
|
Authenticate(m models.AuthModel) (*models.User, error)
|
|
// OnBoardUser will check if a user exists in user table, if not insert the user and
|
|
// put the id in the pointer of user model, if it does exist, fill in the user model based
|
|
// on the data record of the user
|
|
OnBoardUser(u *models.User) error
|
|
// Get user information from account repository
|
|
SearchUser(username string) (*models.User, error)
|
|
}
|
|
|
|
var registry = make(map[string]AuthenticateHelper)
|
|
|
|
// Register add different authenticators to registry map.
|
|
func Register(name string, h AuthenticateHelper) {
|
|
if _, dup := registry[name]; dup {
|
|
log.Infof("authenticator: %s has been registered", name)
|
|
return
|
|
}
|
|
registry[name] = h
|
|
}
|
|
|
|
// Login authenticates user credentials based on setting.
|
|
func Login(m models.AuthModel) (*models.User, error) {
|
|
|
|
authMode, err := config.AuthMode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if authMode == "" || m.Principal == "admin" {
|
|
authMode = "db_auth"
|
|
}
|
|
log.Debug("Current AUTH_MODE is ", authMode)
|
|
|
|
authenticator, ok := registry[authMode]
|
|
if !ok {
|
|
return nil, fmt.Errorf("Unrecognized auth_mode: %s", authMode)
|
|
}
|
|
if lock.IsLocked(m.Principal) {
|
|
log.Debugf("%s is locked due to login failure, login failed", m.Principal)
|
|
return nil, nil
|
|
}
|
|
user, err := authenticator.Authenticate(m)
|
|
if user == nil && err == nil {
|
|
log.Debugf("Login failed, locking %s, and sleep for %v", m.Principal, frozenTime)
|
|
lock.Lock(m.Principal)
|
|
time.Sleep(frozenTime)
|
|
}
|
|
return user, err
|
|
}
|
|
|
|
func getHelper() (AuthenticateHelper, error) {
|
|
authMode, err := config.AuthMode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
AuthenticateHelper, ok := registry[authMode]
|
|
if !ok {
|
|
return nil, fmt.Errorf("Can not get authenticator, authmode: %s", authMode)
|
|
}
|
|
return AuthenticateHelper, nil
|
|
}
|
|
|
|
// OnBoardUser will check if a user exists in user table, if not insert the user and
|
|
// put the id in the pointer of user model, if it does exist, return the user's profile.
|
|
func OnBoardUser(user *models.User) error {
|
|
helper, err := getHelper()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return helper.OnBoardUser(user)
|
|
}
|
|
|
|
// SearchUser --
|
|
func SearchUser(username string) (*models.User, error) {
|
|
helper, err := getHelper()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return helper.SearchUser(username)
|
|
}
|