mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-07-23 04:51:39 +02:00
Refactor auth module
Separate parts Add user repository Add user schema
This commit is contained in:
137
internal/repository/userConfig.go
Normal file
137
internal/repository/userConfig.go
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2022 NHR@FAU, University Erlangen-Nuremberg.
|
||||
// All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
package repository
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||
"github.com/ClusterCockpit/cc-backend/pkg/lrucache"
|
||||
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
var (
|
||||
userCfgRepoOnce sync.Once
|
||||
userCfgRepoInstance *UserCfgRepo
|
||||
)
|
||||
|
||||
type UserCfgRepo struct {
|
||||
DB *sqlx.DB
|
||||
Lookup *sqlx.Stmt
|
||||
lock sync.RWMutex
|
||||
uiDefaults map[string]interface{}
|
||||
cache *lrucache.Cache
|
||||
}
|
||||
|
||||
func GetUserCfgRepo() *UserCfgRepo {
|
||||
userCfgRepoOnce.Do(func() {
|
||||
db := GetConnection()
|
||||
|
||||
lookupConfigStmt, err := db.DB.Preparex(`SELECT confkey, value FROM configuration WHERE configuration.username = ?`)
|
||||
if err != nil {
|
||||
log.Fatalf("db.DB.Preparex() error: %v", err)
|
||||
}
|
||||
|
||||
userCfgRepoInstance = &UserCfgRepo{
|
||||
DB: db.DB,
|
||||
Lookup: lookupConfigStmt,
|
||||
uiDefaults: config.Keys.UiDefaults,
|
||||
cache: lrucache.New(1024),
|
||||
}
|
||||
})
|
||||
|
||||
return userCfgRepoInstance
|
||||
}
|
||||
|
||||
// Return the personalised UI config for the currently authenticated
|
||||
// user or return the plain default config.
|
||||
func (uCfg *UserCfgRepo) GetUIConfig(user *schema.User) (map[string]interface{}, error) {
|
||||
if user == nil {
|
||||
uCfg.lock.RLock()
|
||||
copy := make(map[string]interface{}, len(uCfg.uiDefaults))
|
||||
for k, v := range uCfg.uiDefaults {
|
||||
copy[k] = v
|
||||
}
|
||||
uCfg.lock.RUnlock()
|
||||
return copy, nil
|
||||
}
|
||||
|
||||
data := uCfg.cache.Get(user.Username, func() (interface{}, time.Duration, int) {
|
||||
uiconfig := make(map[string]interface{}, len(uCfg.uiDefaults))
|
||||
for k, v := range uCfg.uiDefaults {
|
||||
uiconfig[k] = v
|
||||
}
|
||||
|
||||
rows, err := uCfg.Lookup.Query(user.Username)
|
||||
if err != nil {
|
||||
log.Warnf("Error while looking up user uiconfig for user '%v'", user.Username)
|
||||
return err, 0, 0
|
||||
}
|
||||
|
||||
size := 0
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var key, rawval string
|
||||
if err := rows.Scan(&key, &rawval); err != nil {
|
||||
log.Warn("Error while scanning user uiconfig values")
|
||||
return err, 0, 0
|
||||
}
|
||||
|
||||
var val interface{}
|
||||
if err := json.Unmarshal([]byte(rawval), &val); err != nil {
|
||||
log.Warn("Error while unmarshaling raw user uiconfig json")
|
||||
return err, 0, 0
|
||||
}
|
||||
|
||||
size += len(key)
|
||||
size += len(rawval)
|
||||
uiconfig[key] = val
|
||||
}
|
||||
|
||||
// Add global ShortRunningJobsDuration setting as plot_list_hideShortRunningJobs
|
||||
uiconfig["plot_list_hideShortRunningJobs"] = config.Keys.ShortRunningJobsDuration
|
||||
|
||||
return uiconfig, 24 * time.Hour, size
|
||||
})
|
||||
if err, ok := data.(error); ok {
|
||||
log.Error("Error in returned dataset")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data.(map[string]interface{}), nil
|
||||
}
|
||||
|
||||
// If the context does not have a user, update the global ui configuration
|
||||
// without persisting it! If there is a (authenticated) user, update only his
|
||||
// configuration.
|
||||
func (uCfg *UserCfgRepo) UpdateConfig(
|
||||
key, value string,
|
||||
user *schema.User) error {
|
||||
|
||||
if user == nil {
|
||||
var val interface{}
|
||||
if err := json.Unmarshal([]byte(value), &val); err != nil {
|
||||
log.Warn("Error while unmarshaling raw user config json")
|
||||
return err
|
||||
}
|
||||
|
||||
uCfg.lock.Lock()
|
||||
defer uCfg.lock.Unlock()
|
||||
uCfg.uiDefaults[key] = val
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := uCfg.DB.Exec(`REPLACE INTO configuration (username, confkey, value) VALUES (?, ?, ?)`, user.Username, key, value); err != nil {
|
||||
log.Warnf("Error while replacing user config in DB for user '%v'", user.Username)
|
||||
return err
|
||||
}
|
||||
|
||||
uCfg.cache.Del(user.Username)
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user