mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-28 11:37:42 +01:00
Remove GetUser and Onboard from common/dao
Replaced by funcs in src/pkg/user and src/controller/user Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
parent
0a8ff4c1f9
commit
952644e23f
@ -155,30 +155,13 @@ func clearAll() {
|
||||
|
||||
var currentUser *models.User
|
||||
|
||||
func TestGetUser(t *testing.T) {
|
||||
queryUser := models.User{
|
||||
Username: username,
|
||||
Email: "tester01@vmware.com",
|
||||
}
|
||||
var err error
|
||||
currentUser, err = GetUser(queryUser)
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred in GetUser: %v", err)
|
||||
}
|
||||
if currentUser == nil {
|
||||
t.Errorf("No user found queried by user query: %+v", queryUser)
|
||||
}
|
||||
if currentUser.Email != "tester01@vmware.com" {
|
||||
t.Errorf("the user's email does not match, expected: tester01@vmware.com, actual: %s", currentUser.Email)
|
||||
}
|
||||
|
||||
queryUser = models.User{}
|
||||
_, err = GetUser(queryUser)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestAddProject(t *testing.T) {
|
||||
|
||||
ctx := libOrm.Context()
|
||||
var err error
|
||||
currentUser, err = user.Mgr.GetByName(ctx, username)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to get user by username: %s, error: %v", username, err)
|
||||
}
|
||||
project := models.Project{
|
||||
OwnerID: currentUser.UserID,
|
||||
Name: projectName,
|
||||
@ -186,7 +169,7 @@ func TestAddProject(t *testing.T) {
|
||||
OwnerName: currentUser.Username,
|
||||
}
|
||||
|
||||
_, err := AddProject(project)
|
||||
_, err = AddProject(project)
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred in AddProject: %v", err)
|
||||
}
|
||||
|
@ -135,6 +135,12 @@ func ExecuteBatchSQL(sqls []string) {
|
||||
}
|
||||
}
|
||||
|
||||
// CleanUser - Clean this user information from DB, this is a shortcut for UT.
|
||||
func CleanUser(id int64) error {
|
||||
_, err := GetOrmer().QueryTable(&models.User{}).Filter("UserID", id).Delete()
|
||||
return err
|
||||
}
|
||||
|
||||
// ArrayEqual ...
|
||||
func ArrayEqual(arrayA, arrayB []int) bool {
|
||||
if len(arrayA) != len(arrayB) {
|
||||
|
@ -1,106 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// 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 dao
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
)
|
||||
|
||||
// GetUser ...
|
||||
func GetUser(query models.User) (*models.User, error) {
|
||||
|
||||
o := GetOrmer()
|
||||
|
||||
sql := `select user_id, username, password, password_version, email, realname, comment, reset_uuid, salt,
|
||||
sysadmin_flag, creation_time, update_time
|
||||
from harbor_user u
|
||||
where deleted = false `
|
||||
queryParam := make([]interface{}, 1)
|
||||
if query.UserID != 0 {
|
||||
sql += ` and user_id = ? `
|
||||
queryParam = append(queryParam, query.UserID)
|
||||
}
|
||||
|
||||
if query.Username != "" {
|
||||
sql += ` and username = ? `
|
||||
queryParam = append(queryParam, query.Username)
|
||||
}
|
||||
|
||||
if query.ResetUUID != "" {
|
||||
sql += ` and reset_uuid = ? `
|
||||
queryParam = append(queryParam, query.ResetUUID)
|
||||
}
|
||||
|
||||
if query.Email != "" {
|
||||
sql += ` and email = ? `
|
||||
queryParam = append(queryParam, query.Email)
|
||||
}
|
||||
|
||||
var u []models.User
|
||||
n, err := o.Raw(sql, queryParam).QueryRows(&u)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if n > 1 {
|
||||
return nil, fmt.Errorf("got more than one user when executing: %s param: %v", sql, queryParam)
|
||||
}
|
||||
|
||||
return &u[0], 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.
|
||||
// This is used for ldap and uaa authentication, such the user can have an ID in Harbor.
|
||||
func OnBoardUser(u *models.User) error {
|
||||
o := GetOrmer()
|
||||
created, id, err := o.ReadOrCreate(u, "Username")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
u.UserID = int(id)
|
||||
// current orm framework doesn't support to fetch a pointer or sql.NullString with QueryRow
|
||||
// https://github.com/astaxie/beego/issues/3767
|
||||
if len(u.Email) == 0 {
|
||||
_, err = o.Raw("update harbor_user set email = null where user_id = ? ", id).Exec()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
existing, err := GetUser(*u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Email = existing.Email
|
||||
u.SysAdminFlag = existing.SysAdminFlag
|
||||
u.Realname = existing.Realname
|
||||
u.UserID = existing.UserID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanUser - Clean this user information from DB
|
||||
func CleanUser(id int64) error {
|
||||
_, err := GetOrmer().QueryTable(&models.User{}).Filter("UserID", id).Delete()
|
||||
return err
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// 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 dao
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestOnBoardUser(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
u := &models.User{
|
||||
Username: "user1",
|
||||
Password: "password1",
|
||||
Email: "dummy@placehodler.com",
|
||||
Realname: "daniel",
|
||||
}
|
||||
err := OnBoardUser(u)
|
||||
assert.Nil(err)
|
||||
id := u.UserID
|
||||
assert.True(id > 0)
|
||||
err = OnBoardUser(u)
|
||||
assert.Nil(err)
|
||||
assert.True(u.UserID == id)
|
||||
CleanUser(int64(id))
|
||||
}
|
||||
func TestOnBoardUser_EmptyEmail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
u := &models.User{
|
||||
Username: "empty_email",
|
||||
Password: "password1",
|
||||
Realname: "empty_email",
|
||||
}
|
||||
err := OnBoardUser(u)
|
||||
assert.Nil(err)
|
||||
id := u.UserID
|
||||
assert.True(id > 0)
|
||||
err = OnBoardUser(u)
|
||||
assert.Nil(err)
|
||||
assert.True(u.UserID == id)
|
||||
assert.Equal("", u.Email)
|
||||
|
||||
user, err := GetUser(models.User{Username: "empty_email"})
|
||||
assert.Equal("", user.Email)
|
||||
CleanUser(int64(id))
|
||||
}
|
@ -78,16 +78,13 @@ func InitDatabaseFromEnv() {
|
||||
}
|
||||
|
||||
func updateUserInitialPassword(userID int, password string) error {
|
||||
queryUser := models.User{UserID: userID}
|
||||
user, err := dao.GetUser(queryUser)
|
||||
ctx := orm.Context()
|
||||
user, err := pkguser.Mgr.Get(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user, userID: %d %v", userID, err)
|
||||
}
|
||||
if user == nil {
|
||||
return fmt.Errorf("user id: %d does not exist", userID)
|
||||
}
|
||||
if user.Salt == "" {
|
||||
err = pkguser.Mgr.UpdatePassword(orm.Context(), userID, password)
|
||||
err = pkguser.Mgr.UpdatePassword(ctx, userID, password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update user encrypted password, userID: %d, err: %v", userID, err)
|
||||
}
|
||||
|
@ -67,7 +67,6 @@ func NewErrAuth(msg string) ErrAuth {
|
||||
|
||||
// AuthenticateHelper provides interface for user management in different auth modes.
|
||||
type AuthenticateHelper interface {
|
||||
|
||||
// Authenticate authenticate the user based on data in m. Only when the error returned is an instance
|
||||
// of ErrAuth, it will be considered a bad credentials, other errors will be treated as server side error.
|
||||
Authenticate(m models.AuthModel) (*models.User, error)
|
||||
|
@ -29,16 +29,17 @@ import (
|
||||
"github.com/goharbor/harbor/src/jobservice/logger"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
cfgModels "github.com/goharbor/harbor/src/lib/config/models"
|
||||
harborErrors "github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/pkg/usergroup/model"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/controller/usergroup"
|
||||
"github.com/goharbor/harbor/src/core/auth"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/pkg/authproxy"
|
||||
"github.com/goharbor/harbor/src/pkg/user"
|
||||
)
|
||||
|
||||
const refreshDuration = 2 * time.Second
|
||||
@ -58,6 +59,7 @@ type Auth struct {
|
||||
SkipSearch bool
|
||||
settingTimeStamp time.Time
|
||||
client *http.Client
|
||||
userMgr user.Manager
|
||||
}
|
||||
|
||||
type session struct {
|
||||
@ -136,18 +138,22 @@ func (a *Auth) VerifyToken(token string) (*models.User, error) {
|
||||
|
||||
// OnBoardUser delegates to dao pkg to insert/update data in DB.
|
||||
func (a *Auth) OnBoardUser(u *models.User) error {
|
||||
return dao.OnBoardUser(u)
|
||||
return a.userMgr.Onboard(orm.Context(), u)
|
||||
}
|
||||
|
||||
// PostAuthenticate generates the user model and on board the user.
|
||||
func (a *Auth) PostAuthenticate(u *models.User) error {
|
||||
if res, _ := dao.GetUser(*u); res != nil {
|
||||
return nil
|
||||
}
|
||||
if err := a.fillInModel(u); err != nil {
|
||||
_, err := a.userMgr.GetByName(orm.Context(), u.Username)
|
||||
if harborErrors.IsNotFoundErr(err) {
|
||||
if err2 := a.fillInModel(u); err2 != nil {
|
||||
return err2
|
||||
}
|
||||
return a.OnBoardUser(u)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.OnBoardUser(u)
|
||||
// do nothing if user exists in DB
|
||||
return nil
|
||||
}
|
||||
|
||||
// SearchUser returns nil as authproxy does not have such capability.
|
||||
@ -250,5 +256,7 @@ func getTLSConfig(setting *cfgModels.HTTPAuthProxy) (*tls.Config, error) {
|
||||
}
|
||||
|
||||
func init() {
|
||||
auth.Register(common.HTTPAuth, &Auth{})
|
||||
auth.Register(common.HTTPAuth, &Auth{
|
||||
userMgr: user.New(),
|
||||
})
|
||||
}
|
||||
|
@ -15,6 +15,10 @@
|
||||
package authproxy
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
@ -25,12 +29,10 @@ import (
|
||||
cfgModels "github.com/goharbor/harbor/src/lib/config/models"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
|
||||
"github.com/goharbor/harbor/src/pkg/user"
|
||||
"github.com/goharbor/harbor/src/pkg/usergroup"
|
||||
"github.com/goharbor/harbor/src/pkg/usergroup/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var mockSvr *httptest.Server
|
||||
@ -48,6 +50,7 @@ func TestMain(m *testing.M) {
|
||||
a = &Auth{
|
||||
Endpoint: mockSvr.URL + "/test/login",
|
||||
TokenReviewEndpoint: mockSvr.URL + "/test/tokenreview",
|
||||
userMgr: user.New(),
|
||||
}
|
||||
cfgMap := cut.GetUnitTestConfig()
|
||||
conf := map[string]interface{}{
|
||||
|
@ -16,9 +16,9 @@ package db
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/core/auth"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/pkg/user"
|
||||
)
|
||||
@ -26,11 +26,12 @@ import (
|
||||
// Auth implements Authenticator interface to authenticate user against DB.
|
||||
type Auth struct {
|
||||
auth.DefaultAuthenticateHelper
|
||||
userMgr user.Manager
|
||||
}
|
||||
|
||||
// Authenticate calls dao to authenticate user.
|
||||
func (d *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
||||
u, err := user.Mgr.MatchLocalPassword(orm.Context(), m.Principal, m.Password)
|
||||
u, err := d.userMgr.MatchLocalPassword(orm.Context(), m.Principal, m.Password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -42,11 +43,13 @@ func (d *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
||||
|
||||
// SearchUser - Check if user exist in local db
|
||||
func (d *Auth) SearchUser(username string) (*models.User, error) {
|
||||
var queryCondition = models.User{
|
||||
Username: username,
|
||||
u, err := d.userMgr.GetByName(orm.Context(), username)
|
||||
if errors.IsNotFoundErr(err) {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dao.GetUser(queryCondition)
|
||||
return u, err
|
||||
}
|
||||
|
||||
// OnBoardUser -
|
||||
@ -55,5 +58,7 @@ func (d *Auth) OnBoardUser(u *models.User) error {
|
||||
}
|
||||
|
||||
func init() {
|
||||
auth.Register(common.DBAuth, &Auth{})
|
||||
auth.Register(common.DBAuth, &Auth{
|
||||
userMgr: user.New(),
|
||||
})
|
||||
}
|
||||
|
@ -14,76 +14,41 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/db"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/core/auth"
|
||||
)
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
"github.com/goharbor/harbor/src/testing/mock"
|
||||
testinguserpkg "github.com/goharbor/harbor/src/testing/pkg/user"
|
||||
|
||||
var testConfig = map[string]interface{}{
|
||||
common.ExtEndpoint: "host01.com",
|
||||
common.AUTHMode: "db_auth",
|
||||
common.DatabaseType: "postgresql",
|
||||
common.PostGreSQLHOST: "127.0.0.1",
|
||||
common.PostGreSQLPort: 5432,
|
||||
common.PostGreSQLUsername: "postgres",
|
||||
common.PostGreSQLPassword: "root123",
|
||||
common.PostGreSQLDatabase: "registry",
|
||||
common.LDAPURL: "ldap://127.0.0.1",
|
||||
common.LDAPSearchDN: "cn=admin,dc=example,dc=com",
|
||||
common.LDAPSearchPwd: "admin",
|
||||
common.LDAPBaseDN: "dc=example,dc=com",
|
||||
common.LDAPUID: "uid",
|
||||
common.LDAPFilter: "",
|
||||
common.LDAPScope: 3,
|
||||
common.LDAPTimeout: 30,
|
||||
common.AdminInitialPassword: "password",
|
||||
}
|
||||
testifymock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
test.InitDatabaseFromEnv()
|
||||
secretKeyPath := "/tmp/secretkey"
|
||||
_, err := test.GenerateKey(secretKeyPath)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to generate secret key: %v", err)
|
||||
return
|
||||
}
|
||||
defer os.Remove(secretKeyPath)
|
||||
|
||||
if err := os.Setenv("KEY_PATH", secretKeyPath); err != nil {
|
||||
log.Fatalf("failed to set env %s: %v", "KEY_PATH", err)
|
||||
}
|
||||
|
||||
config.Init()
|
||||
|
||||
config.Upload(testConfig)
|
||||
retCode := m.Run()
|
||||
os.Exit(retCode)
|
||||
}
|
||||
|
||||
func TestSearchUser(t *testing.T) {
|
||||
// insert user first
|
||||
user := &models.User{
|
||||
UserID: 123,
|
||||
Username: "existuser",
|
||||
Email: "existuser@placeholder.com",
|
||||
Realname: "Existing user",
|
||||
}
|
||||
|
||||
err := dao.OnBoardUser(user)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to OnBoardUser %v", user)
|
||||
mockUserMgr := &testinguserpkg.Manager{}
|
||||
auth := &Auth{
|
||||
userMgr: mockUserMgr,
|
||||
}
|
||||
|
||||
var auth *Auth
|
||||
mockUserMgr.On("GetByName", mock.Anything, testifymock.MatchedBy(
|
||||
func(name string) bool {
|
||||
return name == "existuser"
|
||||
})).Return(user, nil)
|
||||
|
||||
newUser, err := auth.SearchUser("existuser")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to search user, error %v", err)
|
||||
@ -91,31 +56,4 @@ func TestSearchUser(t *testing.T) {
|
||||
if newUser == nil {
|
||||
t.Fatalf("Failed to search user %v", newUser)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAuthenticateHelperOnBoardUser(t *testing.T) {
|
||||
user := models.User{
|
||||
Username: "test01",
|
||||
Realname: "test01",
|
||||
Email: "test01@example.com",
|
||||
}
|
||||
|
||||
err := auth.OnBoardUser(&user)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to onboard user error: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAuthenticateHelperSearchUser(t *testing.T) {
|
||||
|
||||
user, err := auth.SearchUser("admin")
|
||||
if err != nil {
|
||||
t.Error("Failed to search user, admin")
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
t.Error("Failed to search user admin")
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg/ldap/model"
|
||||
@ -29,7 +30,6 @@ import (
|
||||
|
||||
goldap "github.com/go-ldap/ldap/v3"
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
@ -44,6 +44,7 @@ import (
|
||||
// Auth implements AuthenticateHelper interface to authenticate against LDAP
|
||||
type Auth struct {
|
||||
auth.DefaultAuthenticateHelper
|
||||
userMgr user.Manager
|
||||
}
|
||||
|
||||
// Authenticate checks user's credential against LDAP based on basedn template and LDAP URL,
|
||||
@ -92,7 +93,7 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
||||
u.Realname = ldapUsers[0].Realname
|
||||
u.Email = strings.TrimSpace(ldapUsers[0].Email)
|
||||
|
||||
l.syncUserInfoFromDB(&u)
|
||||
l.syncUserInfoFromDB(ctx, &u)
|
||||
l.attachLDAPGroup(ctx, ldapUsers, &u, ldapSession)
|
||||
|
||||
return &u, nil
|
||||
@ -140,14 +141,13 @@ func (l *Auth) attachLDAPGroup(ctx context.Context, ldapUsers []model.User, u *m
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Auth) syncUserInfoFromDB(u *models.User) {
|
||||
func (l *Auth) syncUserInfoFromDB(ctx context.Context, u *models.User) {
|
||||
// Retrieve SysAdminFlag from DB so that it transfer to session
|
||||
dbUser, err := dao.GetUser(models.User{Username: u.Username})
|
||||
if err != nil {
|
||||
log.Errorf("failed to sync user info from DB error %v", err)
|
||||
dbUser, err := l.userMgr.GetByName(ctx, u.Username)
|
||||
if errors.IsNotFoundErr(err) {
|
||||
return
|
||||
}
|
||||
if dbUser == nil {
|
||||
} else if err != nil {
|
||||
log.Errorf("failed to sync user info from DB error %v", err)
|
||||
return
|
||||
}
|
||||
u.SysAdminFlag = dbUser.SysAdminFlag
|
||||
@ -164,7 +164,7 @@ func (l *Auth) OnBoardUser(u *models.User) error {
|
||||
u.Password = "12345678AbC" // Password is not kept in local db
|
||||
u.Comment = "from LDAP." // Source is from LDAP
|
||||
|
||||
return dao.OnBoardUser(u)
|
||||
return l.userMgr.Onboard(orm.Context(), u)
|
||||
}
|
||||
|
||||
// SearchUser -- Search user in ldap
|
||||
@ -259,31 +259,26 @@ func (l *Auth) PostAuthenticate(u *models.User) error {
|
||||
|
||||
ctx := orm.Context()
|
||||
query := q.New(q.KeyWords{"Username": u.Username})
|
||||
n, err := user.Mgr.Count(ctx, query)
|
||||
n, err := l.userMgr.Count(ctx, query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n > 0 {
|
||||
queryCondition := models.User{
|
||||
Username: u.Username,
|
||||
}
|
||||
dbUser, err := dao.GetUser(queryCondition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dbUser == nil {
|
||||
dbUser, err := l.userMgr.GetByName(ctx, u.Username)
|
||||
if errors.IsNotFoundErr(err) {
|
||||
fmt.Printf("User not found in DB %+v", u)
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
u.UserID = dbUser.UserID
|
||||
|
||||
if dbUser.Email != u.Email {
|
||||
Re := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
|
||||
if !Re.MatchString(u.Email) {
|
||||
log.Debugf("Not a valid email address: %v, skip to sync", u.Email)
|
||||
} else {
|
||||
if err = user.Mgr.UpdateProfile(ctx, u, "Email"); err != nil {
|
||||
if err = l.userMgr.UpdateProfile(ctx, u, "Email"); err != nil {
|
||||
u.Email = dbUser.Email
|
||||
log.Errorf("failed to sync user email: %v", err)
|
||||
}
|
||||
@ -304,5 +299,7 @@ func (l *Auth) PostAuthenticate(u *models.User) error {
|
||||
}
|
||||
|
||||
func init() {
|
||||
auth.Register(common.LDAPAuth, &Auth{})
|
||||
auth.Register(common.LDAPAuth, &Auth{
|
||||
userMgr: user.New(),
|
||||
})
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/db"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
|
||||
userpkg "github.com/goharbor/harbor/src/pkg/user"
|
||||
"github.com/goharbor/harbor/src/pkg/usergroup"
|
||||
ugModel "github.com/goharbor/harbor/src/pkg/usergroup/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -62,6 +63,8 @@ var ldapTestConfig = map[string]interface{}{
|
||||
common.LDAPGroupAdminDn: "cn=harbor_users,ou=groups,dc=example,dc=com",
|
||||
}
|
||||
|
||||
var authHelper *Auth
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
test.InitDatabaseFromEnv()
|
||||
config.InitWithSettings(ldapTestConfig)
|
||||
@ -78,6 +81,10 @@ func TestMain(m *testing.M) {
|
||||
log.Fatalf("failed to set env %s: %v", "KEY_PATH", err)
|
||||
}
|
||||
|
||||
authHelper = &Auth{
|
||||
userMgr: userpkg.New(),
|
||||
}
|
||||
|
||||
// Extract to test utils
|
||||
initSqls := []string{
|
||||
"insert into harbor_user (username, email, password, realname) values ('member_test_01', 'member_test_01@example.com', '123456', 'member_test_01')",
|
||||
@ -104,7 +111,6 @@ func TestMain(m *testing.M) {
|
||||
|
||||
func TestAuthenticate(t *testing.T) {
|
||||
var person models.AuthModel
|
||||
var authHelper *Auth
|
||||
person.Principal = "test"
|
||||
person.Password = "123456"
|
||||
user, err := authHelper.Authenticate(person)
|
||||
@ -145,8 +151,7 @@ func TestAuthenticate(t *testing.T) {
|
||||
|
||||
func TestSearchUser(t *testing.T) {
|
||||
var username = "test"
|
||||
var auth *Auth
|
||||
user, err := auth.SearchUser(username)
|
||||
user, err := authHelper.SearchUser(username)
|
||||
if err != nil {
|
||||
t.Errorf("Search user failed %v", err)
|
||||
}
|
||||
@ -156,7 +161,6 @@ func TestSearchUser(t *testing.T) {
|
||||
}
|
||||
func TestAuthenticateWithAdmin(t *testing.T) {
|
||||
var person models.AuthModel
|
||||
var authHelper *Auth
|
||||
person.Principal = "mike"
|
||||
person.Password = "zhu88jie"
|
||||
user, err := authHelper.Authenticate(person)
|
||||
@ -172,7 +176,6 @@ func TestAuthenticateWithAdmin(t *testing.T) {
|
||||
}
|
||||
func TestAuthenticateWithoutAdmin(t *testing.T) {
|
||||
var person models.AuthModel
|
||||
var authHelper *Auth
|
||||
person.Principal = "user001"
|
||||
person.Password = "Test1@34"
|
||||
user, err := authHelper.Authenticate(person)
|
||||
@ -188,8 +191,7 @@ func TestAuthenticateWithoutAdmin(t *testing.T) {
|
||||
}
|
||||
func TestSearchUser_02(t *testing.T) {
|
||||
var username = "nonexist"
|
||||
var auth *Auth
|
||||
user, _ := auth.SearchUser(username)
|
||||
user, _ := authHelper.SearchUser(username)
|
||||
if user != nil {
|
||||
t.Errorf("Should failed to search nonexist user")
|
||||
}
|
||||
@ -202,9 +204,7 @@ func TestOnBoardUser(t *testing.T) {
|
||||
Email: "sample@example.com",
|
||||
Realname: "Sample",
|
||||
}
|
||||
|
||||
var auth *Auth
|
||||
err := auth.OnBoardUser(user)
|
||||
err := authHelper.OnBoardUser(user)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to onboard user")
|
||||
}
|
||||
@ -219,8 +219,7 @@ func TestOnBoardUser_02(t *testing.T) {
|
||||
Username: "sample02",
|
||||
Realname: "Sample02",
|
||||
}
|
||||
var auth *Auth
|
||||
err := auth.OnBoardUser(user)
|
||||
err := authHelper.OnBoardUser(user)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to onboard user")
|
||||
}
|
||||
@ -237,8 +236,7 @@ func TestOnBoardUser_03(t *testing.T) {
|
||||
Username: "sample03@example.com",
|
||||
Realname: "Sample03",
|
||||
}
|
||||
var auth *Auth
|
||||
err := auth.OnBoardUser(user)
|
||||
err := authHelper.OnBoardUser(user)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to onboard user")
|
||||
}
|
||||
@ -304,10 +302,7 @@ func TestPostAuthentication(t *testing.T) {
|
||||
Realname: "test003",
|
||||
}
|
||||
|
||||
queryCondition := models.User{
|
||||
Username: "test003",
|
||||
Realname: "test003",
|
||||
}
|
||||
queryUsername := "test003"
|
||||
|
||||
err := auth.OnBoardUser(user1)
|
||||
assert.Nil(err)
|
||||
@ -318,8 +313,8 @@ func TestPostAuthentication(t *testing.T) {
|
||||
}
|
||||
|
||||
auth.PostAuthenticate(user2)
|
||||
|
||||
dbUser, err := dao.GetUser(queryCondition)
|
||||
ctx := orm.Context()
|
||||
dbUser, err := userpkg.Mgr.GetByName(ctx, queryUsername)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get user, error %v", err)
|
||||
}
|
||||
@ -330,7 +325,7 @@ func TestPostAuthentication(t *testing.T) {
|
||||
}
|
||||
|
||||
auth.PostAuthenticate(user3)
|
||||
dbUser, err = dao.GetUser(queryCondition)
|
||||
dbUser, err = userpkg.Mgr.GetByName(ctx, queryUsername)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get user, error %v", err)
|
||||
}
|
||||
@ -342,8 +337,7 @@ func TestPostAuthentication(t *testing.T) {
|
||||
}
|
||||
|
||||
auth.PostAuthenticate(user4)
|
||||
|
||||
dbUser, err = dao.GetUser(queryCondition)
|
||||
dbUser, err = userpkg.Mgr.GetByName(ctx, queryUsername)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get user, error %v", err)
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils/uaa"
|
||||
"github.com/goharbor/harbor/src/core/auth"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
userpkg "github.com/goharbor/harbor/src/pkg/user"
|
||||
@ -36,6 +36,7 @@ type Auth struct {
|
||||
sync.Mutex
|
||||
client uaa.Client
|
||||
auth.DefaultAuthenticateHelper
|
||||
userMgr userpkg.Manager
|
||||
}
|
||||
|
||||
// Authenticate ...
|
||||
@ -72,7 +73,7 @@ func (u *Auth) OnBoardUser(user *models.User) error {
|
||||
}
|
||||
fillEmailRealName(user)
|
||||
user.Comment = "From UAA"
|
||||
return dao.OnBoardUser(user)
|
||||
return u.userMgr.Onboard(orm.Context(), user)
|
||||
}
|
||||
|
||||
func fillEmailRealName(user *models.User) {
|
||||
@ -86,17 +87,17 @@ func fillEmailRealName(user *models.User) {
|
||||
|
||||
// PostAuthenticate will check if user exists in DB, if not on Board user, if he does, update the profile.
|
||||
func (u *Auth) PostAuthenticate(user *models.User) error {
|
||||
dbUser, err := dao.GetUser(models.User{Username: user.Username})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dbUser == nil {
|
||||
ctx := orm.Context()
|
||||
dbUser, err := u.userMgr.GetByName(ctx, user.Username)
|
||||
if errors.IsNotFoundErr(err) {
|
||||
return u.OnBoardUser(user)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
user.UserID = dbUser.UserID
|
||||
user.SysAdminFlag = dbUser.SysAdminFlag
|
||||
fillEmailRealName(user)
|
||||
if err2 := userpkg.Mgr.UpdateProfile(orm.Context(), user, "Email", "Realname"); err2 != nil {
|
||||
if err2 := u.userMgr.UpdateProfile(ctx, user, "Email", "Realname"); err2 != nil {
|
||||
log.Warningf("Failed to update user profile, user: %s, error: %v", user.Username, err2)
|
||||
}
|
||||
return nil
|
||||
@ -158,5 +159,7 @@ func (u *Auth) ensureClient() error {
|
||||
return nil
|
||||
}
|
||||
func init() {
|
||||
auth.Register(common.UAAAuth, &Auth{})
|
||||
auth.Register(common.UAAAuth, &Auth{
|
||||
userMgr: userpkg.New(),
|
||||
})
|
||||
}
|
||||
|
@ -15,10 +15,10 @@
|
||||
package uaa
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/db"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
|
||||
|
||||
@ -26,6 +26,8 @@ import (
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
"github.com/goharbor/harbor/src/common/utils/uaa"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
userpkg "github.com/goharbor/harbor/src/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -68,7 +70,10 @@ func TestAuthenticate(t *testing.T) {
|
||||
Username: "user1",
|
||||
Password: "password1",
|
||||
}
|
||||
auth := Auth{client: client}
|
||||
auth := Auth{
|
||||
client: client,
|
||||
userMgr: userpkg.New(),
|
||||
}
|
||||
m1 := models.AuthModel{
|
||||
Principal: "user1",
|
||||
Password: "password1",
|
||||
@ -90,7 +95,10 @@ func TestAuthenticate(t *testing.T) {
|
||||
|
||||
func TestOnBoardUser(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
auth := Auth{}
|
||||
ctx := orm.Context()
|
||||
auth := Auth{
|
||||
userMgr: userpkg.New(),
|
||||
}
|
||||
um1 := &models.User{
|
||||
Username: " ",
|
||||
}
|
||||
@ -99,11 +107,11 @@ func TestOnBoardUser(t *testing.T) {
|
||||
um2 := &models.User{
|
||||
Username: "test ",
|
||||
}
|
||||
user2, _ := dao.GetUser(models.User{Username: "test"})
|
||||
user2, _ := auth.userMgr.GetByName(ctx, "test")
|
||||
assert.Nil(user2)
|
||||
err2 := auth.OnBoardUser(um2)
|
||||
assert.Nil(err2)
|
||||
user, _ := dao.GetUser(models.User{Username: "test"})
|
||||
user, _ := auth.userMgr.GetByName(ctx, "test")
|
||||
assert.Equal("test", user.Realname)
|
||||
assert.Equal("test", user.Username)
|
||||
assert.Equal("", user.Email)
|
||||
@ -113,7 +121,9 @@ func TestOnBoardUser(t *testing.T) {
|
||||
|
||||
func TestPostAuthenticate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
auth := Auth{}
|
||||
auth := Auth{
|
||||
userMgr: userpkg.New(),
|
||||
}
|
||||
um := &models.User{
|
||||
Username: "test",
|
||||
}
|
||||
@ -122,15 +132,16 @@ func TestPostAuthenticate(t *testing.T) {
|
||||
um2 := &models.User{
|
||||
Username: "test",
|
||||
}
|
||||
ctx := orm.Context()
|
||||
assert.Nil(err)
|
||||
user, _ := dao.GetUser(models.User{Username: "test"})
|
||||
user, _ := auth.userMgr.GetByName(ctx, "test")
|
||||
assert.Equal("", user.Email)
|
||||
um2.Email = "newEmail@new.com"
|
||||
um2.Realname = "newName"
|
||||
err2 := auth.PostAuthenticate(um2)
|
||||
assert.Equal(user.UserID, um2.UserID)
|
||||
assert.Nil(err2)
|
||||
user2, _ := dao.GetUser(models.User{Username: "test"})
|
||||
user2, _ := auth.userMgr.GetByName(ctx, "test")
|
||||
assert.Equal("newEmail@new.com", user2.Email)
|
||||
assert.Equal("newName", user2.Realname)
|
||||
// need a new user model to simulate a login case...
|
||||
@ -139,7 +150,7 @@ func TestPostAuthenticate(t *testing.T) {
|
||||
}
|
||||
err3 := auth.PostAuthenticate(um3)
|
||||
assert.Nil(err3)
|
||||
user3, _ := dao.GetUser(models.User{Username: "test"})
|
||||
user3, _ := auth.userMgr.GetByName(ctx, "test")
|
||||
assert.Equal(user3.UserID, um3.UserID)
|
||||
assert.Equal("", user3.Email)
|
||||
assert.Equal("test", user3.Realname)
|
||||
|
@ -37,7 +37,6 @@ import (
|
||||
_ "github.com/goharbor/harbor/src/controller/event/handler"
|
||||
"github.com/goharbor/harbor/src/controller/health"
|
||||
"github.com/goharbor/harbor/src/controller/registry"
|
||||
ctluser "github.com/goharbor/harbor/src/controller/user"
|
||||
"github.com/goharbor/harbor/src/core/api"
|
||||
_ "github.com/goharbor/harbor/src/core/auth/authproxy"
|
||||
_ "github.com/goharbor/harbor/src/core/auth/db"
|
||||
@ -58,6 +57,7 @@ import (
|
||||
_ "github.com/goharbor/harbor/src/pkg/notifier/topic"
|
||||
"github.com/goharbor/harbor/src/pkg/scan"
|
||||
"github.com/goharbor/harbor/src/pkg/scan/dao/scanner"
|
||||
pkguser "github.com/goharbor/harbor/src/pkg/user"
|
||||
"github.com/goharbor/harbor/src/pkg/version"
|
||||
"github.com/goharbor/harbor/src/server"
|
||||
)
|
||||
@ -67,16 +67,13 @@ const (
|
||||
)
|
||||
|
||||
func updateInitPassword(ctx context.Context, userID int, password string) error {
|
||||
queryUser := models.User{UserID: userID}
|
||||
user, err := dao.GetUser(queryUser)
|
||||
userMgr := pkguser.Mgr
|
||||
user, err := userMgr.Get(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user, userID: %d %v", userID, err)
|
||||
}
|
||||
if user == nil {
|
||||
return fmt.Errorf("user id: %d does not exist", userID)
|
||||
}
|
||||
if user.Salt == "" {
|
||||
err = ctluser.Ctl.UpdatePassword(ctx, userID, password)
|
||||
err = userMgr.UpdatePassword(ctx, userID, password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update user encrypted password, userID: %d, err: %v", userID, err)
|
||||
}
|
||||
|
@ -54,6 +54,10 @@ type Manager interface {
|
||||
// MatchLocalPassword tries to match the record in DB based on the input, the first return value is
|
||||
// the user model corresponding to the entry in DB
|
||||
MatchLocalPassword(ctx context.Context, username, password string) (*models.User, error)
|
||||
// Onboard 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.
|
||||
// This is used for ldap and uaa authentication, such the user can have an ID in Harbor.
|
||||
Onboard(ctx context.Context, user *models.User) error
|
||||
}
|
||||
|
||||
// New returns a default implementation of Manager
|
||||
@ -65,6 +69,27 @@ type manager struct {
|
||||
dao dao.DAO
|
||||
}
|
||||
|
||||
func (m *manager) Onboard(ctx context.Context, user *models.User) error {
|
||||
u, err := m.GetByName(ctx, user.Username)
|
||||
if err == nil {
|
||||
user.Email = u.Email
|
||||
user.SysAdminFlag = u.SysAdminFlag
|
||||
user.Realname = u.Realname
|
||||
user.UserID = u.UserID
|
||||
return nil
|
||||
} else if !errors.IsNotFoundErr(err) {
|
||||
return err
|
||||
}
|
||||
// User does not exists, insert the user record.
|
||||
// Given this func is ALWAYS called in a tx, the conflict error can rollback the tx to ensure the consistency
|
||||
id, err2 := m.Create(ctx, user)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
user.UserID = id
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manager) Delete(ctx context.Context, id int) error {
|
||||
u, err := m.Get(ctx, id)
|
||||
if err != nil {
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/testing/mock"
|
||||
"github.com/goharbor/harbor/src/testing/pkg/user/dao"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -45,6 +47,56 @@ func (m *mgrTestSuite) TestSetAdminFlag() {
|
||||
m.dao.AssertExpectations(m.T())
|
||||
}
|
||||
|
||||
func (m *mgrTestSuite) TestOnboard() {
|
||||
existingUser := &models.User{
|
||||
UserID: 123,
|
||||
Username: "existing",
|
||||
Email: "existing@mytest.com",
|
||||
Realname: "existing",
|
||||
}
|
||||
newID := 124
|
||||
m.dao.On("Create", mock.Anything, testifymock.MatchedBy(
|
||||
func(u *models.User) bool {
|
||||
return u.Username == "existing"
|
||||
})).Return(0, errors.ConflictError(nil).WithMessage("username exists"))
|
||||
m.dao.On("Create", mock.Anything, testifymock.MatchedBy(
|
||||
func(u *models.User) bool {
|
||||
return u.Username != "existing" && u.Username != "dup-but-not-existing"
|
||||
})).Return(newID, nil)
|
||||
m.dao.On("List", mock.Anything, testifymock.MatchedBy(
|
||||
func(query *q.Query) bool {
|
||||
return query.Keywords["username"] == "existing"
|
||||
})).Return([]*models.User{existingUser}, nil)
|
||||
m.dao.On("List", mock.Anything, testifymock.MatchedBy(
|
||||
func(query *q.Query) bool {
|
||||
return query.Keywords["username"] != "existing"
|
||||
})).Return([]*models.User{}, nil)
|
||||
|
||||
{
|
||||
newUser := &models.User{
|
||||
Username: "newUser",
|
||||
Email: "newUser@mytest.com",
|
||||
Realname: "newUser",
|
||||
}
|
||||
err := m.mgr.Onboard(context.Background(), newUser)
|
||||
m.Nil(err)
|
||||
m.Equal(newID, newUser.UserID)
|
||||
m.Equal(newUser.Username, newUser.Username)
|
||||
}
|
||||
{
|
||||
newUser := &models.User{
|
||||
Username: "existing",
|
||||
Email: "existing@mytest.com",
|
||||
Realname: "existing",
|
||||
}
|
||||
err := m.mgr.Onboard(context.Background(), newUser)
|
||||
m.Nil(err)
|
||||
m.Equal(existingUser.Username, newUser.Username)
|
||||
m.Equal(existingUser.Email, newUser.Email)
|
||||
m.Equal(existingUser.UserID, newUser.UserID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestManager(t *testing.T) {
|
||||
suite.Run(t, &mgrTestSuite{})
|
||||
}
|
||||
|
@ -15,20 +15,20 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/security"
|
||||
"github.com/goharbor/harbor/src/common/security/local"
|
||||
"github.com/goharbor/harbor/src/core/auth"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/pkg/authproxy"
|
||||
pkguser "github.com/goharbor/harbor/src/pkg/user"
|
||||
)
|
||||
|
||||
type authProxy struct{}
|
||||
@ -65,27 +65,22 @@ func (a *authProxy) Generate(req *http.Request) security.Context {
|
||||
log.Errorf("user name doesn't match with token: %s", rawUserName)
|
||||
return nil
|
||||
}
|
||||
user, err := dao.GetUser(models.User{
|
||||
Username: rawUserName,
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to get user %s: %v", rawUserName, err)
|
||||
return nil
|
||||
}
|
||||
if user == nil {
|
||||
user, err := pkguser.Mgr.GetByName(req.Context(), rawUserName)
|
||||
if errors.IsNotFoundErr(err) {
|
||||
// onboard user if it's not yet onboarded.
|
||||
uid, err := auth.SearchAndOnBoardUser(rawUserName)
|
||||
if err != nil {
|
||||
uid, err2 := auth.SearchAndOnBoardUser(rawUserName)
|
||||
if err2 != nil {
|
||||
log.Errorf("failed to search and onboard user %s: %v", rawUserName, err)
|
||||
return nil
|
||||
}
|
||||
user, err = dao.GetUser(models.User{
|
||||
UserID: uid,
|
||||
})
|
||||
if err != nil {
|
||||
user, err2 = pkguser.Mgr.Get(req.Context(), uid)
|
||||
if err2 != nil {
|
||||
log.Errorf("failed to get user, name: %s, ID: %d: %v", rawUserName, uid, err)
|
||||
return nil
|
||||
}
|
||||
} else if err != nil {
|
||||
log.Errorf("failed to get user %s: %v", rawUserName, err)
|
||||
return nil
|
||||
}
|
||||
u2, err := authproxy.UserFromReviewStatus(tokenReviewStatus, httpAuthProxyConf.AdminGroups, httpAuthProxyConf.AdminUsernames)
|
||||
if err != nil {
|
||||
|
@ -67,7 +67,8 @@ func TestAuthProxy(t *testing.T) {
|
||||
// No onboard
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1/v2", nil)
|
||||
require.Nil(t, err)
|
||||
req = req.WithContext(lib.WithAuthMode(req.Context(), common.HTTPAuth))
|
||||
ormCtx := orm.Context()
|
||||
req = req.WithContext(lib.WithAuthMode(ormCtx, common.HTTPAuth))
|
||||
req.SetBasicAuth("tokenreview$administrator@vsphere.local", "reviEwt0k3n")
|
||||
ctx := authProxy.Generate(req)
|
||||
assert.NotNil(t, ctx)
|
||||
|
@ -166,6 +166,20 @@ func (_m *Manager) MatchLocalPassword(ctx context.Context, username string, pass
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Onboard provides a mock function with given fields: ctx, _a1
|
||||
func (_m *Manager) Onboard(ctx context.Context, _a1 *models.User) error {
|
||||
ret := _m.Called(ctx, _a1)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.User) error); ok {
|
||||
r0 = rf(ctx, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetSysAdminFlag provides a mock function with given fields: ctx, id, admin
|
||||
func (_m *Manager) SetSysAdminFlag(ctx context.Context, id int, admin bool) error {
|
||||
ret := _m.Called(ctx, id, admin)
|
||||
|
Loading…
Reference in New Issue
Block a user