package models import ( "time" "github.com/h44z/wg-portal/internal/domain" ) // User represents a user in the system. type User struct { // The unique identifier of the user. Identifier string `json:"Identifier" binding:"required,max=64" example:"uid-1234567"` // The email address of the user. This field is optional. Email string `json:"Email" binding:"omitempty,email" example:"test@test.com"` // The source of the user. This field is optional. Source string `json:"Source" binding:"oneof=db" example:"db"` // The name of the authentication provider. This field is read-only. ProviderName string `json:"ProviderName,omitempty" readonly:"true" example:""` // If this field is set, the user is an admin. IsAdmin bool `json:"IsAdmin" binding:"required" example:"false"` // The first name of the user. This field is optional. Firstname string `json:"Firstname" example:"Max"` // The last name of the user. This field is optional. Lastname string `json:"Lastname" example:"Muster"` // The phone number of the user. This field is optional. Phone string `json:"Phone" example:"+1234546789"` // The department of the user. This field is optional. Department string `json:"Department" example:"Software Development"` // Additional notes about the user. This field is optional. Notes string `json:"Notes" example:"some sample notes"` // The password of the user. This field is never populated on read operations. Password string `json:"Password,omitempty" binding:"omitempty,min=16,max=64" example:""` // If this field is set, the user is disabled. Disabled bool `json:"Disabled" example:"false"` // The reason why the user has been disabled. DisabledReason string `json:"DisabledReason" binding:"required_if=Disabled true" example:""` // If this field is set, the user is locked and thus unable to log in to WireGuard Portal. Locked bool `json:"Locked" example:"false"` // The reason why the user has been locked. LockedReason string `json:"LockedReason" binding:"required_if=Locked true" example:""` // The API token of the user. This field is never populated on bulk read operations. ApiToken string `json:"ApiToken,omitempty" binding:"omitempty,min=32,max=64" example:""` // If this field is set, the user is allowed to use the RESTful API. This field is read-only. ApiEnabled bool `json:"ApiEnabled" readonly:"true" example:"false"` // The number of peers linked to the user. This field is read-only. PeerCount int `json:"PeerCount" readonly:"true" example:"2"` } func NewUser(src *domain.User, exposeCredentials bool) *User { u := &User{ Identifier: string(src.Identifier), Email: src.Email, Source: string(src.Source), ProviderName: src.ProviderName, IsAdmin: src.IsAdmin, Firstname: src.Firstname, Lastname: src.Lastname, Phone: src.Phone, Department: src.Department, Notes: src.Notes, Password: "", // never fill password Disabled: src.IsDisabled(), DisabledReason: src.DisabledReason, Locked: src.IsLocked(), LockedReason: src.LockedReason, ApiToken: "", // by default, do not expose API token ApiEnabled: src.IsApiEnabled(), PeerCount: src.LinkedPeerCount, } if exposeCredentials { u.ApiToken = src.ApiToken } return u } func NewUsers(src []domain.User) []User { results := make([]User, len(src)) for i := range src { results[i] = *NewUser(&src[i], false) } return results } func NewDomainUser(src *User) *domain.User { now := time.Now() res := &domain.User{ Identifier: domain.UserIdentifier(src.Identifier), Email: src.Email, Source: domain.UserSource(src.Source), ProviderName: src.ProviderName, IsAdmin: src.IsAdmin, Firstname: src.Firstname, Lastname: src.Lastname, Phone: src.Phone, Department: src.Department, Notes: src.Notes, Password: domain.PrivateString(src.Password), Disabled: nil, // set below DisabledReason: src.DisabledReason, Locked: nil, // set below LockedReason: src.LockedReason, } if src.ApiToken != "" { res.ApiToken = src.ApiToken res.ApiTokenCreated = &now } if src.Disabled { res.Disabled = &now } if src.Locked { res.Locked = &now } return res }