Compare commits
No commits in common. "582988add25159deee069461b9d5fa25755019f2" and "69927c76ffd85f08ab2f8838bf5f483e468a4c9c" have entirely different histories.
582988add2
...
69927c76ff
11 changed files with 72 additions and 650 deletions
|
@ -17,7 +17,5 @@ type Authenticator struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func calcAccessExpirationTimestamp() time.Time {
|
func calcAccessExpirationTimestamp() time.Time {
|
||||||
// For now, the default expiration is one month after creation
|
|
||||||
// though "never" might also be a good option
|
|
||||||
return time.Now().Add(time.Hour * 24 * 30)
|
return time.Now().Add(time.Hour * 24 * 30)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,4 @@ var (
|
||||||
ErrUnsupportedAuthMethod = errors.New("authentication method not supported for this user")
|
ErrUnsupportedAuthMethod = errors.New("authentication method not supported for this user")
|
||||||
ErrInvalidCombination = errors.New("invalid account and token combination")
|
ErrInvalidCombination = errors.New("invalid account and token combination")
|
||||||
ErrProcessTimeout = errors.New("authentication process timed out")
|
ErrProcessTimeout = errors.New("authentication process timed out")
|
||||||
// A user may not login, for whatever reason
|
|
||||||
ErrCantLogin = errors.New("user can't login")
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,12 +5,10 @@ import (
|
||||||
|
|
||||||
"git.mstar.dev/mstar/goutils/other"
|
"git.mstar.dev/mstar/goutils/other"
|
||||||
"git.mstar.dev/mstar/goutils/sliceutils"
|
"git.mstar.dev/mstar/goutils/sliceutils"
|
||||||
"github.com/google/uuid"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
|
|
||||||
"git.mstar.dev/mstar/linstrom/storage-new"
|
|
||||||
"git.mstar.dev/mstar/linstrom/storage-new/dbgen"
|
"git.mstar.dev/mstar/linstrom/storage-new/dbgen"
|
||||||
"git.mstar.dev/mstar/linstrom/storage-new/models"
|
"git.mstar.dev/mstar/linstrom/storage-new/models"
|
||||||
)
|
)
|
||||||
|
@ -81,10 +79,8 @@ func (a *Authenticator) StartPasswordLogin(
|
||||||
username string,
|
username string,
|
||||||
password string,
|
password string,
|
||||||
) (nextState LoginNextState, token string, err error) {
|
) (nextState LoginNextState, token string, err error) {
|
||||||
if ok, err := a.canUsernameLogin(username); !ok {
|
var acc *models.User
|
||||||
return LoginNextFailure, "", other.Error("auth", "user may not login", err)
|
acc, err = dbgen.User.Where(dbgen.User.Username.Eq(username)).First()
|
||||||
}
|
|
||||||
acc, err := dbgen.User.Where(dbgen.User.Username.Eq(username)).First()
|
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
break
|
break
|
||||||
|
@ -147,10 +143,10 @@ func (a *Authenticator) StartPasswordLogin(
|
||||||
loginToken := models.LoginProcessToken{
|
loginToken := models.LoginProcessToken{
|
||||||
User: *acc,
|
User: *acc,
|
||||||
UserId: acc.ID,
|
UserId: acc.ID,
|
||||||
ExpiresAt: calcAccessExpirationTimestamp(),
|
ExpiresAt: time.Now().Add(time.Minute * 5),
|
||||||
Token: uuid.NewString(),
|
|
||||||
}
|
}
|
||||||
err = dbgen.LoginProcessToken.Clauses(clause.OnConflict{UpdateAll: true}).
|
err = dbgen.LoginProcessToken.Clauses(clause.OnConflict{DoNothing: true}).
|
||||||
|
Omit(dbgen.LoginProcessToken.Token).
|
||||||
Create(&loginToken)
|
Create(&loginToken)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -163,24 +159,3 @@ func (a *Authenticator) StartPasswordLogin(
|
||||||
|
|
||||||
return nextStates, loginToken.Token, nil
|
return nextStates, loginToken.Token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Authenticator) canUsernameLogin(username string) (bool, error) {
|
|
||||||
acc, err := dbgen.User.Where(dbgen.User.Username.Eq(username)).First()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if !acc.FinishedRegistration {
|
|
||||||
return false, ErrCantLogin
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Check roles too
|
|
||||||
finalRole := storage.CollapseRolesIntoOne(
|
|
||||||
sliceutils.Map(acc.Roles, func(t models.UserToRole) models.Role {
|
|
||||||
return t.Role
|
|
||||||
})...)
|
|
||||||
if finalRole.CanLogin != nil && !*finalRole.CanLogin {
|
|
||||||
return false, ErrCantLogin
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,9 +15,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *Authenticator) StartPasskeyLogin(username string) (*protocol.CredentialAssertion, error) {
|
func (a *Authenticator) StartPasskeyLogin(username string) (*protocol.CredentialAssertion, error) {
|
||||||
if ok, err := a.canUsernameLogin(username); !ok {
|
|
||||||
return nil, other.Error("auth", "user may not login", err)
|
|
||||||
}
|
|
||||||
acc, err := dbgen.User.Where(dbgen.User.Username.Eq(username)).First()
|
acc, err := dbgen.User.Where(dbgen.User.Username.Eq(username)).First()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -1,195 +0,0 @@
|
||||||
/*
|
|
||||||
Tool for generating helper functions for storage.Role structs inside of the storage package
|
|
||||||
It generates the following functions:
|
|
||||||
- CollapseRolesIntoOne: Collapse a list of roles into one singular role. Each value will be set to the
|
|
||||||
value of the role with the highest priority
|
|
||||||
- RoleDeepCopy: Copy a role, including all arrays. Every value will be copied too
|
|
||||||
- CompareRoles: Compare two roles. Returns true only if all fields are equal
|
|
||||||
(if one of the fields is nil, that field is seen as equal)
|
|
||||||
*/
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.mstar.dev/mstar/goutils/sliceutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
var findRoleStructRegex = regexp.MustCompile(`type Role struct \{([\s\S]+)\}\n\n/\*`)
|
|
||||||
|
|
||||||
var (
|
|
||||||
flagInputFile = flag.String("input", "", "Specify the input file. If empty, read from stdin")
|
|
||||||
flagOutputFile = flag.String(
|
|
||||||
"output",
|
|
||||||
"",
|
|
||||||
"Specify the output file. If empty, writes to stdout",
|
|
||||||
)
|
|
||||||
flagOutputModule = flag.String(
|
|
||||||
"mod",
|
|
||||||
"",
|
|
||||||
"Module for the output file. If empty, use mod of input file",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
var input io.Reader
|
|
||||||
var output io.Writer
|
|
||||||
|
|
||||||
if *flagInputFile == "" {
|
|
||||||
input = os.Stdin
|
|
||||||
} else {
|
|
||||||
file, err := os.Open(*flagInputFile)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
input = file
|
|
||||||
}
|
|
||||||
if *flagOutputFile == "" {
|
|
||||||
output = os.Stdout
|
|
||||||
} else {
|
|
||||||
file, err := os.Create(*flagOutputFile)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
output = file
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := io.ReadAll(input)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if !findRoleStructRegex.Match(data) {
|
|
||||||
panic("Input doesn't contain role struct")
|
|
||||||
}
|
|
||||||
content := findRoleStructRegex.FindStringSubmatch(string(data))[1]
|
|
||||||
lines := strings.Split(content, "\n")
|
|
||||||
lines = sliceutils.Map(lines, func(t string) string { return strings.TrimSpace(t) })
|
|
||||||
importantLines := sliceutils.Filter(lines, func(t string) bool {
|
|
||||||
if strings.HasPrefix(t, "//") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if strings.Contains(t, "gorm.Model") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
data := sliceutils.Filter(strings.Split(t, " "), func(t string) bool { return t != "" })
|
|
||||||
if len(data) < 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !strings.HasPrefix(data[1], "*") && !strings.HasPrefix(data[1], "[]") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
nameTypeMap := map[string]string{}
|
|
||||||
for _, line := range importantLines {
|
|
||||||
parts := sliceutils.Filter(strings.Split(line, " "), func(t string) bool { return t != "" })
|
|
||||||
nameTypeMap[parts[0]] = parts[1]
|
|
||||||
}
|
|
||||||
pkgString, _, _ := strings.Cut(string(data), "\n")
|
|
||||||
|
|
||||||
outBuilder := strings.Builder{}
|
|
||||||
outBuilder.WriteString(`// Code generated by cmd/RolesGenerator DO NOT EDIT.
|
|
||||||
// If you need to refresh the content, run go generate again
|
|
||||||
`)
|
|
||||||
if *flagOutputModule == "" {
|
|
||||||
outBuilder.WriteString(pkgString + "\n\n")
|
|
||||||
} else {
|
|
||||||
outBuilder.WriteString("package " + *flagOutputModule + "\n\n")
|
|
||||||
}
|
|
||||||
outBuilder.WriteString(
|
|
||||||
`import (
|
|
||||||
"slices"
|
|
||||||
"git.mstar.dev/mstar/goutils/sliceutils"
|
|
||||||
"git.mstar.dev/mstar/linstrom/storage-new/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
`,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Build role collapse function
|
|
||||||
outBuilder.WriteString(
|
|
||||||
`func CollapseRolesIntoOne(roles ...models.Role) models.Role {
|
|
||||||
startingRole := RoleDeepCopy(models.DefaultUserRole)
|
|
||||||
slices.SortFunc(roles, func(a, b models.Role) int { return int(int64(a.Priority)-int64(b.Priority)) })
|
|
||||||
for _, role := range roles {
|
|
||||||
`)
|
|
||||||
// Write all the stupid conditions here
|
|
||||||
for valName, valType := range nameTypeMap {
|
|
||||||
if strings.HasPrefix(valType, "[]") {
|
|
||||||
outBuilder.WriteString(fmt.Sprintf(` if role.%s != nil {
|
|
||||||
startingRole.%s = append(startingRole.%s, role.%s...)
|
|
||||||
}
|
|
||||||
`, valName, valName, valName, valName))
|
|
||||||
} else {
|
|
||||||
outBuilder.WriteString(fmt.Sprintf(` if role.%s != nil {
|
|
||||||
*startingRole.%s = *role.%s
|
|
||||||
}
|
|
||||||
`, valName, valName, valName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Then finish up with the end of the function
|
|
||||||
outBuilder.WriteString(
|
|
||||||
` }
|
|
||||||
return startingRole
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
// Then build the deep copy function
|
|
||||||
outBuilder.WriteString("\nfunc RoleDeepCopy(o models.Role) models.Role {\n")
|
|
||||||
outBuilder.WriteString(` n := models.Role{}
|
|
||||||
n.Model = o.Model
|
|
||||||
n.Name = o.Name
|
|
||||||
n.Priority = o.Priority
|
|
||||||
n.IsUserRole = o.IsUserRole
|
|
||||||
n.IsBuiltIn = o.IsBuiltIn
|
|
||||||
`)
|
|
||||||
for valName, valType := range nameTypeMap {
|
|
||||||
if strings.HasPrefix(valType, "[]") {
|
|
||||||
outBuilder.WriteString(fmt.Sprintf(" n.%s = slices.Clone(o.%s)\n", valName, valName))
|
|
||||||
} else {
|
|
||||||
outBuilder.WriteString(fmt.Sprintf(` if o.%s == nil { n.%s = nil } else {
|
|
||||||
t := *o.%s
|
|
||||||
n.%s = &t
|
|
||||||
}
|
|
||||||
`, valName, valName, valName, valName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outBuilder.WriteString(" return n\n}\n\n")
|
|
||||||
|
|
||||||
// Build compare function
|
|
||||||
outBuilder.WriteString("func CompareRoles(a, b *models.Role) bool {\n")
|
|
||||||
outBuilder.WriteString(" return ")
|
|
||||||
lastName, lastType := "", ""
|
|
||||||
for valName, valType := range nameTypeMap {
|
|
||||||
lastName = valName
|
|
||||||
lastType = valType
|
|
||||||
outBuilder.WriteString(fmt.Sprintf("(a.%s == nil || b.%s == nil || ", valName, valName))
|
|
||||||
if strings.HasPrefix(valType, "[]") {
|
|
||||||
outBuilder.WriteString(
|
|
||||||
fmt.Sprintf("sliceutils.CompareUnordered(a.%s,b.%s)) && ", valName, valName),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
outBuilder.WriteString(fmt.Sprintf("a.%s == b.%s) && ", valName, valName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outBuilder.WriteString("(a == nil || b == nil || ")
|
|
||||||
if strings.HasPrefix(lastType, "[]") {
|
|
||||||
outBuilder.WriteString(
|
|
||||||
fmt.Sprintf("sliceutils.CompareUnordered(a.%s,b.%s))", lastName, lastName),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
outBuilder.WriteString(fmt.Sprintf("a.%s == b.%s)", lastName, lastName))
|
|
||||||
}
|
|
||||||
outBuilder.WriteString("\n}")
|
|
||||||
|
|
||||||
// And write the entire thing to the output
|
|
||||||
fmt.Fprint(output, outBuilder.String())
|
|
||||||
}
|
|
|
@ -1,15 +1,19 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.mstar.dev/mstar/goutils/other"
|
"git.mstar.dev/mstar/goutils/other"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/testcontainers/testcontainers-go"
|
||||||
|
postgresContainer "github.com/testcontainers/testcontainers-go/modules/postgres"
|
||||||
|
"github.com/testcontainers/testcontainers-go/wait"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gen"
|
"gorm.io/gen"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"git.mstar.dev/mstar/linstrom/config"
|
|
||||||
"git.mstar.dev/mstar/linstrom/shared"
|
"git.mstar.dev/mstar/linstrom/shared"
|
||||||
"git.mstar.dev/mstar/linstrom/storage-new/models"
|
"git.mstar.dev/mstar/linstrom/storage-new/models"
|
||||||
)
|
)
|
||||||
|
@ -32,36 +36,36 @@ func main() {
|
||||||
other.SetupFlags()
|
other.SetupFlags()
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
other.ConfigureLogging(nil)
|
other.ConfigureLogging(nil)
|
||||||
config.ReadAndWriteToGlobal(*shared.FlagConfigFile)
|
// config.ReadAndWriteToGlobal(*shared.FlagConfigFile)
|
||||||
|
|
||||||
// Set up a temporary postgres container for gorm-gen to do its thing
|
// Set up a temporary postgres container for gorm-gen to do its thing
|
||||||
// log.Info().Msg("Starting temporary postgres container")
|
log.Info().Msg("Starting temporary postgres container")
|
||||||
// pgContainer, err := postgresContainer.Run(
|
pgContainer, err := postgresContainer.Run(
|
||||||
// context.Background(),
|
context.Background(),
|
||||||
// "postgres:16.4-alpine",
|
"postgres:16.4-alpine",
|
||||||
// postgresContainer.WithDatabase(dbName),
|
postgresContainer.WithDatabase(dbName),
|
||||||
// postgresContainer.WithUsername(dbUser),
|
postgresContainer.WithUsername(dbUser),
|
||||||
// postgresContainer.WithPassword(dbPass),
|
postgresContainer.WithPassword(dbPass),
|
||||||
// testcontainers.WithWaitStrategyAndDeadline(
|
testcontainers.WithWaitStrategyAndDeadline(
|
||||||
// time.Minute,
|
time.Minute,
|
||||||
// wait.ForLog("database system is ready to accept connections").
|
wait.ForLog("database system is ready to accept connections").
|
||||||
// WithOccurrence(2).
|
WithOccurrence(2).
|
||||||
// WithStartupTimeout(time.Second*5),
|
WithStartupTimeout(time.Second*5),
|
||||||
// ),
|
),
|
||||||
// )
|
)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// log.Fatal().Err(err).Msg("Failed to setup temporary postgres container")
|
log.Fatal().Err(err).Msg("Failed to setup temporary postgres container")
|
||||||
// }
|
}
|
||||||
// log.Info().Msg("Temporary postgres container started")
|
log.Info().Msg("Temporary postgres container started")
|
||||||
// defer func() {
|
defer func() {
|
||||||
// if err := testcontainers.TerminateContainer(pgContainer); err != nil {
|
if err := testcontainers.TerminateContainer(pgContainer); err != nil {
|
||||||
// log.Fatal().Err(err).Msg("Failed to terminate temporary postgres container")
|
log.Fatal().Err(err).Msg("Failed to terminate temporary postgres container")
|
||||||
// }
|
}
|
||||||
// log.Info().Msg("Temporary postgres container stopped")
|
log.Info().Msg("Temporary postgres container stopped")
|
||||||
// }()
|
}()
|
||||||
db, err := gorm.Open(
|
db, err := gorm.Open(
|
||||||
postgres.Open(config.GlobalConfig.Storage.BuildPostgresDSN()),
|
// postgres.Open(config.GlobalConfig.Storage.BuildPostgresDSN()),
|
||||||
// postgres.Open(pgContainer.MustConnectionString(context.Background())),
|
postgres.Open(pgContainer.MustConnectionString(context.Background())),
|
||||||
&gorm.Config{
|
&gorm.Config{
|
||||||
PrepareStmt: false,
|
PrepareStmt: false,
|
||||||
Logger: shared.NewGormLogger(log.Logger),
|
Logger: shared.NewGormLogger(log.Logger),
|
||||||
|
|
|
@ -28,7 +28,6 @@ func newLoginProcessToken(db *gorm.DB, opts ...gen.DOOption) loginProcessToken {
|
||||||
_loginProcessToken.ALL = field.NewAsterisk(tableName)
|
_loginProcessToken.ALL = field.NewAsterisk(tableName)
|
||||||
_loginProcessToken.UserId = field.NewString(tableName, "user_id")
|
_loginProcessToken.UserId = field.NewString(tableName, "user_id")
|
||||||
_loginProcessToken.Token = field.NewString(tableName, "token")
|
_loginProcessToken.Token = field.NewString(tableName, "token")
|
||||||
_loginProcessToken.ExpiresAt = field.NewTime(tableName, "expires_at")
|
|
||||||
_loginProcessToken.User = loginProcessTokenBelongsToUser{
|
_loginProcessToken.User = loginProcessTokenBelongsToUser{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
@ -178,11 +177,10 @@ func newLoginProcessToken(db *gorm.DB, opts ...gen.DOOption) loginProcessToken {
|
||||||
type loginProcessToken struct {
|
type loginProcessToken struct {
|
||||||
loginProcessTokenDo
|
loginProcessTokenDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
UserId field.String
|
UserId field.String
|
||||||
Token field.String
|
Token field.String
|
||||||
ExpiresAt field.Time
|
User loginProcessTokenBelongsToUser
|
||||||
User loginProcessTokenBelongsToUser
|
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
|
@ -201,7 +199,6 @@ func (l *loginProcessToken) updateTableName(table string) *loginProcessToken {
|
||||||
l.ALL = field.NewAsterisk(table)
|
l.ALL = field.NewAsterisk(table)
|
||||||
l.UserId = field.NewString(table, "user_id")
|
l.UserId = field.NewString(table, "user_id")
|
||||||
l.Token = field.NewString(table, "token")
|
l.Token = field.NewString(table, "token")
|
||||||
l.ExpiresAt = field.NewTime(table, "expires_at")
|
|
||||||
|
|
||||||
l.fillFieldMap()
|
l.fillFieldMap()
|
||||||
|
|
||||||
|
@ -218,10 +215,9 @@ func (l *loginProcessToken) GetFieldByName(fieldName string) (field.OrderExpr, b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loginProcessToken) fillFieldMap() {
|
func (l *loginProcessToken) fillFieldMap() {
|
||||||
l.fieldMap = make(map[string]field.Expr, 4)
|
l.fieldMap = make(map[string]field.Expr, 3)
|
||||||
l.fieldMap["user_id"] = l.UserId
|
l.fieldMap["user_id"] = l.UserId
|
||||||
l.fieldMap["token"] = l.Token
|
l.fieldMap["token"] = l.Token
|
||||||
l.fieldMap["expires_at"] = l.ExpiresAt
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,16 +36,14 @@ func newUser(db *gorm.DB, opts ...gen.DOOption) user {
|
||||||
_user.Description = field.NewString(tableName, "description")
|
_user.Description = field.NewString(tableName, "description")
|
||||||
_user.IsBot = field.NewBool(tableName, "is_bot")
|
_user.IsBot = field.NewBool(tableName, "is_bot")
|
||||||
_user.IconId = field.NewString(tableName, "icon_id")
|
_user.IconId = field.NewString(tableName, "icon_id")
|
||||||
_user.BackgroundId = field.NewField(tableName, "background_id")
|
_user.BackgroundId = field.NewString(tableName, "background_id")
|
||||||
_user.BannerId = field.NewField(tableName, "banner_id")
|
_user.BannerId = field.NewString(tableName, "banner_id")
|
||||||
_user.Indexable = field.NewBool(tableName, "indexable")
|
_user.Indexable = field.NewBool(tableName, "indexable")
|
||||||
_user.PublicKey = field.NewBytes(tableName, "public_key")
|
_user.PublicKey = field.NewBytes(tableName, "public_key")
|
||||||
_user.RestrictedFollow = field.NewBool(tableName, "restricted_follow")
|
_user.RestrictedFollow = field.NewBool(tableName, "restricted_follow")
|
||||||
_user.Location = field.NewField(tableName, "location")
|
_user.Location = field.NewString(tableName, "location")
|
||||||
_user.Birthday = field.NewField(tableName, "birthday")
|
_user.Birthday = field.NewTime(tableName, "birthday")
|
||||||
_user.Verified = field.NewBool(tableName, "verified")
|
_user.Verified = field.NewBool(tableName, "verified")
|
||||||
_user.PasskeyId = field.NewBytes(tableName, "passkey_id")
|
|
||||||
_user.FinishedRegistration = field.NewBool(tableName, "finished_registration")
|
|
||||||
_user.RemoteInfo = userHasOneRemoteInfo{
|
_user.RemoteInfo = userHasOneRemoteInfo{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
@ -312,28 +310,26 @@ func newUser(db *gorm.DB, opts ...gen.DOOption) user {
|
||||||
type user struct {
|
type user struct {
|
||||||
userDo
|
userDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.String
|
ID field.String
|
||||||
Username field.String
|
Username field.String
|
||||||
CreatedAt field.Time
|
CreatedAt field.Time
|
||||||
UpdatedAt field.Time
|
UpdatedAt field.Time
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
ServerId field.Uint
|
ServerId field.Uint
|
||||||
DisplayName field.String
|
DisplayName field.String
|
||||||
Description field.String
|
Description field.String
|
||||||
IsBot field.Bool
|
IsBot field.Bool
|
||||||
IconId field.String
|
IconId field.String
|
||||||
BackgroundId field.Field
|
BackgroundId field.String
|
||||||
BannerId field.Field
|
BannerId field.String
|
||||||
Indexable field.Bool
|
Indexable field.Bool
|
||||||
PublicKey field.Bytes
|
PublicKey field.Bytes
|
||||||
RestrictedFollow field.Bool
|
RestrictedFollow field.Bool
|
||||||
Location field.Field
|
Location field.String
|
||||||
Birthday field.Field
|
Birthday field.Time
|
||||||
Verified field.Bool
|
Verified field.Bool
|
||||||
PasskeyId field.Bytes
|
RemoteInfo userHasOneRemoteInfo
|
||||||
FinishedRegistration field.Bool
|
|
||||||
RemoteInfo userHasOneRemoteInfo
|
|
||||||
|
|
||||||
InfoFields userHasManyInfoFields
|
InfoFields userHasManyInfoFields
|
||||||
|
|
||||||
|
@ -380,16 +376,14 @@ func (u *user) updateTableName(table string) *user {
|
||||||
u.Description = field.NewString(table, "description")
|
u.Description = field.NewString(table, "description")
|
||||||
u.IsBot = field.NewBool(table, "is_bot")
|
u.IsBot = field.NewBool(table, "is_bot")
|
||||||
u.IconId = field.NewString(table, "icon_id")
|
u.IconId = field.NewString(table, "icon_id")
|
||||||
u.BackgroundId = field.NewField(table, "background_id")
|
u.BackgroundId = field.NewString(table, "background_id")
|
||||||
u.BannerId = field.NewField(table, "banner_id")
|
u.BannerId = field.NewString(table, "banner_id")
|
||||||
u.Indexable = field.NewBool(table, "indexable")
|
u.Indexable = field.NewBool(table, "indexable")
|
||||||
u.PublicKey = field.NewBytes(table, "public_key")
|
u.PublicKey = field.NewBytes(table, "public_key")
|
||||||
u.RestrictedFollow = field.NewBool(table, "restricted_follow")
|
u.RestrictedFollow = field.NewBool(table, "restricted_follow")
|
||||||
u.Location = field.NewField(table, "location")
|
u.Location = field.NewString(table, "location")
|
||||||
u.Birthday = field.NewField(table, "birthday")
|
u.Birthday = field.NewTime(table, "birthday")
|
||||||
u.Verified = field.NewBool(table, "verified")
|
u.Verified = field.NewBool(table, "verified")
|
||||||
u.PasskeyId = field.NewBytes(table, "passkey_id")
|
|
||||||
u.FinishedRegistration = field.NewBool(table, "finished_registration")
|
|
||||||
|
|
||||||
u.fillFieldMap()
|
u.fillFieldMap()
|
||||||
|
|
||||||
|
@ -406,7 +400,7 @@ func (u *user) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *user) fillFieldMap() {
|
func (u *user) fillFieldMap() {
|
||||||
u.fieldMap = make(map[string]field.Expr, 31)
|
u.fieldMap = make(map[string]field.Expr, 29)
|
||||||
u.fieldMap["id"] = u.ID
|
u.fieldMap["id"] = u.ID
|
||||||
u.fieldMap["username"] = u.Username
|
u.fieldMap["username"] = u.Username
|
||||||
u.fieldMap["created_at"] = u.CreatedAt
|
u.fieldMap["created_at"] = u.CreatedAt
|
||||||
|
@ -425,8 +419,6 @@ func (u *user) fillFieldMap() {
|
||||||
u.fieldMap["location"] = u.Location
|
u.fieldMap["location"] = u.Location
|
||||||
u.fieldMap["birthday"] = u.Birthday
|
u.fieldMap["birthday"] = u.Birthday
|
||||||
u.fieldMap["verified"] = u.Verified
|
u.fieldMap["verified"] = u.Verified
|
||||||
u.fieldMap["passkey_id"] = u.PasskeyId
|
|
||||||
u.fieldMap["finished_registration"] = u.FinishedRegistration
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,7 @@ type User struct {
|
||||||
// 64 byte unique id for passkeys, because UUIDs are 128 bytes and passkey spec says 64 bytes max
|
// 64 byte unique id for passkeys, because UUIDs are 128 bytes and passkey spec says 64 bytes max
|
||||||
// In theory, could also slash Id in half, but that would be a lot more calculations than the
|
// In theory, could also slash Id in half, but that would be a lot more calculations than the
|
||||||
// saved space is worth
|
// saved space is worth
|
||||||
PasskeyId []byte
|
PasskeyId []byte
|
||||||
FinishedRegistration bool // Whether this account has completed registration yet
|
|
||||||
|
|
||||||
// ---- "Remote" linked values
|
// ---- "Remote" linked values
|
||||||
InfoFields []UserInfoField
|
InfoFields []UserInfoField
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,3 +1 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
//go:generate go run ../cmd/NewRoleHelperGenerator/main.go -input ./models/Role.go -output role_generated.go -mod storage
|
|
||||||
|
|
Loading…
Reference in a new issue