delete column user_id from table accesslog

This commit is contained in:
Wenkai Yin 2017-05-03 10:43:57 +08:00
parent f7a4a21066
commit 3be9cca0f5
11 changed files with 144 additions and 118 deletions

View File

@ -99,7 +99,7 @@ insert into project_member (project_id, user_id, role, creation_time, update_tim
create table access_log ( create table access_log (
log_id int NOT NULL AUTO_INCREMENT, log_id int NOT NULL AUTO_INCREMENT,
user_id int NOT NULL, username varchar (32) NOT NULL,
project_id int NOT NULL, project_id int NOT NULL,
repo_name varchar (256), repo_name varchar (256),
repo_tag varchar (128), repo_tag varchar (128),
@ -108,7 +108,6 @@ create table access_log (
op_time timestamp, op_time timestamp,
primary key (log_id), primary key (log_id),
INDEX pid_optime (project_id, op_time), INDEX pid_optime (project_id, op_time),
FOREIGN KEY (user_id) REFERENCES user(user_id),
FOREIGN KEY (project_id) REFERENCES project (project_id) FOREIGN KEY (project_id) REFERENCES project (project_id)
); );

View File

@ -96,14 +96,13 @@ insert into project_member (project_id, user_id, role, creation_time, update_tim
create table access_log ( create table access_log (
log_id INTEGER PRIMARY KEY, log_id INTEGER PRIMARY KEY,
user_id int NOT NULL, username varchar (32) NOT NULL,
project_id int NOT NULL, project_id int NOT NULL,
repo_name varchar (256), repo_name varchar (256),
repo_tag varchar (128), repo_tag varchar (128),
GUID varchar(64), GUID varchar(64),
operation varchar(20) NOT NULL, operation varchar(20) NOT NULL,
op_time timestamp, op_time timestamp,
FOREIGN KEY (user_id) REFERENCES user(user_id),
FOREIGN KEY (project_id) REFERENCES project (project_id) FOREIGN KEY (project_id) REFERENCES project (project_id)
); );

View File

@ -16,7 +16,6 @@ package dao
import ( import (
"strings" "strings"
"time"
"github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/common/utils/log"
@ -25,17 +24,7 @@ import (
// AddAccessLog persists the access logs // AddAccessLog persists the access logs
func AddAccessLog(accessLog models.AccessLog) error { func AddAccessLog(accessLog models.AccessLog) error {
o := GetOrmer() o := GetOrmer()
p, err := o.Raw(`insert into access_log _, err := o.Insert(&accessLog)
(user_id, project_id, repo_name, repo_tag, guid, operation, op_time)
values (?, ?, ?, ?, ?, ?, ?)`).Prepare()
if err != nil {
return err
}
defer p.Close()
_, err = p.Exec(accessLog.UserID, accessLog.ProjectID, accessLog.RepoName, accessLog.RepoTag,
accessLog.GUID, accessLog.Operation, time.Now())
return err return err
} }
@ -49,14 +38,6 @@ func GetTotalOfAccessLogs(query models.AccessLog) (int64, error) {
where al.project_id = ?` where al.project_id = ?`
queryParam = append(queryParam, query.ProjectID) queryParam = append(queryParam, query.ProjectID)
if query.Username != "" {
sql = `select count(*) from access_log al
left join user u
on al.user_id = u.user_id
where al.project_id = ? and u.username like ? `
queryParam = append(queryParam, "%"+escape(query.Username)+"%")
}
sql += genFilterClauses(query, &queryParam) sql += genFilterClauses(query, &queryParam)
var total int64 var total int64
@ -71,19 +52,12 @@ func GetAccessLogs(query models.AccessLog, limit, offset int64) ([]models.Access
o := GetOrmer() o := GetOrmer()
queryParam := []interface{}{} queryParam := []interface{}{}
sql := `select al.log_id, u.username, al.repo_name, sql := `select al.log_id, al.username, al.repo_name,
al.repo_tag, al.operation, al.op_time al.repo_tag, al.operation, al.op_time
from access_log al from access_log al
left join user u
on al.user_id = u.user_id
where al.project_id = ? ` where al.project_id = ? `
queryParam = append(queryParam, query.ProjectID) queryParam = append(queryParam, query.ProjectID)
if query.Username != "" {
sql += ` and u.username like ? `
queryParam = append(queryParam, "%"+escape(query.Username)+"%")
}
sql += genFilterClauses(query, &queryParam) sql += genFilterClauses(query, &queryParam)
sql += ` order by al.op_time desc ` sql += ` order by al.op_time desc `
@ -102,6 +76,11 @@ func GetAccessLogs(query models.AccessLog, limit, offset int64) ([]models.Access
func genFilterClauses(query models.AccessLog, queryParam *[]interface{}) string { func genFilterClauses(query models.AccessLog, queryParam *[]interface{}) string {
sql := "" sql := ""
if query.Username != "" {
sql += ` and al.username like ? `
*queryParam = append(*queryParam, "%"+escape(query.Username)+"%")
}
if query.Operation != "" { if query.Operation != "" {
sql += ` and al.operation = ? ` sql += ` and al.operation = ? `
*queryParam = append(*queryParam, query.Operation) *queryParam = append(*queryParam, query.Operation)
@ -141,42 +120,28 @@ func genFilterClauses(query models.AccessLog, queryParam *[]interface{}) string
return sql return sql
} }
// AccessLog ...
func AccessLog(username, projectName, repoName, repoTag, action string) error {
o := GetOrmer()
sql := "insert into access_log (user_id, project_id, repo_name, repo_tag, operation, op_time) " +
"select (select user_id as user_id from user where username=?), " +
"(select project_id as project_id from project where name=?), ?, ?, ?, ? "
_, err := o.Raw(sql, username, projectName, repoName, repoTag, action, time.Now()).Exec()
if err != nil {
log.Errorf("error in AccessLog: %v ", err)
}
return err
}
//GetRecentLogs returns recent logs according to parameters //GetRecentLogs returns recent logs according to parameters
func GetRecentLogs(userID, linesNum int, startTime, endTime string) ([]models.AccessLog, error) { func GetRecentLogs(username string, linesNum int, startTime, endTime string) ([]models.AccessLog, error) {
logs := []models.AccessLog{} logs := []models.AccessLog{}
isAdmin, err := IsAdminRole(userID) isAdmin, err := IsAdminRole(username)
if err != nil { if err != nil {
return logs, err return logs, err
} }
queryParam := []interface{}{} queryParam := []interface{}{}
sql := `select log_id, access_log.user_id, project_id, repo_name, repo_tag, GUID, operation, op_time, username sql := `select log_id, username, project_id, repo_name, repo_tag, GUID, operation, op_time
from access_log from access_log `
join user
on access_log.user_id=user.user_id `
hasWhere := false hasWhere := false
if !isAdmin { if !isAdmin {
sql += ` where project_id in sql += ` where project_id in
(select distinct project_id (select distinct project_id
from project_member from project_member pm
where user_id = ?) ` join user u
queryParam = append(queryParam, userID) on pm.user_id = u.user_id
where u.username = ?) `
queryParam = append(queryParam, username)
hasWhere = true hasWhere = true
} }

View File

@ -73,11 +73,8 @@ func clearUp(username string) {
err = execUpdate(o, `delete err = execUpdate(o, `delete
from access_log from access_log
where user_id = ( where username = ?
select user_id `, username)
from user
where username = ?
)`, username)
if err != nil { if err != nil {
o.Rollback() o.Rollback()
log.Error(err) log.Error(err)
@ -559,8 +556,22 @@ func TestGetProject(t *testing.T) {
} }
func TestGetAccessLog(t *testing.T) { func TestGetAccessLog(t *testing.T) {
accessLog := models.AccessLog{
Username: currentUser.Username,
ProjectID: currentProject.ProjectID,
RepoName: currentProject.Name + "/",
RepoTag: "N/A",
GUID: "N/A",
Operation: "create",
OpTime: time.Now(),
}
if err := AddAccessLog(accessLog); err != nil {
t.Errorf("failed to add access log: %v", err)
}
queryAccessLog := models.AccessLog{ queryAccessLog := models.AccessLog{
UserID: currentUser.UserID, Username: currentUser.Username,
ProjectID: currentProject.ProjectID, ProjectID: currentProject.ProjectID,
} }
accessLogs, err := GetAccessLogs(queryAccessLog, 1000, 0) accessLogs, err := GetAccessLogs(queryAccessLog, 1000, 0)
@ -577,7 +588,7 @@ func TestGetAccessLog(t *testing.T) {
func TestGetTotalOfAccessLogs(t *testing.T) { func TestGetTotalOfAccessLogs(t *testing.T) {
queryAccessLog := models.AccessLog{ queryAccessLog := models.AccessLog{
UserID: currentUser.UserID, Username: currentUser.Username,
ProjectID: currentProject.ProjectID, ProjectID: currentProject.ProjectID,
} }
total, err := GetTotalOfAccessLogs(queryAccessLog) total, err := GetTotalOfAccessLogs(queryAccessLog)
@ -594,7 +605,7 @@ func TestAddAccessLog(t *testing.T) {
var err error var err error
var accessLogList []models.AccessLog var accessLogList []models.AccessLog
accessLog := models.AccessLog{ accessLog := models.AccessLog{
UserID: currentUser.UserID, Username: currentUser.Username,
ProjectID: currentProject.ProjectID, ProjectID: currentProject.ProjectID,
RepoName: currentProject.Name + "/", RepoName: currentProject.Name + "/",
RepoTag: repoTag, RepoTag: repoTag,
@ -621,47 +632,38 @@ func TestAddAccessLog(t *testing.T) {
} }
} }
func TestAccessLog(t *testing.T) {
var err error
var accessLogList []models.AccessLog
accessLog := models.AccessLog{
UserID: currentUser.UserID,
ProjectID: currentProject.ProjectID,
RepoName: currentProject.Name + "/",
RepoTag: repoTag2,
Operation: "create",
}
err = AccessLog(currentUser.Username, currentProject.Name, currentProject.Name+"/", repoTag2, "create")
if err != nil {
t.Errorf("Error occurred in AccessLog: %v", err)
}
accessLogList, err = GetAccessLogs(accessLog, 1000, 0)
if err != nil {
t.Errorf("Error occurred in GetAccessLog: %v", err)
}
if len(accessLogList) != 1 {
t.Errorf("The length of accesslog list should be 1, actual: %d", len(accessLogList))
}
if accessLogList[0].RepoName != projectName+"/" {
t.Errorf("The project name does not match, expected: %s, actual: %s", projectName+"/", accessLogList[0].RepoName)
}
if accessLogList[0].RepoTag != repoTag2 {
t.Errorf("The repo tag does not match, expected: %s, actual: %s", repoTag2, accessLogList[0].RepoTag)
}
}
func TestCountPull(t *testing.T) { func TestCountPull(t *testing.T) {
var err error var err error
err = AccessLog(currentUser.Username, currentProject.Name, currentProject.Name+"/tomcat", repoTag2, "pull") if err = AddAccessLog(models.AccessLog{
if err != nil { Username: currentUser.Username,
ProjectID: currentProject.ProjectID,
RepoName: currentProject.Name + "/tomcat",
RepoTag: repoTag2,
Operation: "pull",
OpTime: time.Now(),
}); err != nil {
t.Errorf("Error occurred in AccessLog: %v", err) t.Errorf("Error occurred in AccessLog: %v", err)
} }
err = AccessLog(currentUser.Username, currentProject.Name, currentProject.Name+"/tomcat", repoTag2, "pull")
if err != nil { if err = AddAccessLog(models.AccessLog{
Username: currentUser.Username,
ProjectID: currentProject.ProjectID,
RepoName: currentProject.Name + "/tomcat",
RepoTag: repoTag2,
Operation: "pull",
OpTime: time.Now(),
}); err != nil {
t.Errorf("Error occurred in AccessLog: %v", err) t.Errorf("Error occurred in AccessLog: %v", err)
} }
err = AccessLog(currentUser.Username, currentProject.Name, currentProject.Name+"/tomcat", repoTag2, "pull")
if err != nil { if err = AddAccessLog(models.AccessLog{
Username: currentUser.Username,
ProjectID: currentProject.ProjectID,
RepoName: currentProject.Name + "/tomcat",
RepoTag: repoTag2,
Operation: "pull",
OpTime: time.Now(),
}); err != nil {
t.Errorf("Error occurred in AccessLog: %v", err) t.Errorf("Error occurred in AccessLog: %v", err)
} }
@ -973,7 +975,7 @@ func TestChangeUserProfile(t *testing.T) {
} }
func TestGetRecentLogs(t *testing.T) { func TestGetRecentLogs(t *testing.T) {
logs, err := GetRecentLogs(currentUser.UserID, 10, "2016-05-13 00:00:00", time.Now().String()) logs, err := GetRecentLogs(currentUser.Username, 10, "2016-05-13 00:00:00", time.Now().String())
if err != nil { if err != nil {
t.Errorf("error occured in getting recent logs, error: %v", err) t.Errorf("error occured in getting recent logs, error: %v", err)
} }

View File

@ -45,13 +45,7 @@ func AddProject(project models.Project) (int64, error) {
return 0, err return 0, err
} }
if err = AddProjectMember(projectID, project.OwnerID, models.PROJECTADMIN); err != nil { err = AddProjectMember(projectID, project.OwnerID, models.PROJECTADMIN)
return projectID, err
}
accessLog := models.AccessLog{UserID: project.OwnerID, ProjectID: projectID, RepoName: project.Name + "/", RepoTag: "N/A", GUID: "N/A", Operation: "create", OpTime: time.Now()}
err = AddAccessLog(accessLog)
return projectID, err return projectID, err
} }

View File

@ -21,17 +21,16 @@ import (
// AccessLog holds information about logs which are used to record the actions that user take to the resourses. // AccessLog holds information about logs which are used to record the actions that user take to the resourses.
type AccessLog struct { type AccessLog struct {
LogID int `orm:"pk;auto;column(log_id)" json:"log_id"` LogID int `orm:"pk;auto;column(log_id)" json:"log_id"`
UserID int `orm:"column(user_id)" json:"user_id"` Username string `orm:"column(username)" json:"username"`
ProjectID int64 `orm:"column(project_id)" json:"project_id"` ProjectID int64 `orm:"column(project_id)" json:"project_id"`
RepoName string `orm:"column(repo_name)" json:"repo_name"` RepoName string `orm:"column(repo_name)" json:"repo_name"`
RepoTag string `orm:"column(repo_tag)" json:"repo_tag"` RepoTag string `orm:"column(repo_tag)" json:"repo_tag"`
GUID string `orm:"column(GUID)" json:"guid"` GUID string `orm:"column(GUID)" json:"guid"`
Operation string `orm:"column(operation)" json:"operation"` Operation string `orm:"column(operation)" json:"operation"`
OpTime time.Time `orm:"column(op_time)" json:"op_time"` OpTime time.Time `orm:"column(op_time)" json:"op_time"`
Username string `json:"username"` Keywords string `orm:"-" json:"keywords"`
Keywords string `json:"keywords"` BeginTime time.Time `orm:"-"`
BeginTime time.Time BeginTimestamp int64 `orm:"-" json:"begin_timestamp"`
BeginTimestamp int64 `json:"begin_timestamp"` EndTime time.Time `orm:"-"`
EndTime time.Time EndTimestamp int64 `orm:"-" json:"end_timestamp"`
EndTimestamp int64 `json:"end_timestamp"`
} }

View File

@ -19,10 +19,10 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/vmware/harbor/src/common/api"
"github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/common/utils/log"
"github.com/vmware/harbor/src/common/api"
) )
//LogAPI handles request api/logs //LogAPI handles request api/logs
@ -75,8 +75,16 @@ func (l *LogAPI) Get() {
linesNum = 10 linesNum = 10
} }
user, err := dao.GetUser(models.User{
UserID: l.userID,
})
if err != nil {
log.Errorf("failed to get user by user ID %d: %v", l.userID, err)
l.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
var logList []models.AccessLog var logList []models.AccessLog
logList, err = dao.GetRecentLogs(l.userID, linesNum, startTime, endTime) logList, err = dao.GetRecentLogs(user.Username, linesNum, startTime, endTime)
if err != nil { if err != nil {
log.Errorf("Get recent logs error, err: %v", err) log.Errorf("Get recent logs error, err: %v", err)
l.CustomAbort(http.StatusInternalServerError, "Internal error") l.CustomAbort(http.StatusInternalServerError, "Internal error")

View File

@ -118,6 +118,29 @@ func (p *ProjectAPI) Post() {
} }
return return
} }
user, err := dao.GetUser(models.User{
UserID: p.userID,
})
if err != nil {
log.Errorf("failed to get user by ID %d: %v", p.userID, err)
p.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
accessLog := models.AccessLog{
Username: user.Username,
ProjectID: projectID,
RepoName: project.Name + "/",
RepoTag: "N/A",
GUID: "N/A",
Operation: "create",
OpTime: time.Now(),
}
if err = dao.AddAccessLog(accessLog); err != nil {
log.Errorf("failed to add access log: %v", err)
p.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
p.Redirect(http.StatusCreated, strconv.FormatInt(projectID, 10)) p.Redirect(http.StatusCreated, strconv.FormatInt(projectID, 10))
} }
@ -200,12 +223,21 @@ func (p *ProjectAPI) Delete() {
} }
go func() { go func() {
user, err := dao.GetUser(models.User{
UserID: userID,
})
if err != nil {
log.Errorf("failed to get user by ID %d: %v", userID, err)
p.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if err := dao.AddAccessLog(models.AccessLog{ if err := dao.AddAccessLog(models.AccessLog{
UserID: userID, Username: user.Username,
ProjectID: p.projectID, ProjectID: p.projectID,
RepoName: p.projectName + "/", RepoName: p.projectName + "/",
RepoTag: "N/A", RepoTag: "N/A",
Operation: "delete", Operation: "delete",
OpTime: time.Now(),
}); err != nil { }); err != nil {
log.Errorf("failed to add access log: %v", err) log.Errorf("failed to add access log: %v", err)
} }

View File

@ -267,7 +267,19 @@ func (ra *RepositoryAPI) Delete() {
go TriggerReplicationByRepository(repoName, []string{t}, models.RepOpDelete) go TriggerReplicationByRepository(repoName, []string{t}, models.RepOpDelete)
go func(tag string) { go func(tag string) {
if err := dao.AccessLog(user, projectName, repoName, tag, "delete"); err != nil { project, err := dao.GetProjectByName(projectName)
if err != nil {
log.Errorf("failed to get project by name %s: %v", projectName, err)
return
}
if err := dao.AddAccessLog(models.AccessLog{
Username: user,
ProjectID: project.ProjectID,
RepoName: repoName,
RepoTag: tag,
Operation: "delete",
OpTime: time.Now(),
}); err != nil {
log.Errorf("failed to add access log: %v", err) log.Errorf("failed to add access log: %v", err)
} }
}(t) }(t)

View File

@ -18,6 +18,7 @@ import (
"encoding/json" "encoding/json"
"regexp" "regexp"
"strings" "strings"
"time"
"github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/models"
@ -65,7 +66,19 @@ func (n *NotificationHandler) Post() {
} }
go func() { go func() {
if err := dao.AccessLog(user, project, repository, tag, action); err != nil { pro, err := dao.GetProjectByName(project)
if err != nil {
log.Errorf("failed to get project by name %s: %v", project, err)
return
}
if err := dao.AddAccessLog(models.AccessLog{
Username: user,
ProjectID: pro.ProjectID,
RepoName: repository,
RepoTag: tag,
Operation: action,
OpTime: time.Now(),
}); err != nil {
log.Errorf("failed to add access log: %v", err) log.Errorf("failed to add access log: %v", err)
} }
}() }()

View File

@ -41,3 +41,6 @@ Changelog for harbor database schema
## 1.2.0 ## 1.2.0
- delete column `owner_id` from table `repository` - delete column `owner_id` from table `repository`
- delete column `user_id` from table `access_log`
- delete foreign key (user_id) references user(user_id)from table `access_log`
- add column `username` varchar (32) to table `access_log`