2022-05-11 22:47:31 +00:00
|
|
|
package user
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"npm/internal/database"
|
2023-05-26 01:04:43 +00:00
|
|
|
"npm/internal/entity"
|
2022-05-11 22:47:31 +00:00
|
|
|
"npm/internal/entity/auth"
|
|
|
|
"npm/internal/errors"
|
|
|
|
"npm/internal/util"
|
|
|
|
|
|
|
|
"github.com/drexedam/gravatar"
|
2023-02-24 07:19:07 +00:00
|
|
|
"github.com/rotisserie/eris"
|
2022-05-11 22:47:31 +00:00
|
|
|
)
|
|
|
|
|
2023-05-26 01:04:43 +00:00
|
|
|
// Model is the model
|
2022-05-11 22:47:31 +00:00
|
|
|
type Model struct {
|
2023-05-26 01:04:43 +00:00
|
|
|
entity.ModelBase
|
|
|
|
Name string `json:"name" gorm:"column:name" filter:"name,string"`
|
|
|
|
Nickname string `json:"nickname" gorm:"column:nickname" filter:"nickname,string"`
|
|
|
|
Email string `json:"email" gorm:"column:email" filter:"email,email"`
|
|
|
|
IsDisabled bool `json:"is_disabled" gorm:"column:is_disabled" filter:"is_disabled,boolean"`
|
2023-05-29 03:53:16 +00:00
|
|
|
IsSystem bool `json:"is_system,omitempty" gorm:"column:is_system" filter:"is_system,boolean"`
|
2023-05-26 01:04:43 +00:00
|
|
|
// Other
|
|
|
|
GravatarURL string `json:"gravatar_url" gorm:"-"`
|
2022-05-11 22:47:31 +00:00
|
|
|
// Expansions
|
2023-05-26 01:04:43 +00:00
|
|
|
Auth *auth.Model `json:"auth,omitempty" gorm:"-"`
|
|
|
|
Capabilities []string `json:"capabilities,omitempty" gorm:"-"`
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
2023-05-26 01:04:43 +00:00
|
|
|
// TableName overrides the table name used by gorm
|
|
|
|
func (Model) TableName() string {
|
|
|
|
return "user"
|
|
|
|
}
|
|
|
|
|
|
|
|
// UserHasCapabilityModel is the model
|
|
|
|
type UserHasCapabilityModel struct {
|
|
|
|
UserID uint `json:"user_id" gorm:"column:user_id"`
|
|
|
|
CapabilityName string `json:"name" gorm:"column:capability_name"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// TableName overrides the table name used by gorm
|
|
|
|
func (UserHasCapabilityModel) TableName() string {
|
|
|
|
return "user_has_capability"
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// LoadByID will load from an ID
|
2023-05-26 01:04:43 +00:00
|
|
|
func (m *Model) LoadByID(id uint) error {
|
|
|
|
db := database.GetDB()
|
|
|
|
result := db.First(&m, id)
|
|
|
|
return result.Error
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// LoadByEmail will load from an Email
|
|
|
|
func (m *Model) LoadByEmail(email string) error {
|
2023-05-26 01:04:43 +00:00
|
|
|
db := database.GetDB()
|
|
|
|
result := db.
|
|
|
|
Where("email = ?", strings.TrimSpace(strings.ToLower(email))).
|
|
|
|
Where("is_system = ?", false).
|
|
|
|
First(&m)
|
|
|
|
return result.Error
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Save will save this model to the DB
|
|
|
|
func (m *Model) Save() error {
|
|
|
|
// Ensure email is nice
|
|
|
|
m.Email = strings.TrimSpace(strings.ToLower(m.Email))
|
|
|
|
if m.IsSystem {
|
|
|
|
return errors.ErrSystemUserReadonly
|
|
|
|
}
|
|
|
|
|
2023-05-29 04:51:42 +00:00
|
|
|
// Check if an existing user with this email exists
|
|
|
|
if m2, err := GetByEmail(m.Email); err == nil && m.ID != m2.ID {
|
|
|
|
return errors.ErrDuplicateEmailUser
|
|
|
|
}
|
|
|
|
|
2023-05-26 01:04:43 +00:00
|
|
|
db := database.GetDB()
|
|
|
|
result := db.Save(m)
|
|
|
|
return result.Error
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete will mark a user as deleted
|
|
|
|
func (m *Model) Delete() bool {
|
2023-05-26 01:04:43 +00:00
|
|
|
if m.ID == 0 {
|
|
|
|
// Can't delete a new object
|
2022-05-11 22:47:31 +00:00
|
|
|
return false
|
|
|
|
}
|
2023-05-26 01:04:43 +00:00
|
|
|
db := database.GetDB()
|
|
|
|
result := db.Delete(m)
|
|
|
|
return result.Error == nil
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetPermissions will wipe out any existing permissions and add new ones for this user
|
|
|
|
func (m *Model) SetPermissions(permissions []string) error {
|
|
|
|
if m.ID == 0 {
|
2023-02-24 07:19:07 +00:00
|
|
|
return eris.Errorf("Cannot set permissions without first saving the User")
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
2023-05-26 01:04:43 +00:00
|
|
|
db := database.GetDB()
|
2022-05-11 22:47:31 +00:00
|
|
|
// Wipe out previous permissions
|
2023-05-26 01:04:43 +00:00
|
|
|
if result := db.Where("user_id = ?", m.ID).Delete(&UserHasCapabilityModel{}); result.Error != nil {
|
|
|
|
return result.Error
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(permissions) > 0 {
|
|
|
|
// Add new permissions
|
2023-05-26 01:04:43 +00:00
|
|
|
objs := []*UserHasCapabilityModel{}
|
2022-05-11 22:47:31 +00:00
|
|
|
for _, permission := range permissions {
|
2023-05-26 01:04:43 +00:00
|
|
|
objs = append(objs, &UserHasCapabilityModel{UserID: m.ID, CapabilityName: permission})
|
|
|
|
}
|
|
|
|
if result := db.Create(objs); result.Error != nil {
|
|
|
|
return result.Error
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expand will fill in more properties
|
|
|
|
func (m *Model) Expand(items []string) error {
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if util.SliceContainsItem(items, "capabilities") && m.ID > 0 {
|
|
|
|
m.Capabilities, err = GetCapabilities(m.ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Model) generateGravatar() {
|
|
|
|
m.GravatarURL = gravatar.New(m.Email).
|
|
|
|
Size(128).
|
|
|
|
Default(gravatar.MysteryMan).
|
|
|
|
Rating(gravatar.Pg).
|
|
|
|
AvatarURL()
|
|
|
|
}
|
|
|
|
|
|
|
|
// SaveCapabilities will save the capabilities of the user.
|
|
|
|
func (m *Model) SaveCapabilities() error {
|
|
|
|
// m.Capabilities
|
|
|
|
if m.ID == 0 {
|
2023-02-24 07:19:07 +00:00
|
|
|
return eris.Errorf("Cannot save capabilities on unsaved user")
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// there must be at least 1 capability
|
|
|
|
if len(m.Capabilities) == 0 {
|
2023-02-24 07:19:07 +00:00
|
|
|
return eris.New("At least 1 capability required for a user")
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
2023-05-26 01:04:43 +00:00
|
|
|
db := database.GetDB()
|
2022-05-11 22:47:31 +00:00
|
|
|
// Get a full list of capabilities
|
2023-05-26 01:04:43 +00:00
|
|
|
var capabilities []entity.Capability
|
|
|
|
if result := db.Find(&capabilities); result.Error != nil {
|
|
|
|
return result.Error
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the capabilities defined exist in the db
|
|
|
|
for _, cap := range m.Capabilities {
|
|
|
|
found := false
|
|
|
|
for _, a := range capabilities {
|
2023-05-26 01:04:43 +00:00
|
|
|
if a.Name == cap {
|
2022-05-11 22:47:31 +00:00
|
|
|
found = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
2023-02-24 07:19:07 +00:00
|
|
|
return eris.Errorf("Capability `%s` is not valid", cap)
|
2022-05-11 22:47:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return m.SetPermissions(m.Capabilities)
|
|
|
|
}
|