2016-02-01 12:59:10 +01:00
/ *
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 .
* /
2016-02-26 11:54:14 +01:00
2016-02-01 12:59:10 +01:00
package dao
import (
"strings"
2016-06-06 11:53:36 +02:00
2016-02-01 12:59:10 +01:00
"github.com/vmware/harbor/models"
2016-04-21 18:28:59 +02:00
"github.com/vmware/harbor/utils/log"
2016-02-01 12:59:10 +01:00
)
2016-02-26 11:13:13 +01:00
// AddAccessLog persists the access logs
2016-02-01 12:59:10 +01:00
func AddAccessLog ( accessLog models . AccessLog ) error {
2016-05-20 10:36:10 +02:00
o := GetOrmer ( )
2016-02-01 12:59:10 +01:00
p , err := o . Raw ( ` insert into access_log
2016-04-21 18:28:59 +02:00
( user_id , project_id , repo_name , repo_tag , guid , operation , op_time )
values ( ? , ? , ? , ? , ? , ? , now ( ) ) ` ) . Prepare ( )
2016-02-01 12:59:10 +01:00
if err != nil {
return err
}
defer p . Close ( )
2016-04-21 18:28:59 +02:00
_ , err = p . Exec ( accessLog . UserID , accessLog . ProjectID , accessLog . RepoName , accessLog . RepoTag , accessLog . GUID , accessLog . Operation )
2016-02-01 12:59:10 +01:00
return err
}
2016-02-26 11:13:13 +01:00
//GetAccessLogs gets access logs according to different conditions
2016-07-31 13:58:33 +02:00
func GetAccessLogs ( query models . AccessLog , limit , offset int64 ) ( [ ] models . AccessLog , int64 , error ) {
2016-05-20 10:36:10 +02:00
o := GetOrmer ( )
2016-07-31 13:58:33 +02:00
condition := ` from access_log a left join user u on a . user_id = u . user_id
2016-02-01 12:59:10 +01:00
where a . project_id = ? `
queryParam := make ( [ ] interface { } , 1 )
2016-07-31 13:58:33 +02:00
queryParam = append ( queryParam , query . ProjectID )
2016-02-01 12:59:10 +01:00
2016-07-31 13:58:33 +02:00
if query . UserID != 0 {
condition += ` and a.user_id = ? `
queryParam = append ( queryParam , query . UserID )
2016-02-01 12:59:10 +01:00
}
2016-07-31 13:58:33 +02:00
if query . Operation != "" {
condition += ` and a.operation = ? `
queryParam = append ( queryParam , query . Operation )
2016-02-01 12:59:10 +01:00
}
2016-07-31 13:58:33 +02:00
if query . Username != "" {
condition += ` and u.username like ? `
queryParam = append ( queryParam , query . Username )
2016-02-01 12:59:10 +01:00
}
2016-07-31 13:58:33 +02:00
if query . RepoName != "" {
condition += ` and a.repo_name = ? `
queryParam = append ( queryParam , query . RepoName )
2016-05-03 10:54:01 +02:00
}
2016-07-31 13:58:33 +02:00
if query . RepoTag != "" {
condition += ` and a.repo_tag = ? `
queryParam = append ( queryParam , query . RepoTag )
2016-05-03 10:54:01 +02:00
}
2016-07-31 13:58:33 +02:00
if query . Keywords != "" {
condition += ` and a.operation in ( `
keywordList := strings . Split ( query . Keywords , "/" )
2016-02-01 12:59:10 +01:00
num := len ( keywordList )
for i := 0 ; i < num ; i ++ {
if keywordList [ i ] != "" {
if i == num - 1 {
2016-07-31 13:58:33 +02:00
condition += ` ?) `
2016-02-01 12:59:10 +01:00
} else {
2016-07-31 13:58:33 +02:00
condition += ` ?, `
2016-02-01 12:59:10 +01:00
}
queryParam = append ( queryParam , keywordList [ i ] )
}
}
}
2016-07-31 13:58:33 +02:00
if query . BeginTimestamp > 0 {
condition += ` and a.op_time >= ? `
queryParam = append ( queryParam , query . BeginTime )
2016-02-01 12:59:10 +01:00
}
2016-07-31 13:58:33 +02:00
if query . EndTimestamp > 0 {
condition += ` and a.op_time <= ? `
queryParam = append ( queryParam , query . EndTime )
}
condition += ` order by a.op_time desc `
totalSQL := ` select count(*) ` + condition
logs := [ ] models . AccessLog { }
var total int64
if err := o . Raw ( totalSQL , queryParam ) . QueryRow ( & total ) ; err != nil {
return logs , 0 , err
2016-02-01 12:59:10 +01:00
}
2016-07-31 13:58:33 +02:00
condition = paginateForRawSQL ( condition , limit , offset )
2016-02-01 12:59:10 +01:00
2016-07-31 13:58:33 +02:00
recordsSQL := ` select a.log_id, u.username, a.repo_name, a.repo_tag, a.operation, a.op_time ` + condition
_ , err := o . Raw ( recordsSQL , queryParam ) . QueryRows ( & logs )
2016-02-01 12:59:10 +01:00
if err != nil {
2016-07-31 13:58:33 +02:00
return logs , 0 , err
2016-02-01 12:59:10 +01:00
}
2016-07-31 13:58:33 +02:00
return logs , total , nil
2016-02-01 12:59:10 +01:00
}
2016-04-22 14:26:28 +02:00
// AccessLog ...
2016-04-21 18:28:59 +02:00
func AccessLog ( username , projectName , repoName , repoTag , action string ) error {
2016-05-20 10:36:10 +02:00
o := GetOrmer ( )
2016-04-21 18:28:59 +02:00
sql := "insert into access_log (user_id, project_id, repo_name, repo_tag, operation, op_time) " +
2016-02-01 12:59:10 +01:00
"select (select user_id as user_id from user where username=?), " +
2016-04-21 18:28:59 +02:00
"(select project_id as project_id from project where name=?), ?, ?, ?, now() "
_ , err := o . Raw ( sql , username , projectName , repoName , repoTag , action ) . Exec ( )
2016-02-01 12:59:10 +01:00
2016-04-21 18:28:59 +02:00
if err != nil {
log . Errorf ( "error in AccessLog: %v " , err )
}
2016-02-01 12:59:10 +01:00
return err
}
2016-05-20 10:56:12 +02:00
//GetRecentLogs returns recent logs according to parameters
2016-05-30 11:11:39 +02:00
func GetRecentLogs ( userID , linesNum int , startTime , endTime string ) ( [ ] models . AccessLog , error ) {
2016-05-20 10:56:12 +02:00
var recentLogList [ ] models . AccessLog
queryParam := make ( [ ] interface { } , 1 )
2016-05-30 11:11:39 +02:00
2016-06-01 06:27:26 +02:00
sql := "select log_id, access_log.user_id, project_id, repo_name, repo_tag, GUID, operation, op_time, username from access_log left join user on access_log.user_id=user.user_id where project_id in (select distinct project_id from project_member where user_id = ?)"
2016-05-30 11:11:39 +02:00
queryParam = append ( queryParam , userID )
2016-05-31 11:38:51 +02:00
if startTime != "" {
2016-05-30 11:11:39 +02:00
sql += " and op_time >= ?"
queryParam = append ( queryParam , startTime )
}
2016-05-31 11:38:51 +02:00
if endTime != "" {
2016-05-30 11:11:39 +02:00
sql += " and op_time <= ?"
queryParam = append ( queryParam , endTime )
}
sql += " order by op_time desc"
2016-05-31 11:38:51 +02:00
if linesNum != 0 {
2016-05-30 11:11:39 +02:00
sql += " limit ?"
queryParam = append ( queryParam , linesNum )
}
2016-05-25 09:45:30 +02:00
o := GetOrmer ( )
2016-05-20 10:56:12 +02:00
_ , err := o . Raw ( sql , queryParam ) . QueryRows ( & recentLogList )
if err != nil {
return nil , err
}
return recentLogList , nil
}
2016-06-01 11:01:43 +02:00
2016-06-02 07:41:52 +02:00
//GetTopRepos return top accessed public repos
2016-06-06 11:53:36 +02:00
func GetTopRepos ( countNum int ) ( [ ] models . TopRepo , error ) {
2016-06-01 11:01:43 +02:00
o := GetOrmer ( )
2016-06-22 10:36:36 +02:00
// hide the where condition: project.public = 1, Can add to the sql when necessary.
sql := "select repo_name, COUNT(repo_name) as access_count from access_log left join project on access_log.project_id=project.project_id where access_log.operation = 'pull' group by repo_name order by access_count desc limit ? "
2016-06-21 12:43:31 +02:00
queryParam := [ ] interface { } { }
2016-06-01 13:29:08 +02:00
queryParam = append ( queryParam , countNum )
2016-06-21 12:43:31 +02:00
var list [ ] models . TopRepo
_ , err := o . Raw ( sql , queryParam ) . QueryRows ( & list )
2016-06-15 12:26:21 +02:00
if err != nil {
return nil , err
}
2016-06-21 12:43:31 +02:00
if len ( list ) == 0 {
return list , nil
2016-06-22 08:15:32 +02:00
}
placeHolder := make ( [ ] string , len ( list ) )
repos := make ( [ ] string , len ( list ) )
for i , v := range list {
repos [ i ] = v . RepoName
placeHolder [ i ] = "?"
}
placeHolderStr := strings . Join ( placeHolder , "," )
queryParam = nil
queryParam = append ( queryParam , repos )
var usrnameList [ ] models . TopRepo
sql = ` select a . username as creator , a . repo_name from ( select access_log . repo_name , user . username ,
access_log . op_time from user left join access_log on user . user_id = access_log . user_id where
access_log . operation = ' push ' and access_log . repo_name in ( # # # # # # ) order by access_log . repo_name ,
access_log . op_time ASC ) a group by a . repo_name `
sql = strings . Replace ( sql , "######" , placeHolderStr , 1 )
_ , err = o . Raw ( sql , queryParam ) . QueryRows ( & usrnameList )
if err != nil {
return nil , err
}
for i := 0 ; i < len ( list ) ; i ++ {
for _ , v := range usrnameList {
if v . RepoName == list [ i ] . RepoName {
2016-08-03 04:39:33 +02:00
// list[i].Creator = v.Creator
2016-06-22 08:15:32 +02:00
break
2016-06-21 12:43:31 +02:00
}
}
2016-06-15 12:26:21 +02:00
}
2016-06-22 08:15:32 +02:00
return list , nil
2016-06-01 11:01:43 +02:00
}