tulip/database/db-types.go

129 lines
3.6 KiB
Go

package database
import (
"database/sql"
"fmt"
"github.com/MrMelon54/pronouns"
"github.com/go-oauth2/oauth2/v4"
"github.com/google/uuid"
"golang.org/x/text/language"
"net/url"
"time"
)
type User struct {
Sub uuid.UUID `json:"sub"`
Name string `json:"name,omitempty"`
Username string `json:"username"`
Picture NullStringScanner `json:"picture,omitempty"`
Website NullStringScanner `json:"website,omitempty"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
Pronouns PronounScanner `json:"pronouns,omitempty"`
Birthdate NullDateScanner `json:"birthdate,omitempty"`
ZoneInfo LocationScanner `json:"zoneinfo,omitempty"`
Locale LocaleScanner `json:"locale,omitempty"`
Role UserRole `json:"role"`
UpdatedAt time.Time `json:"updated_at"`
Active bool `json:"active"`
}
type UserRole int
const (
RoleMember UserRole = iota
RoleAdmin
RoleToDelete
)
func (r UserRole) String() string {
switch r {
case RoleMember:
return "Member"
case RoleAdmin:
return "Admin"
case RoleToDelete:
return "ToDelete"
}
return fmt.Sprintf("UserRole{ %d }", r)
}
func (r UserRole) IsValid() bool {
return r == RoleMember || r == RoleAdmin
}
type UserPatch struct {
Name string
Picture string
Website string
Pronouns pronouns.Pronoun
Birthdate sql.NullTime
ZoneInfo *time.Location
Locale language.Tag
}
func (u *UserPatch) ParseFromForm(v url.Values) (safeErrs []error) {
var err error
u.Name = v.Get("name")
u.Picture = v.Get("picture")
u.Website = v.Get("website")
if v.Has("reset_pronouns") {
u.Pronouns = pronouns.TheyThem
} else {
u.Pronouns, err = pronouns.FindPronoun(v.Get("pronouns"))
if err != nil {
safeErrs = append(safeErrs, fmt.Errorf("invalid pronoun selected"))
}
}
if v.Has("reset_birthdate") || v.Get("birthdate") == "" {
u.Birthdate = sql.NullTime{}
} else {
u.Birthdate = sql.NullTime{Valid: true}
u.Birthdate.Time, err = time.Parse(time.DateOnly, v.Get("birthdate"))
if err != nil {
safeErrs = append(safeErrs, fmt.Errorf("invalid time selected"))
}
}
if v.Has("reset_zoneinfo") {
u.ZoneInfo = time.UTC
} else {
u.ZoneInfo, err = time.LoadLocation(v.Get("zoneinfo"))
if err != nil {
safeErrs = append(safeErrs, fmt.Errorf("invalid timezone selected"))
}
}
if v.Has("reset_locale") {
u.Locale = language.AmericanEnglish
} else {
u.Locale, err = language.Parse(v.Get("locale"))
if err != nil {
safeErrs = append(safeErrs, fmt.Errorf("invalid language selected"))
}
}
return
}
type ClientInfoDbOutput struct {
Sub, Name, Secret, Domain, Owner string
SSO, Active bool
}
var _ oauth2.ClientInfo = &ClientInfoDbOutput{}
func (c *ClientInfoDbOutput) GetID() string { return c.Sub }
func (c *ClientInfoDbOutput) GetSecret() string { return c.Secret }
func (c *ClientInfoDbOutput) GetDomain() string { return c.Domain }
func (c *ClientInfoDbOutput) IsPublic() bool { return false }
func (c *ClientInfoDbOutput) GetUserID() string { return c.Owner }
// GetName is an extra field for the oauth handler to display the application
// name
func (c *ClientInfoDbOutput) GetName() string { return c.Name }
// IsSSO is an extra field for the oauth handler to skip the user input stage
// this is for trusted applications to get permissions without asking the user
func (c *ClientInfoDbOutput) IsSSO() bool { return c.SSO }
// IsActive is an extra field for the app manager to get the active state
func (c *ClientInfoDbOutput) IsActive() bool { return c.Active }