github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/audit_logs.go (about)

     1  package common
     2  
     3  import (
     4  	"database/sql"
     5  	"time"
     6  
     7  	qgen "github.com/Azareal/Gosora/query_gen"
     8  )
     9  
    10  var ModLogs LogStore
    11  var AdminLogs LogStore
    12  
    13  type LogItem struct {
    14  	Action      string
    15  	ElementID   int
    16  	ElementType string
    17  	IP          string
    18  	ActorID     int
    19  	DoneAt      string
    20  	Extra       string
    21  }
    22  
    23  type LogStore interface {
    24  	Create(action string, elementID int, elementType, ip string, actorID int) (err error)
    25  	CreateExtra(action string, elementID int, elementType, ip string, actorID int, extra string) (err error)
    26  	Count() int
    27  	GetOffset(offset, perPage int) (logs []LogItem, err error)
    28  }
    29  
    30  type SQLModLogStore struct {
    31  	create    *sql.Stmt
    32  	count     *sql.Stmt
    33  	getOffset *sql.Stmt
    34  }
    35  
    36  func NewModLogStore(acc *qgen.Accumulator) (*SQLModLogStore, error) {
    37  	ml := "moderation_logs"
    38  	// TODO: Shorten name of ipaddress column to ip
    39  	cols := "action, elementID, elementType, ipaddress, actorID, doneAt, extra"
    40  	return &SQLModLogStore{
    41  		create:    acc.Insert(ml).Columns(cols).Fields("?,?,?,?,?,UTC_TIMESTAMP(),?").Prepare(),
    42  		count:     acc.Count(ml).Prepare(),
    43  		getOffset: acc.Select(ml).Columns(cols).Orderby("doneAt DESC").Limit("?,?").Prepare(),
    44  	}, acc.FirstError()
    45  }
    46  
    47  // TODO: Make a store for this?
    48  func (s *SQLModLogStore) Create(action string, elementID int, elementType, ip string, actorID int) (err error) {
    49  	return s.CreateExtra(action, elementID, elementType, ip, actorID, "")
    50  }
    51  
    52  func (s *SQLModLogStore) CreateExtra(action string, elementID int, elementType, ip string, actorID int, extra string) (err error) {
    53  	_, err = s.create.Exec(action, elementID, elementType, ip, actorID, extra)
    54  	return err
    55  }
    56  
    57  func (s *SQLModLogStore) Count() (count int) {
    58  	err := s.count.QueryRow().Scan(&count)
    59  	if err != nil {
    60  		LogError(err)
    61  	}
    62  	return count
    63  }
    64  
    65  func buildLogList(rows *sql.Rows) (logs []LogItem, err error) {
    66  	for rows.Next() {
    67  		var l LogItem
    68  		var doneAt time.Time
    69  		err := rows.Scan(&l.Action, &l.ElementID, &l.ElementType, &l.IP, &l.ActorID, &doneAt, &l.Extra)
    70  		if err != nil {
    71  			return logs, err
    72  		}
    73  		l.DoneAt = doneAt.Format("2006-01-02 15:04:05")
    74  		logs = append(logs, l)
    75  	}
    76  	return logs, rows.Err()
    77  }
    78  
    79  func (s *SQLModLogStore) GetOffset(offset, perPage int) (logs []LogItem, err error) {
    80  	rows, err := s.getOffset.Query(offset, perPage)
    81  	if err != nil {
    82  		return logs, err
    83  	}
    84  	defer rows.Close()
    85  	return buildLogList(rows)
    86  }
    87  
    88  type SQLAdminLogStore struct {
    89  	create    *sql.Stmt
    90  	count     *sql.Stmt
    91  	getOffset *sql.Stmt
    92  }
    93  
    94  func NewAdminLogStore(acc *qgen.Accumulator) (*SQLAdminLogStore, error) {
    95  	al := "administration_logs"
    96  	cols := "action, elementID, elementType, ipaddress, actorID, doneAt, extra"
    97  	return &SQLAdminLogStore{
    98  		create:    acc.Insert(al).Columns(cols).Fields("?,?,?,?,?,UTC_TIMESTAMP(),?").Prepare(),
    99  		count:     acc.Count(al).Prepare(),
   100  		getOffset: acc.Select(al).Columns(cols).Orderby("doneAt DESC").Limit("?,?").Prepare(),
   101  	}, acc.FirstError()
   102  }
   103  
   104  // TODO: Make a store for this?
   105  func (s *SQLAdminLogStore) Create(action string, elementID int, elementType, ip string, actorID int) (err error) {
   106  	return s.CreateExtra(action, elementID, elementType, ip, actorID, "")
   107  }
   108  
   109  func (s *SQLAdminLogStore) CreateExtra(action string, elementID int, elementType, ip string, actorID int, extra string) (err error) {
   110  	_, err = s.create.Exec(action, elementID, elementType, ip, actorID, extra)
   111  	return err
   112  }
   113  
   114  func (s *SQLAdminLogStore) Count() (count int) {
   115  	err := s.count.QueryRow().Scan(&count)
   116  	if err != nil {
   117  		LogError(err)
   118  	}
   119  	return count
   120  }
   121  
   122  func (s *SQLAdminLogStore) GetOffset(offset, perPage int) (logs []LogItem, err error) {
   123  	rows, err := s.getOffset.Query(offset, perPage)
   124  	if err != nil {
   125  		return logs, err
   126  	}
   127  	defer rows.Close()
   128  	return buildLogList(rows)
   129  }