205 lines
5.1 KiB
Go
205 lines
5.1 KiB
Go
package user
|
|
|
|
import (
|
|
"encoding/pem"
|
|
"log"
|
|
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
|
|
group "example.com/database/group"
|
|
person "example.com/database/person"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type User struct {
|
|
gorm.Model
|
|
Id string `gorm:"primaryKey uniqueIndex" json:"id"`
|
|
Person person.Person `gorm:"foreignKey:Name" json:"person"`
|
|
DisplayName string `json:"display_name"`
|
|
Username string `json:"user_name"`
|
|
Avatar string `json:"avatar"`
|
|
AvatarDecoration string `json:"avatar_decoration"`
|
|
LoginToken string `json:"login_token"`
|
|
LoggedIn bool `json:"logged_in"`
|
|
ApiKeys []ApiKey `gorm:"many2many:user_apikey_associations" json:"api_key"`
|
|
}
|
|
|
|
type ApiKey struct {
|
|
gorm.Model
|
|
Name string `gorm:"primaryKey uniqueIndex" json:"name"`
|
|
Secret string `json:"secret"`
|
|
}
|
|
|
|
func (user User) Create(db *gorm.DB) error {
|
|
result := db.Create(&user)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (user *User) getAssociations(db *gorm.DB) error {
|
|
result := db.Model(&user).Association("Person").Find(&user.Person)
|
|
if result != nil {
|
|
return result
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (user *User) Get(db *gorm.DB, id string) error {
|
|
result := db.Where("id = ?", id).Take(&user)
|
|
if result.Error == gorm.ErrRecordNotFound {
|
|
result = db.Where("login_token = ?", id).Take(&user)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
}
|
|
err := user.getAssociations(db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (user *User) GetPersonGroups(db *gorm.DB) []string {
|
|
var groups []string
|
|
var groupObjects []group.Group
|
|
user.getAssociations(db)
|
|
var person []person.Person
|
|
db.Model(&user).Association("Person").Find(&person)
|
|
db.Model(&person[0]).Association("Groups").Find(&groupObjects)
|
|
for _, groupObject := range groupObjects {
|
|
groups = append(groups, groupObject.Name)
|
|
}
|
|
return groups
|
|
}
|
|
|
|
func (user *User) GetAPIKeySecret(db *gorm.DB, name string) string {
|
|
var apiKeys []ApiKey
|
|
err := db.Model(&user).Association("ApiKeys").Find(&apiKeys)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
var secret string
|
|
result := db.Model(&apiKeys).Select("secret").Where("name = ?", name).Take(&secret)
|
|
if result.Error != nil {
|
|
return ""
|
|
}
|
|
return secret
|
|
}
|
|
|
|
func (user User) Update(db *gorm.DB) error {
|
|
var originalUser User
|
|
originalUser.Get(db, user.Id)
|
|
result := db.Model(&originalUser).Updates(&user)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (user User) Delete(db *gorm.DB) error {
|
|
result := db.Delete(&user)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (user User) Logout(db *gorm.DB) error {
|
|
result := db.Model(&user).Update("logged_in", false)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (user User) GenerateAPIKey(db *gorm.DB, name string) error {
|
|
key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
bytestringKey, err := x509.MarshalECPrivateKey(key)
|
|
pemKey := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: bytestringKey})
|
|
newApiKey := ApiKey{
|
|
Name: name,
|
|
Secret: string(pemKey),
|
|
}
|
|
db.Create(&newApiKey)
|
|
user.getAssociations(db)
|
|
user.ApiKeys = append(user.ApiKeys, newApiKey)
|
|
user.Update(db)
|
|
return err
|
|
}
|
|
|
|
func Logout(db *gorm.DB, oauthToken string) error {
|
|
var user User
|
|
user.Get(db, oauthToken)
|
|
return user.Logout(db)
|
|
}
|
|
|
|
func Exists(db *gorm.DB, id string) bool {
|
|
var queryUser User
|
|
err := queryUser.Get(db, id)
|
|
return (err == nil)
|
|
}
|
|
|
|
func Create(db *gorm.DB, discordId string, displayName string, username string, avatar string, avatarDecoration string, loginToken string, loggedIn bool) error {
|
|
person.Create(db, displayName, []uint{})
|
|
newPerson := person.GetByName(db, username)
|
|
newUser := User{
|
|
Id: discordId,
|
|
Person: person.Person{},
|
|
DisplayName: displayName,
|
|
Username: username,
|
|
Avatar: avatar,
|
|
AvatarDecoration: avatarDecoration,
|
|
LoginToken: loginToken,
|
|
LoggedIn: loggedIn,
|
|
ApiKeys: nil,
|
|
}
|
|
err := newUser.Create(db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = db.Model(&newUser).Association("Person").Replace(&newPerson)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Get(db *gorm.DB, inputUsers []string) *[]User {
|
|
var outputUsers []User
|
|
for _, inputUser := range inputUsers {
|
|
var outputUser User
|
|
outputUser.Get(db, inputUser)
|
|
outputUsers = append(outputUsers, outputUser)
|
|
}
|
|
return &outputUsers
|
|
}
|
|
|
|
func GetAll(db *gorm.DB) *[]User {
|
|
var outputUserIDs []string
|
|
result := db.Model(&User{}).Select("id").Find(&outputUserIDs)
|
|
if result.Error != nil {
|
|
log.Println(result.Error)
|
|
}
|
|
return Get(db, outputUserIDs)
|
|
}
|
|
|
|
func Update(db *gorm.DB, discordId string, displayName string, username string, avatar string, avatarDecoration string, loginToken string, loggedIn bool) error {
|
|
newPerson := *person.GetByName(db, username)
|
|
return User{
|
|
Id: discordId,
|
|
Person: newPerson,
|
|
DisplayName: displayName,
|
|
Username: username,
|
|
Avatar: avatar,
|
|
AvatarDecoration: avatarDecoration,
|
|
LoginToken: loginToken,
|
|
LoggedIn: loggedIn,
|
|
ApiKeys: nil,
|
|
}.Update(db)
|
|
}
|