103 lines
3.0 KiB
Go
103 lines
3.0 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
)
|
|
|
|
type PanelSession struct {
|
|
ID int64
|
|
Token string
|
|
CSRFToken string
|
|
AdminID int64
|
|
IPAddress string
|
|
UserAgent string
|
|
LastActivity time.Time
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
type PanelSessionRepo struct{ db *sql.DB }
|
|
|
|
func NewPanelSessionRepo(db *sql.DB) *PanelSessionRepo { return &PanelSessionRepo{db: db} }
|
|
|
|
func (r *PanelSessionRepo) Create(ctx context.Context, s *PanelSession) error {
|
|
res, err := r.db.ExecContext(ctx,
|
|
`INSERT INTO panel_sessions(token,csrf_token,admin_id,ip_address,user_agent,last_activity,created_at)
|
|
VALUES(?,?,?,?,?,?,?)`,
|
|
s.Token, s.CSRFToken, s.AdminID, s.IPAddress, s.UserAgent, s.LastActivity, s.CreatedAt)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.ID, _ = res.LastInsertId()
|
|
return nil
|
|
}
|
|
|
|
func (r *PanelSessionRepo) GetByToken(ctx context.Context, token string) (*PanelSession, error) {
|
|
row := r.db.QueryRowContext(ctx,
|
|
`SELECT id,token,csrf_token,admin_id,ip_address,user_agent,last_activity,created_at
|
|
FROM panel_sessions WHERE token=?`, token)
|
|
var s PanelSession
|
|
err := row.Scan(&s.ID, &s.Token, &s.CSRFToken, &s.AdminID,
|
|
&s.IPAddress, &s.UserAgent, &s.LastActivity, &s.CreatedAt)
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &s, nil
|
|
}
|
|
|
|
func (r *PanelSessionRepo) UpdateLastActivity(ctx context.Context, token string, t time.Time) error {
|
|
_, err := r.db.ExecContext(ctx,
|
|
`UPDATE panel_sessions SET last_activity=? WHERE token=?`, t, token)
|
|
return err
|
|
}
|
|
|
|
func (r *PanelSessionRepo) DeleteByToken(ctx context.Context, token string) error {
|
|
_, err := r.db.ExecContext(ctx, `DELETE FROM panel_sessions WHERE token=?`, token)
|
|
return err
|
|
}
|
|
|
|
func (r *PanelSessionRepo) DeleteByID(ctx context.Context, id int64) error {
|
|
_, err := r.db.ExecContext(ctx, `DELETE FROM panel_sessions WHERE id=?`, id)
|
|
return err
|
|
}
|
|
|
|
// DeleteAllExcept deletes all sessions for adminID except the one with exceptToken.
|
|
func (r *PanelSessionRepo) DeleteAllExcept(ctx context.Context, adminID int64, exceptToken string) error {
|
|
_, err := r.db.ExecContext(ctx,
|
|
`DELETE FROM panel_sessions WHERE admin_id=? AND token!=?`, adminID, exceptToken)
|
|
return err
|
|
}
|
|
|
|
func (r *PanelSessionRepo) List(ctx context.Context) ([]*PanelSession, error) {
|
|
rows, err := r.db.QueryContext(ctx,
|
|
`SELECT id,token,csrf_token,admin_id,ip_address,user_agent,last_activity,created_at
|
|
FROM panel_sessions ORDER BY last_activity DESC`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
return scanSessions(rows)
|
|
}
|
|
|
|
func (r *PanelSessionRepo) DeleteExpiredBefore(ctx context.Context, before time.Time) error {
|
|
_, err := r.db.ExecContext(ctx, `DELETE FROM panel_sessions WHERE last_activity<?`, before)
|
|
return err
|
|
}
|
|
|
|
func scanSessions(rows *sql.Rows) ([]*PanelSession, error) {
|
|
var out []*PanelSession
|
|
for rows.Next() {
|
|
var s PanelSession
|
|
if err := rows.Scan(&s.ID, &s.Token, &s.CSRFToken, &s.AdminID,
|
|
&s.IPAddress, &s.UserAgent, &s.LastActivity, &s.CreatedAt); err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, &s)
|
|
}
|
|
return out, rows.Err()
|
|
}
|