db refactor

This commit is contained in:
Wenkai Yin 2016-03-28 15:34:41 +08:00
parent a61cf3625a
commit ac5bbc4657
12 changed files with 415 additions and 242 deletions

View File

@ -16,6 +16,7 @@
package api
import (
"fmt"
"net/http"
"strconv"
@ -23,6 +24,7 @@ import (
"github.com/vmware/harbor/models"
"github.com/astaxie/beego"
"github.com/vmware/harbor/utils/log"
)
// ProjectMemberAPI handles request to /api/projects/{}/members/{}
@ -148,7 +150,13 @@ func (pma *ProjectMemberAPI) Post() {
}
for _, rid := range req.Roles {
err = dao.AddUserProjectRole(userID, pid, int(rid))
role, err := dao.IntToRole(rid)
if err != nil {
log.Error(err)
pma.RenderError(http.StatusBadRequest, fmt.Sprintf("Invalid role: %d", rid))
}
err = dao.AddProjectMember(pid, userID, role)
if err != nil {
beego.Error("Failed to update DB to add project user role, project id:", pid, ", user id:", userID, ", role id:", rid)
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
@ -182,7 +190,7 @@ func (pma *ProjectMemberAPI) Put() {
}
//TODO: delete and insert should in one transaction
//delete user project role record for the given user
err = dao.DeleteUserProjectRoles(mid, pid)
err = dao.DeleteProjectMember(pid, mid)
if err != nil {
beego.Error("Failed to delete project roles for user, user id:", mid, ", project id: ", pid, ", error: ", err)
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")
@ -190,7 +198,13 @@ func (pma *ProjectMemberAPI) Put() {
}
//insert roles in request
for _, rid := range req.Roles {
err = dao.AddUserProjectRole(mid, pid, int(rid))
role, err := dao.IntToRole(rid)
if err != nil {
log.Error(err)
pma.RenderError(http.StatusBadRequest, fmt.Sprintf("Invalid role: %d", rid))
}
err = dao.AddProjectMember(pid, mid, role)
if err != nil {
beego.Error("Failed to update DB to add project user role, project id:", pid, ", user id:", mid, ", role id:", rid)
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
@ -210,7 +224,7 @@ func (pma *ProjectMemberAPI) Delete() {
pma.RenderError(http.StatusForbidden, "")
return
}
err = dao.DeleteUserProjectRoles(mid, pid)
err = dao.DeleteProjectMember(pid, mid)
if err != nil {
beego.Error("Failed to delete project roles for user, user id:", mid, ", project id:", pid, ", error:", err)
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")

View File

@ -17,11 +17,12 @@ package dao
import (
"fmt"
"log"
"os"
"testing"
"time"
"github.com/vmware/harbor/utils/log"
"github.com/vmware/harbor/models"
"github.com/astaxie/beego/orm"
@ -41,44 +42,61 @@ func execUpdate(o orm.Ormer, sql string, params interface{}) error {
}
func clearUp(username string) {
var err error
o := orm.NewOrm()
o.Begin()
err := execUpdate(o, `delete upr from user_project_role upr
left join project_role pr on upr.pr_id = pr.pr_id
left join project p on pr.project_id = p.project_id
left join user u on u.user_id = p.owner_id
where u.username = ?`, username)
err = execUpdate(o, `delete pm
from project_member pm
join user u
on pm.user_id = u.user_id
where u.username = ?`, username)
if err != nil {
o.Rollback()
log.Println(err)
log.Error(err)
}
err = execUpdate(o, `delete pr from project_role pr
left join project p on pr.project_id = p.project_id
left join user u on u.user_id = p.owner_id
where u.username = ?`, username)
err = execUpdate(o, `delete pm
from project_member pm
join project p
on pm.project_id = p.project_id
where p.name = ?`, projectName)
if err != nil {
o.Rollback()
log.Println(err)
log.Error(err)
}
err = execUpdate(o, `delete a from access_log a
left join user u on a.user_id = u.user_id
where u.username = ?`, username)
err = execUpdate(o, `delete al
from access_log al
join user u
on al.user_id = u.user_id
where u.username = ?`, username)
if err != nil {
o.Rollback()
log.Println(err)
log.Error(err)
}
err = execUpdate(o, `delete p from project p
left join user u on p.owner_id = u.user_id
where u.username = ?`, username)
err = execUpdate(o, `delete al
from access_log al
join project p
on al.project_id = p.project_id
where p.name = ?`, projectName)
if err != nil {
o.Rollback()
log.Println(err)
log.Error(err)
}
err = execUpdate(o, `delete u from user u
where u.username = ?`, username)
err = execUpdate(o, `delete from project where name = ?`, projectName)
if err != nil {
o.Rollback()
log.Println(err)
log.Error(err)
}
err = execUpdate(o, `delete from user where username = ?`, username)
if err != nil {
o.Rollback()
log.Error(err)
}
o.Commit()
}
@ -379,32 +397,6 @@ func TestGetProject(t *testing.T) {
}
}
func getProjectRole(projectID int64) []models.Role {
o := orm.NewOrm()
var r []models.Role
_, err := o.Raw(`select r.role_id, r.name
from project_role pr
left join role r on pr.role_id = r.role_id
where project_id = ?`, projectID).QueryRows(&r)
if err != nil {
log.Printf("Error occurred in querying project_role: %v", err)
}
return r
}
func TestCheckProjectRoles(t *testing.T) {
r := getProjectRole(currentProject.ProjectID)
if len(r) != 3 {
t.Errorf("The length of project roles is not 3")
}
if r[1].RoleID != 3 {
t.Errorf("The role id does not match, expected: 3, acutal: %d", r[1].RoleID)
}
if r[1].Name != "developer" {
t.Errorf("The name of role id: 3 should be developer, actual:%s", r[1].Name)
}
}
func TestGetAccessLog(t *testing.T) {
queryAccessLog := models.AccessLog{
UserID: currentUser.UserID,
@ -546,20 +538,6 @@ func TestQueryProject(t *testing.T) {
}
}
func getUserProjectRole(projectID int64, userID int) []models.Role {
o := orm.NewOrm()
var r []models.Role
_, err := o.Raw(`select r.role_id, r.name
from user_project_role upr
left join project_role pr on upr.pr_id = pr.pr_id
left join role r on r.role_id = pr.role_id
where pr.project_id = ? and upr.user_id = ?`, projectID, userID).QueryRows(&r)
if err != nil {
log.Fatalf("Error occurred in querying user_project_role: %v", err)
}
return r
}
func TestGetUserProjectRoles(t *testing.T) {
user := *currentUser
r, err := GetUserProjectRoles(user, currentProject.ProjectID)
@ -575,16 +553,6 @@ func TestGetUserProjectRoles(t *testing.T) {
if r[0].Name != "projectAdmin" {
t.Errorf("the expected rolename is: projectAdmin, actual: %s", r[0].Name)
}
user.RoleID = 1
r, err = GetUserProjectRoles(user, currentProject.ProjectID)
if err != nil {
t.Errorf("Error happened in GetUserProjectRole: %v, user: %+v, project Id: %d", err, user, currentProject.ProjectID)
}
//Get the size of current user project role.
if len(r) != 0 {
t.Errorf("The user, id: %d, should not have role id: 1 in project id: %d, actual role list: %v", currentUser.UserID, currentProject.ProjectID, r)
}
}
func TestProjectPermission(t *testing.T) {
@ -610,34 +578,43 @@ func TestQueryRelevantProjects(t *testing.T) {
}
}
func TestAssignUserProjectRole(t *testing.T) {
err := AddUserProjectRole(currentUser.UserID, currentProject.ProjectID, developer)
func TestAddProjectMember(t *testing.T) {
err := AddProjectMember(currentProject.ProjectID, 1, Developer)
if err != nil {
t.Errorf("Error occurred in AddUserProjectRole: %v", err)
t.Errorf("Error occurred in AddProjectMember: %v", err)
}
r := getUserProjectRole(currentProject.ProjectID, currentUser.UserID)
//Get the size of current user project role info.
if len(r) != 2 {
t.Errorf("Expected length of role list is 2, actual: %d", len(r))
roles, err := GetUserProjectRoles(models.User{UserID: 1}, currentProject.ProjectID)
if err != nil {
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
}
if r[1].RoleID != 3 {
t.Errorf("Expected role id of the second role in list is 3, actual: %d", r[1].RoleID)
flag := false
for _, role := range roles {
if role.Name == "developer" {
flag = true
break
}
}
if !flag {
t.Errorf("the user which ID is 1 does not have developer privileges")
}
}
func TestDeleteUserProjectRole(t *testing.T) {
err := DeleteUserProjectRoles(currentUser.UserID, currentProject.ProjectID)
func TestDeleteProjectMember(t *testing.T) {
err := DeleteProjectMember(currentProject.ProjectID, 1)
if err != nil {
t.Errorf("Error occurred in DeleteUserProjectRoles: %v", err)
t.Errorf("Error occurred in DeleteProjectMember: %v", err)
}
r := getUserProjectRole(currentProject.ProjectID, currentUser.UserID)
//Get the size of current user project role.
if len(r) != 0 {
t.Errorf("Expected role list length is 0, actual: %d, role list: %+v", len(r), r)
roles, err := GetUserProjectRoles(models.User{UserID: 1}, currentProject.ProjectID)
if err != nil {
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
}
if len(roles) != 0 {
t.Errorf("delete record failed from table project_member")
}
}

View File

@ -15,23 +15,25 @@
package dao
/*
import (
"github.com/vmware/harbor/models"
"github.com/astaxie/beego/orm"
)
// GetUserByProject gets all members of the project.
func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, error) {
o := orm.NewOrm()
u := []models.User{}
sql := `select
sql := `select
u.user_id, u.username, r.name rolename, r.role_id
from user u left join user_project_role upr
from user u left join user_project_role upr
on u.user_id = upr.user_id
left join project_role pr
left join project_role pr
on pr.pr_id = upr.pr_id
left join role r
left join role r
on r.role_id = pr.role_id
where u.deleted = 0
and pr.project_id = ? `
@ -47,3 +49,4 @@ func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, er
_, err := o.Raw(sql, queryParam).QueryRows(&u)
return u, err
}
*/

View File

@ -40,12 +40,13 @@ func AddProject(project models.Project) error {
o := orm.NewOrm()
p, err := o.Raw("insert into project (owner_id, name, creation_time, deleted, public) values (?, ?, now(), ?, ?)").Prepare()
p, err := o.Raw("insert into project (owner_id, name, creation_time, update_time, deleted, public) values (?, ?, ?, ?, ?, ?)").Prepare()
if err != nil {
return err
}
r, err := p.Exec(project.OwnerID, project.Name, project.Deleted, project.Public)
now := time.Now()
r, err := p.Exec(project.OwnerID, project.Name, now, now, project.Deleted, project.Public)
if err != nil {
return err
}
@ -55,27 +56,7 @@ func AddProject(project models.Project) error {
return err
}
projectAdminRole := models.ProjectRole{ProjectID: projectID, RoleID: models.PROJECTADMIN}
_, err = AddProjectRole(projectAdminRole)
if err != nil {
return err
}
projectDeveloperRole := models.ProjectRole{ProjectID: projectID, RoleID: models.DEVELOPER}
_, err = AddProjectRole(projectDeveloperRole)
if err != nil {
return err
}
projectGuestRole := models.ProjectRole{ProjectID: projectID, RoleID: models.GUEST}
_, err = AddProjectRole(projectGuestRole)
if err != nil {
return err
}
//Add all project roles, after that when assigning a user to a project just update the upr table
err = AddUserProjectRole(project.OwnerID, projectID, models.PROJECTADMIN)
if err != nil {
if err = AddProjectMember(projectID, project.OwnerID, ProjectAdmin); err != nil {
return err
}
@ -103,11 +84,9 @@ func QueryProject(query models.Project) ([]models.Project, error) {
o := orm.NewOrm()
sql := `select distinct
p.project_id, p.owner_id, p.name,p.creation_time, p.public
p.project_id, p.owner_id, p.name,p.creation_time, p.update_time, p.public
from project p
left join project_role pr on p.project_id = pr.project_id
left join user_project_role upr on upr.pr_id = pr.pr_id
left join user u on u.user_id = upr.user_id
left join project_member pm on p.project_id = pm.project_id
where p.deleted = 0 `
queryParam := make([]interface{}, 1)
@ -116,8 +95,7 @@ func QueryProject(query models.Project) ([]models.Project, error) {
sql += ` and p.public = ?`
queryParam = append(queryParam, query.Public)
} else if isAdmin, _ := IsAdminRole(query.UserID); isAdmin == false {
sql += ` and (p.owner_id = ? or u.user_id = ?) `
queryParam = append(queryParam, query.UserID)
sql += ` and (pm.user_id = ?) `
queryParam = append(queryParam, query.UserID)
}
@ -161,60 +139,65 @@ func ProjectExists(nameOrID interface{}) (bool, error) {
}
// GetProjectByID ...
func GetProjectByID(projectID int64) (*models.Project, error) {
func GetProjectByID(id int64) (*models.Project, error) {
o := orm.NewOrm()
sql := `select p.project_id, p.name, u.username as owner_name, p.owner_id, p.creation_time, p.public
sql := `select p.project_id, p.name, u.username as owner_name, p.owner_id, p.creation_time, p.update_time, p.public
from project p left join user u on p.owner_id = u.user_id where p.deleted = 0 and p.project_id = ?`
queryParam := make([]interface{}, 1)
queryParam = append(queryParam, projectID)
queryParam = append(queryParam, id)
p := []models.Project{}
count, err := o.Raw(sql, queryParam).QueryRows(&p)
if err != nil {
return nil, err
} else if count == 0 {
return nil, nil
} else {
return &p[0], nil
}
if count == 0 {
return nil, nil
}
return &p[0], nil
}
// GetProjectByName ...
func GetProjectByName(projectName string) (*models.Project, error) {
func GetProjectByName(name string) (*models.Project, error) {
o := orm.NewOrm()
var p []models.Project
n, err := o.Raw(`select project_id, owner_id, name, deleted, public from project where name = ? and deleted = 0`, projectName).QueryRows(&p)
n, err := o.Raw(`select * from project where name = ? and deleted = 0`, name).QueryRows(&p)
if err != nil {
return nil, err
} else if n == 0 {
return nil, nil
} else {
return &p[0], nil
}
if n == 0 {
return nil, nil
}
return &p[0], nil
}
// GetPermission gets roles that the user has according to the project.
func GetPermission(username, projectName string) (string, error) {
o := orm.NewOrm()
sql := "select r.role_code from role as r " +
"inner join project_role as pr on r.role_id = pr.role_id " +
"inner join user_project_role as ur on pr.pr_id = ur.pr_id " +
"inner join user as u on u.user_id = ur.user_id " +
"inner join project p on p.project_id = pr.project_id " +
"where u.username = ? and p.name = ? and u.deleted = 0 and p.deleted = 0"
sql := `select r.role_code from role as r
inner join project_member as pm on r.role_id = pm.role
inner join user as u on u.user_id = pm.user_id
inner join project p on p.project_id = pm.project_id
where u.username = ? and p.name = ? and u.deleted = 0 and p.deleted = 0`
var r []models.Role
n, err := o.Raw(sql, username, projectName).QueryRows(&r)
if err != nil {
return "", err
} else if n == 0 {
return "", nil
} else {
return r[0].RoleCode, nil
}
if n == 0 {
return "", nil
}
return r[0].RoleCode, nil
}
// ToggleProjectPublicity toggles the publicity of the project.
@ -228,10 +211,11 @@ func ToggleProjectPublicity(projectID int64, publicity int) error {
// QueryRelevantProjects returns all projects that the user is a member of.
func QueryRelevantProjects(userID int) ([]models.Project, error) {
o := orm.NewOrm()
sql := `SELECT distinct p.project_id, p.name, p.public FROM registry.project p
left join project_role pr on p.project_id = pr.project_id
left join user_project_role upr on upr.pr_id = pr.pr_id
where upr.user_id = ? or p.public = 1 and p.deleted = 0`
sql := `select distinct p.project_id, p.name, p.public
from project p
left join project_member pm on p.project_id = pm.project_id
left join user u on u.user_id = pm.user_id
where u.user_id = ? or p.public = 1 and p.deleted = 0`
var res []models.Project
_, err := o.Raw(sql, userID).QueryRows(&res)
if err != nil {

94
dao/projectmember.go Normal file
View File

@ -0,0 +1,94 @@
/*
Copyright (c) 2016 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 dao
import (
"github.com/astaxie/beego/orm"
"github.com/vmware/harbor/models"
)
// AddProjectMember inserts a record to table project_member
func AddProjectMember(projectID int64, userID int, r role) error {
o := orm.NewOrm()
sql := "insert into project_member (project_id, user_id , role) values (?, ?, ?)"
rr, err := getRole(r)
if err != nil {
return err
}
if _, err = o.Raw(sql, projectID, userID, rr.RoleID).Exec(); err != nil {
return err
}
return nil
}
// UpdateProjectMember updates the record in table project_member
func UpdateProjectMember(projectID int64, userID int, r role) error {
o := orm.NewOrm()
sql := "update project_member set role = ? where project_id = ? and user_id = ?"
rr, err := getRole(r)
if err != nil {
return err
}
if _, err := o.Raw(sql, rr.RoleID, projectID, userID).Exec(); err != nil {
return err
}
return nil
}
// DeleteProjectMember delete the record from table project_member
func DeleteProjectMember(projectID int64, userID int) error {
o := orm.NewOrm()
sql := "delete from project_member where project_id = ? and user_id = ?"
if _, err := o.Raw(sql, projectID, userID).Exec(); err != nil {
return err
}
return nil
}
// GetUserByProject gets all members of the project.
func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, error) {
o := orm.NewOrm()
u := []models.User{}
sql := `select u.user_id, u.username, r.name rolename, r.role_id
from user u
join project_member pm
on pm.project_id = ? and u.user_id = pm.user_id
join role r
on pm.role = r.role_id
where u.deleted = 0`
queryParam := make([]interface{}, 1)
queryParam = append(queryParam, projectID)
if queryUser.Username != "" {
sql += " and u.username like ? "
queryParam = append(queryParam, queryUser.Username)
}
sql += ` order by u.user_id `
_, err := o.Raw(sql, queryParam).QueryRows(&u)
return u, err
}

View File

@ -15,6 +15,7 @@
package dao
/*
import (
"github.com/vmware/harbor/models"
@ -37,6 +38,7 @@ func AddProjectRole(projectRole models.ProjectRole) (int64, error) {
return id, err
}
// AddUserProjectRole inserts role information to table project_role and user_project_role.
func AddUserProjectRole(userID int, projectID int64, roleID int) error {
@ -91,3 +93,6 @@ func DeleteUserProjectRoles(userID int, projectID int64) error {
_, err = p.Exec(userID, projectID)
return err
}
*/

View File

@ -18,6 +18,7 @@ package dao
import (
"errors"
"regexp"
"time"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/utils"
@ -34,7 +35,8 @@ func Register(user models.User) (int64, error) {
}
o := orm.NewOrm()
p, err := o.Raw("insert into user (username, password, realname, email, comment, salt) values (?, ?, ?, ?, ?, ?)").Prepare()
p, err := o.Raw("insert into user (username, password, realname, email, comment, salt, sysadmin_flag, creation_time, update_time) values (?, ?, ?, ?, ?, ?, ?, ?, ?)").Prepare()
if err != nil {
return 0, err
}
@ -45,7 +47,8 @@ func Register(user models.User) (int64, error) {
return 0, err
}
r, err := p.Exec(user.Username, utils.Encrypt(user.Password, salt), user.Realname, user.Email, user.Comment, salt)
now := time.Now()
r, err := p.Exec(user.Username, utils.Encrypt(user.Password, salt), user.Realname, user.Email, user.Comment, salt, user.HasAdminRole, now, now)
if err != nil {
return 0, err

View File

@ -16,37 +16,57 @@
package dao
import (
"fmt"
"github.com/vmware/harbor/models"
"github.com/astaxie/beego/orm"
)
type role int
// Start from 2 to guarantee the compatibility with former code
const (
ProjectAdmin role = 2
Developer = 3
Guest = 4
)
var roleList = make(map[role]*models.Role)
// IntToRole is used to convert int to role.
func IntToRole(i int) (r role, err error) {
switch i {
case 2:
r = ProjectAdmin
case 3:
r = Developer
case 4:
r = Guest
default:
err = fmt.Errorf("no role is correspondent with the input: %d", i)
}
return
}
// GetUserProjectRoles returns roles that the user has according to the project.
func GetUserProjectRoles(userQuery models.User, projectID int64) ([]models.Role, error) {
o := orm.NewOrm()
sql := `select distinct r.role_id, r.role_code, r.name
from role r
left join project_role pr on r.role_id = pr.role_id
left join user_project_role upr on pr.pr_id = upr.pr_id
left join user u on u.user_id = upr.user_id
where u.deleted = 0
and u.user_id = ? `
sql := `select *
from role
where role_id =
(
select role
from project_member
where project_id = ? and user_id = ?
)`
queryParam := make([]interface{}, 1)
queryParam = append(queryParam, userQuery.UserID)
if projectID > 0 {
sql += ` and pr.project_id = ? `
queryParam = append(queryParam, projectID)
}
if userQuery.RoleID > 0 {
sql += ` and r.role_id = ? `
queryParam = append(queryParam, userQuery.RoleID)
}
var roleList []models.Role
_, err := o.Raw(sql, queryParam).QueryRows(&roleList)
_, err := o.Raw(sql, projectID, userQuery.UserID).QueryRows(&roleList)
if err != nil {
return nil, err
@ -56,11 +76,54 @@ func GetUserProjectRoles(userQuery models.User, projectID int64) ([]models.Role,
// IsAdminRole returns whether the user is admin.
func IsAdminRole(userID int) (bool, error) {
//role_id == 1 means the user is system admin
userQuery := models.User{UserID: userID, RoleID: models.SYSADMIN}
adminRoleList, err := GetUserProjectRoles(userQuery, 0)
user, err := GetUser(models.User{UserID: userID})
if err != nil {
return false, err
}
return len(adminRoleList) > 0, nil
if user == nil {
return false, nil
}
return user.HasAdminRole == 1, nil
}
func getRole(r role) (*models.Role, error) {
if roleList[r] != nil {
return roleList[r], nil
}
o := orm.NewOrm()
var roles []*models.Role
sql := "select role_id, role_code, name, role_mask from role"
_, err := o.Raw(sql).QueryRows(&roles)
if err != nil {
return nil, err
}
for _, rr := range roles {
if rr.RoleCode == "MDRWS" {
roleList[ProjectAdmin] = rr
continue
}
if rr.RoleCode == "RWS" {
roleList[Developer] = rr
continue
}
if rr.RoleCode == "RS" {
roleList[Guest] = rr
continue
}
}
if roleList[r] == nil {
return nil, fmt.Errorf("unsupported role type: %v", r)
}
return roleList[r], nil
}

View File

@ -22,8 +22,8 @@ import (
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/utils"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"github.com/vmware/harbor/utils/log"
)
// GetUser ...
@ -31,12 +31,8 @@ func GetUser(query models.User) (*models.User, error) {
o := orm.NewOrm()
sql := `select user_id, username, email, realname, reset_uuid, salt,
ifnull((select pr.role_id
from project_role pr
left join user_project_role upr on upr.pr_id = pr.pr_id
where pr.role_id = 1
and upr.user_id = u.user_id),0) as has_admin_role
sql := `select user_id, username, email, realname, comment, reset_uuid, salt,
sysadmin_flag, creation_time, update_time
from user u
where deleted = 0 `
queryParam := make([]interface{}, 1)
@ -60,51 +56,52 @@ func GetUser(query models.User) (*models.User, error) {
if err != nil {
return nil, err
} else if n == 0 {
return nil, nil
} else {
return &u[0], nil
}
if n == 0 {
return nil, nil
}
return &u[0], nil
}
// LoginByDb is used for user to login with database auth mode.
func LoginByDb(auth models.AuthModel) (*models.User, error) {
query := models.User{Username: auth.Principal, Email: auth.Principal}
o := orm.NewOrm()
var u []models.User
n, err := o.Raw(`select username from user where (username = ? or email = ?)`, query.Username, query.Email).QueryRows(&u)
var users []models.User
n, err := o.Raw(`select * from user where (username = ? or email = ?)`,
auth.Principal, auth.Principal).QueryRows(&users)
if err != nil {
return nil, err
} else if n == 0 {
beego.Warning("User does not exist. Principal:", auth.Principal)
}
if n == 0 {
return nil, nil
} else {
u[0].Password = auth.Password
return CheckUserPassword(u[0])
}
user := users[0]
if user.Password != utils.Encrypt(auth.Password, user.Salt) {
return nil, nil
}
return &user, nil
}
// ListUsers lists all users according to different conditions.
func ListUsers(query models.User) ([]models.User, error) {
o := orm.NewOrm()
u := []models.User{}
sql := `select u.user_id, u.username, u.email, ifnull((select pr.role_id
from project_role pr
left join user_project_role upr on upr.pr_id = pr.pr_id
where pr.role_id = 1
and upr.user_id = u.user_id),0) as has_admin_role
from user u
where u.deleted = 0 and u.user_id != 1 `
sql := `select user_id, username, email, realname, comment, reset_uuid, salt,
sysadmin_flag, creation_time, update_time
from user u
where u.deleted = 0 and u.user_id != 1 `
queryParam := make([]interface{}, 1)
if query.Username != "" {
sql += ` and u.username like ? `
sql += ` and username like ? `
queryParam = append(queryParam, query.Username)
}
sql += ` order by u.user_id desc `
sql += ` order by user_id desc `
_, err := o.Raw(sql, queryParam).QueryRows(&u)
return u, err
@ -112,59 +109,76 @@ func ListUsers(query models.User) ([]models.User, error) {
// ToggleUserAdminRole gives a user admim role.
func ToggleUserAdminRole(u models.User) error {
projectRole := models.ProjectRole{PrID: 1} //admin project role
o := orm.NewOrm()
var pr []models.ProjectRole
n, err := o.Raw(`select user_id from user_project_role where user_id = ? and pr_id = ? `, u.UserID, projectRole.PrID).QueryRows(&pr)
var user models.User
err := o.Raw(`select sysadmin_flag from user where user_id = ?`, u.UserID).QueryRow(&user)
if err != nil {
return err
}
var sql string
if n == 0 {
sql = `insert into user_project_role (user_id, pr_id) values (?, ?)`
var sysAdminFlag int
if user.HasAdminRole == 0 {
sysAdminFlag = 1
} else {
sql = `delete from user_project_role where user_id = ? and pr_id = ?`
sysAdminFlag = 0
}
p, err := o.Raw(sql).Prepare()
sql := `update user set sysadmin_flag = ? where user_id = ?`
r, err := o.Raw(sql, sysAdminFlag, u.UserID).Exec()
if err != nil {
return err
}
defer p.Close()
_, err = p.Exec(u.UserID, projectRole.PrID)
return err
if _, err := r.RowsAffected(); err != nil {
return err
}
return nil
}
// ChangeUserPassword ...
func ChangeUserPassword(u models.User, oldPassword ...string) error {
func ChangeUserPassword(u models.User, oldPassword ...string) (err error) {
o := orm.NewOrm()
var err error
var r sql.Result
if len(oldPassword) == 0 {
//In some cases, it may no need to check old password, just as Linux change password policies.
_, err = o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID).Exec()
} else if len(oldPassword) == 1 {
r, err = o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID).Exec()
if err != nil {
return err
}
c, err := r.RowsAffected()
if err != nil {
return err
}
if c == 0 {
return errors.New("No record has been modified, change password failed.")
}
return nil
}
if len(oldPassword) == 1 {
r, err = o.Raw(`update user set password=?, salt=? where user_id=? and password = ?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID, utils.Encrypt(oldPassword[0], u.Salt)).Exec()
if err != nil {
return err
}
count, err := r.RowsAffected()
c, err := r.RowsAffected()
if err != nil {
return err
}
if count == 0 {
return errors.New("No record be changed, change password failed.")
if c == 0 {
return errors.New("No record has been modified, change password failed.")
}
} else {
return errors.New("Wrong numbers of params.")
return nil
}
return err
return errors.New("Wrong numbers of params.")
}
// ResetUserPassword ...
@ -181,7 +195,7 @@ func ResetUserPassword(u models.User) error {
if count == 0 {
return errors.New("No record be changed, reset password failed.")
}
return err
return nil
}
// UpdateUserResetUUID ...
@ -224,12 +238,14 @@ func CheckUserPassword(query models.User) (*models.User, error) {
if err != nil {
return nil, err
} else if n == 0 {
beego.Warning("User principal does not match password. Current:", currentUser)
return nil, nil
} else {
return &user[0], nil
}
if n == 0 {
log.Warning("User principal does not match password. Current:", currentUser)
return nil, nil
}
return &user[0], nil
}
// DeleteUser ...

View File

@ -32,4 +32,6 @@ type Project struct {
Public int `orm:"column(public)"`
//This field does not have correspondent column in DB, this is just for UI to disable button
Togglable bool
UpdateTime time.Time `orm:"update_time" json:"update_time"`
}

View File

@ -15,6 +15,7 @@
package models
/*
const (
//SYSADMIN system administrator
SYSADMIN = 1
@ -25,14 +26,17 @@ const (
//GUEST guest
GUEST = 4
)
*/
// Role holds the details of a role.
type Role struct {
RoleID int `json:"role_id" orm:"column(role_id)"`
RoleCode string `json:"role_code" orm:"column(role_code)"`
Name string `json:"role_name" orm:"column(name)"`
RoleID int `orm:"column(role_id)" json:"role_id"`
RoleCode string `orm:"column(role_code)" json:"role_code"`
Name string `orm:"column(name)" json:"role_name"`
RoleMask int `orm:"role_mask" json:"role_mask"`
}
/*
// ProjectRole holds information about the relationship of project and role.
type ProjectRole struct {
PrID int `orm:"column(pr_id)" json:"PrId"`
@ -46,3 +50,4 @@ type UserProjectRole struct {
UserID int `orm:"column(user_id)" json:"UserId"`
PrID int64 `orm:"column(pr_id)" json:"PrId"`
}
*/

View File

@ -15,6 +15,10 @@
package models
import (
"time"
)
// User holds the details of a user.
type User struct {
UserID int `orm:"column(user_id)" json:"UserId"`
@ -27,7 +31,10 @@ type User struct {
Rolename string
RoleID int `json:"RoleId"`
RoleList []Role
HasAdminRole int
HasAdminRole int `orm:"column(sysadmin_flag)"`
ResetUUID string `orm:"column(reset_uuid)" json:"ResetUuid"`
Salt string `orm:"column(salt)"`
CreationTime time.Time `orm:"creation_time" json:"creation_time"`
UpdateTime time.Time `orm:"update_time" json:"update_time"`
}