init push
This commit is contained in:
127
internal/auth/session.go
Normal file
127
internal/auth/session.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type UserSession struct {
|
||||
UserID string `json:"user_id"`
|
||||
MicrosoftNameID string `json:"microsoft_name_id"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
LoggedInAt time.Time `json:"logged_in_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
}
|
||||
|
||||
type SessionRecord struct {
|
||||
Token string `gorm:"type:varchar(128);primaryKey;column:token"`
|
||||
UserID string `gorm:"type:varchar(191);index;not null;column:user_id"`
|
||||
MicrosoftNameID string `gorm:"type:varchar(255);index;not null;column:microsoft_name_id"`
|
||||
Email string `gorm:"type:varchar(191);index;not null;column:email"`
|
||||
Name string `gorm:"type:varchar(191);not null;column:name"`
|
||||
LoggedInAt time.Time `gorm:"not null;column:logged_in_at"`
|
||||
ExpiresAt time.Time `gorm:"index;not null;column:expires_at"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at"`
|
||||
}
|
||||
|
||||
func (SessionRecord) TableName() string { return "saml_sessions" }
|
||||
|
||||
var sessionDB *gorm.DB
|
||||
|
||||
func InitSessionStoreDB(db *gorm.DB) error {
|
||||
if db == nil {
|
||||
return fmt.Errorf("database is required")
|
||||
}
|
||||
if err := db.AutoMigrate(&SessionRecord{}); err != nil {
|
||||
return fmt.Errorf("auto migrate saml_sessions: %w", err)
|
||||
}
|
||||
sessionDB = db
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateSession(session UserSession) (string, error) {
|
||||
if sessionDB == nil {
|
||||
return "", fmt.Errorf("session store is not initialized")
|
||||
}
|
||||
token, err := generateToken()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if session.LoggedInAt.IsZero() {
|
||||
session.LoggedInAt = time.Now().UTC()
|
||||
}
|
||||
if session.ExpiresAt.IsZero() {
|
||||
session.ExpiresAt = session.LoggedInAt.Add(8 * time.Hour)
|
||||
}
|
||||
|
||||
record := SessionRecord{
|
||||
Token: token,
|
||||
UserID: session.UserID,
|
||||
MicrosoftNameID: session.MicrosoftNameID,
|
||||
Email: session.Email,
|
||||
Name: session.Name,
|
||||
LoggedInAt: session.LoggedInAt,
|
||||
ExpiresAt: session.ExpiresAt,
|
||||
}
|
||||
if err := sessionDB.Create(&record).Error; err != nil {
|
||||
return "", fmt.Errorf("create session: %w", err)
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func GetSession(token string) (*UserSession, error) {
|
||||
if sessionDB == nil {
|
||||
return nil, fmt.Errorf("session store is not initialized")
|
||||
}
|
||||
var record SessionRecord
|
||||
err := sessionDB.Where("token = ?", token).First(&record).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
if !record.ExpiresAt.After(now) {
|
||||
_ = sessionDB.Delete(&SessionRecord{}, "token = ?", token).Error
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
return &UserSession{
|
||||
UserID: record.UserID,
|
||||
MicrosoftNameID: record.MicrosoftNameID,
|
||||
Email: record.Email,
|
||||
Name: record.Name,
|
||||
LoggedInAt: record.LoggedInAt,
|
||||
ExpiresAt: record.ExpiresAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func DeleteSession(token string) error {
|
||||
if sessionDB == nil {
|
||||
return fmt.Errorf("session store is not initialized")
|
||||
}
|
||||
return sessionDB.Delete(&SessionRecord{}, "token = ?", token).Error
|
||||
}
|
||||
|
||||
func DeleteSessionByNameID(nameID string) error {
|
||||
if sessionDB == nil {
|
||||
return fmt.Errorf("session store is not initialized")
|
||||
}
|
||||
return sessionDB.Delete(&SessionRecord{}, "microsoft_name_id = ?", nameID).Error
|
||||
}
|
||||
|
||||
func generateToken() (string, error) {
|
||||
b := make([]byte, 32)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", fmt.Errorf("generate token: %w", err)
|
||||
}
|
||||
token := hex.EncodeToString(b)
|
||||
if token == "" {
|
||||
return "", errors.New("empty token")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
Reference in New Issue
Block a user