feat: add roles, activation, superuser fields on user (#38)

This commit is contained in:
Hayden 2022-10-09 09:44:13 -08:00 committed by GitHub
parent a6d2fd45df
commit 0c90b05dca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 705 additions and 12 deletions

View file

@ -1503,6 +1503,9 @@ const docTemplate = `{
"id": {
"type": "string"
},
"isOwner": {
"type": "boolean"
},
"isSuperuser": {
"type": "boolean"
},

View file

@ -1495,6 +1495,9 @@
"id": {
"type": "string"
},
"isOwner": {
"type": "boolean"
},
"isSuperuser": {
"type": "boolean"
},

View file

@ -285,6 +285,8 @@ definitions:
type: string
id:
type: string
isOwner:
type: boolean
isSuperuser:
type: boolean
name:

View file

@ -312,6 +312,9 @@ var (
{Name: "email", Type: field.TypeString, Unique: true, Size: 255},
{Name: "password", Type: field.TypeString, Size: 255},
{Name: "is_superuser", Type: field.TypeBool, Default: false},
{Name: "role", Type: field.TypeEnum, Enums: []string{"user", "owner"}, Default: "user"},
{Name: "superuser", Type: field.TypeBool, Default: false},
{Name: "activated_on", Type: field.TypeTime, Nullable: true},
{Name: "group_users", Type: field.TypeUUID},
}
// UsersTable holds the schema information for the "users" table.
@ -322,7 +325,7 @@ var (
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "users_groups_users",
Columns: []*schema.Column{UsersColumns[7]},
Columns: []*schema.Column{UsersColumns[10]},
RefColumns: []*schema.Column{GroupsColumns[0]},
OnDelete: schema.Cascade,
},

View file

@ -8548,6 +8548,9 @@ type UserMutation struct {
email *string
password *string
is_superuser *bool
role *user.Role
superuser *bool
activated_on *time.Time
clearedFields map[string]struct{}
group *uuid.UUID
clearedgroup bool
@ -8879,6 +8882,127 @@ func (m *UserMutation) ResetIsSuperuser() {
m.is_superuser = nil
}
// SetRole sets the "role" field.
func (m *UserMutation) SetRole(u user.Role) {
m.role = &u
}
// Role returns the value of the "role" field in the mutation.
func (m *UserMutation) Role() (r user.Role, exists bool) {
v := m.role
if v == nil {
return
}
return *v, true
}
// OldRole returns the old "role" field's value of the User entity.
// If the User object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UserMutation) OldRole(ctx context.Context) (v user.Role, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldRole is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldRole requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldRole: %w", err)
}
return oldValue.Role, nil
}
// ResetRole resets all changes to the "role" field.
func (m *UserMutation) ResetRole() {
m.role = nil
}
// SetSuperuser sets the "superuser" field.
func (m *UserMutation) SetSuperuser(b bool) {
m.superuser = &b
}
// Superuser returns the value of the "superuser" field in the mutation.
func (m *UserMutation) Superuser() (r bool, exists bool) {
v := m.superuser
if v == nil {
return
}
return *v, true
}
// OldSuperuser returns the old "superuser" field's value of the User entity.
// If the User object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UserMutation) OldSuperuser(ctx context.Context) (v bool, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldSuperuser is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldSuperuser requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldSuperuser: %w", err)
}
return oldValue.Superuser, nil
}
// ResetSuperuser resets all changes to the "superuser" field.
func (m *UserMutation) ResetSuperuser() {
m.superuser = nil
}
// SetActivatedOn sets the "activated_on" field.
func (m *UserMutation) SetActivatedOn(t time.Time) {
m.activated_on = &t
}
// ActivatedOn returns the value of the "activated_on" field in the mutation.
func (m *UserMutation) ActivatedOn() (r time.Time, exists bool) {
v := m.activated_on
if v == nil {
return
}
return *v, true
}
// OldActivatedOn returns the old "activated_on" field's value of the User entity.
// If the User object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UserMutation) OldActivatedOn(ctx context.Context) (v time.Time, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldActivatedOn is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldActivatedOn requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldActivatedOn: %w", err)
}
return oldValue.ActivatedOn, nil
}
// ClearActivatedOn clears the value of the "activated_on" field.
func (m *UserMutation) ClearActivatedOn() {
m.activated_on = nil
m.clearedFields[user.FieldActivatedOn] = struct{}{}
}
// ActivatedOnCleared returns if the "activated_on" field was cleared in this mutation.
func (m *UserMutation) ActivatedOnCleared() bool {
_, ok := m.clearedFields[user.FieldActivatedOn]
return ok
}
// ResetActivatedOn resets all changes to the "activated_on" field.
func (m *UserMutation) ResetActivatedOn() {
m.activated_on = nil
delete(m.clearedFields, user.FieldActivatedOn)
}
// SetGroupID sets the "group" edge to the Group entity by id.
func (m *UserMutation) SetGroupID(id uuid.UUID) {
m.group = &id
@ -8991,7 +9115,7 @@ func (m *UserMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *UserMutation) Fields() []string {
fields := make([]string, 0, 6)
fields := make([]string, 0, 9)
if m.created_at != nil {
fields = append(fields, user.FieldCreatedAt)
}
@ -9010,6 +9134,15 @@ func (m *UserMutation) Fields() []string {
if m.is_superuser != nil {
fields = append(fields, user.FieldIsSuperuser)
}
if m.role != nil {
fields = append(fields, user.FieldRole)
}
if m.superuser != nil {
fields = append(fields, user.FieldSuperuser)
}
if m.activated_on != nil {
fields = append(fields, user.FieldActivatedOn)
}
return fields
}
@ -9030,6 +9163,12 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) {
return m.Password()
case user.FieldIsSuperuser:
return m.IsSuperuser()
case user.FieldRole:
return m.Role()
case user.FieldSuperuser:
return m.Superuser()
case user.FieldActivatedOn:
return m.ActivatedOn()
}
return nil, false
}
@ -9051,6 +9190,12 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er
return m.OldPassword(ctx)
case user.FieldIsSuperuser:
return m.OldIsSuperuser(ctx)
case user.FieldRole:
return m.OldRole(ctx)
case user.FieldSuperuser:
return m.OldSuperuser(ctx)
case user.FieldActivatedOn:
return m.OldActivatedOn(ctx)
}
return nil, fmt.Errorf("unknown User field %s", name)
}
@ -9102,6 +9247,27 @@ func (m *UserMutation) SetField(name string, value ent.Value) error {
}
m.SetIsSuperuser(v)
return nil
case user.FieldRole:
v, ok := value.(user.Role)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetRole(v)
return nil
case user.FieldSuperuser:
v, ok := value.(bool)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetSuperuser(v)
return nil
case user.FieldActivatedOn:
v, ok := value.(time.Time)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetActivatedOn(v)
return nil
}
return fmt.Errorf("unknown User field %s", name)
}
@ -9131,7 +9297,11 @@ func (m *UserMutation) AddField(name string, value ent.Value) error {
// ClearedFields returns all nullable fields that were cleared during this
// mutation.
func (m *UserMutation) ClearedFields() []string {
return nil
var fields []string
if m.FieldCleared(user.FieldActivatedOn) {
fields = append(fields, user.FieldActivatedOn)
}
return fields
}
// FieldCleared returns a boolean indicating if a field with the given name was
@ -9144,6 +9314,11 @@ func (m *UserMutation) FieldCleared(name string) bool {
// ClearField clears the value of the field with the given name. It returns an
// error if the field is not defined in the schema.
func (m *UserMutation) ClearField(name string) error {
switch name {
case user.FieldActivatedOn:
m.ClearActivatedOn()
return nil
}
return fmt.Errorf("unknown User nullable field %s", name)
}
@ -9169,6 +9344,15 @@ func (m *UserMutation) ResetField(name string) error {
case user.FieldIsSuperuser:
m.ResetIsSuperuser()
return nil
case user.FieldRole:
m.ResetRole()
return nil
case user.FieldSuperuser:
m.ResetSuperuser()
return nil
case user.FieldActivatedOn:
m.ResetActivatedOn()
return nil
}
return fmt.Errorf("unknown User field %s", name)
}

View file

@ -525,6 +525,10 @@ func init() {
userDescIsSuperuser := userFields[3].Descriptor()
// user.DefaultIsSuperuser holds the default value on creation for the is_superuser field.
user.DefaultIsSuperuser = userDescIsSuperuser.Default.(bool)
// userDescSuperuser is the schema descriptor for superuser field.
userDescSuperuser := userFields[5].Descriptor()
// user.DefaultSuperuser holds the default value on creation for the superuser field.
user.DefaultSuperuser = userDescSuperuser.Default.(bool)
// userDescID is the schema descriptor for id field.
userDescID := userMixinFields0[0].Descriptor()
// user.DefaultID holds the default value on creation for the id field.

View file

@ -35,6 +35,13 @@ func (User) Fields() []ent.Field {
Sensitive(),
field.Bool("is_superuser").
Default(false),
field.Enum("role").
Default("user").
Values("user", "owner"),
field.Bool("superuser").
Default(false),
field.Time("activated_on").
Optional(),
}
}

View file

@ -30,6 +30,12 @@ type User struct {
Password string `json:"-"`
// IsSuperuser holds the value of the "is_superuser" field.
IsSuperuser bool `json:"is_superuser,omitempty"`
// Role holds the value of the "role" field.
Role user.Role `json:"role,omitempty"`
// Superuser holds the value of the "superuser" field.
Superuser bool `json:"superuser,omitempty"`
// ActivatedOn holds the value of the "activated_on" field.
ActivatedOn time.Time `json:"activated_on,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the UserQuery when eager-loading is set.
Edges UserEdges `json:"edges"`
@ -74,11 +80,11 @@ func (*User) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case user.FieldIsSuperuser:
case user.FieldIsSuperuser, user.FieldSuperuser:
values[i] = new(sql.NullBool)
case user.FieldName, user.FieldEmail, user.FieldPassword:
case user.FieldName, user.FieldEmail, user.FieldPassword, user.FieldRole:
values[i] = new(sql.NullString)
case user.FieldCreatedAt, user.FieldUpdatedAt:
case user.FieldCreatedAt, user.FieldUpdatedAt, user.FieldActivatedOn:
values[i] = new(sql.NullTime)
case user.FieldID:
values[i] = new(uuid.UUID)
@ -141,6 +147,24 @@ func (u *User) assignValues(columns []string, values []any) error {
} else if value.Valid {
u.IsSuperuser = value.Bool
}
case user.FieldRole:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field role", values[i])
} else if value.Valid {
u.Role = user.Role(value.String)
}
case user.FieldSuperuser:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field superuser", values[i])
} else if value.Valid {
u.Superuser = value.Bool
}
case user.FieldActivatedOn:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field activated_on", values[i])
} else if value.Valid {
u.ActivatedOn = value.Time
}
case user.ForeignKeys[0]:
if value, ok := values[i].(*sql.NullScanner); !ok {
return fmt.Errorf("unexpected type %T for field group_users", values[i])
@ -202,6 +226,15 @@ func (u *User) String() string {
builder.WriteString(", ")
builder.WriteString("is_superuser=")
builder.WriteString(fmt.Sprintf("%v", u.IsSuperuser))
builder.WriteString(", ")
builder.WriteString("role=")
builder.WriteString(fmt.Sprintf("%v", u.Role))
builder.WriteString(", ")
builder.WriteString("superuser=")
builder.WriteString(fmt.Sprintf("%v", u.Superuser))
builder.WriteString(", ")
builder.WriteString("activated_on=")
builder.WriteString(u.ActivatedOn.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}

View file

@ -3,6 +3,7 @@
package user
import (
"fmt"
"time"
"github.com/google/uuid"
@ -25,6 +26,12 @@ const (
FieldPassword = "password"
// FieldIsSuperuser holds the string denoting the is_superuser field in the database.
FieldIsSuperuser = "is_superuser"
// FieldRole holds the string denoting the role field in the database.
FieldRole = "role"
// FieldSuperuser holds the string denoting the superuser field in the database.
FieldSuperuser = "superuser"
// FieldActivatedOn holds the string denoting the activated_on field in the database.
FieldActivatedOn = "activated_on"
// EdgeGroup holds the string denoting the group edge name in mutations.
EdgeGroup = "group"
// EdgeAuthTokens holds the string denoting the auth_tokens edge name in mutations.
@ -56,6 +63,9 @@ var Columns = []string{
FieldEmail,
FieldPassword,
FieldIsSuperuser,
FieldRole,
FieldSuperuser,
FieldActivatedOn,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the "users"
@ -94,6 +104,34 @@ var (
PasswordValidator func(string) error
// DefaultIsSuperuser holds the default value on creation for the "is_superuser" field.
DefaultIsSuperuser bool
// DefaultSuperuser holds the default value on creation for the "superuser" field.
DefaultSuperuser bool
// DefaultID holds the default value on creation for the "id" field.
DefaultID func() uuid.UUID
)
// Role defines the type for the "role" enum field.
type Role string
// RoleUser is the default value of the Role enum.
const DefaultRole = RoleUser
// Role values.
const (
RoleUser Role = "user"
RoleOwner Role = "owner"
)
func (r Role) String() string {
return string(r)
}
// RoleValidator is a validator for the "role" field enum values. It is called by the builders before save.
func RoleValidator(r Role) error {
switch r {
case RoleUser, RoleOwner:
return nil
default:
return fmt.Errorf("user: invalid enum value for role field: %q", r)
}
}

View file

@ -124,6 +124,20 @@ func IsSuperuser(v bool) predicate.User {
})
}
// Superuser applies equality check predicate on the "superuser" field. It's identical to SuperuserEQ.
func Superuser(v bool) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldSuperuser), v))
})
}
// ActivatedOn applies equality check predicate on the "activated_on" field. It's identical to ActivatedOnEQ.
func ActivatedOn(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldActivatedOn), v))
})
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
@ -563,6 +577,134 @@ func IsSuperuserNEQ(v bool) predicate.User {
})
}
// RoleEQ applies the EQ predicate on the "role" field.
func RoleEQ(v Role) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldRole), v))
})
}
// RoleNEQ applies the NEQ predicate on the "role" field.
func RoleNEQ(v Role) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldRole), v))
})
}
// RoleIn applies the In predicate on the "role" field.
func RoleIn(vs ...Role) predicate.User {
v := make([]any, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.User(func(s *sql.Selector) {
s.Where(sql.In(s.C(FieldRole), v...))
})
}
// RoleNotIn applies the NotIn predicate on the "role" field.
func RoleNotIn(vs ...Role) predicate.User {
v := make([]any, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.User(func(s *sql.Selector) {
s.Where(sql.NotIn(s.C(FieldRole), v...))
})
}
// SuperuserEQ applies the EQ predicate on the "superuser" field.
func SuperuserEQ(v bool) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldSuperuser), v))
})
}
// SuperuserNEQ applies the NEQ predicate on the "superuser" field.
func SuperuserNEQ(v bool) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldSuperuser), v))
})
}
// ActivatedOnEQ applies the EQ predicate on the "activated_on" field.
func ActivatedOnEQ(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldActivatedOn), v))
})
}
// ActivatedOnNEQ applies the NEQ predicate on the "activated_on" field.
func ActivatedOnNEQ(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldActivatedOn), v))
})
}
// ActivatedOnIn applies the In predicate on the "activated_on" field.
func ActivatedOnIn(vs ...time.Time) predicate.User {
v := make([]any, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.User(func(s *sql.Selector) {
s.Where(sql.In(s.C(FieldActivatedOn), v...))
})
}
// ActivatedOnNotIn applies the NotIn predicate on the "activated_on" field.
func ActivatedOnNotIn(vs ...time.Time) predicate.User {
v := make([]any, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.User(func(s *sql.Selector) {
s.Where(sql.NotIn(s.C(FieldActivatedOn), v...))
})
}
// ActivatedOnGT applies the GT predicate on the "activated_on" field.
func ActivatedOnGT(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldActivatedOn), v))
})
}
// ActivatedOnGTE applies the GTE predicate on the "activated_on" field.
func ActivatedOnGTE(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldActivatedOn), v))
})
}
// ActivatedOnLT applies the LT predicate on the "activated_on" field.
func ActivatedOnLT(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldActivatedOn), v))
})
}
// ActivatedOnLTE applies the LTE predicate on the "activated_on" field.
func ActivatedOnLTE(v time.Time) predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldActivatedOn), v))
})
}
// ActivatedOnIsNil applies the IsNil predicate on the "activated_on" field.
func ActivatedOnIsNil() predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.IsNull(s.C(FieldActivatedOn)))
})
}
// ActivatedOnNotNil applies the NotNil predicate on the "activated_on" field.
func ActivatedOnNotNil() predicate.User {
return predicate.User(func(s *sql.Selector) {
s.Where(sql.NotNull(s.C(FieldActivatedOn)))
})
}
// HasGroup applies the HasEdge predicate on the "group" edge.
func HasGroup() predicate.User {
return predicate.User(func(s *sql.Selector) {

View file

@ -83,6 +83,48 @@ func (uc *UserCreate) SetNillableIsSuperuser(b *bool) *UserCreate {
return uc
}
// SetRole sets the "role" field.
func (uc *UserCreate) SetRole(u user.Role) *UserCreate {
uc.mutation.SetRole(u)
return uc
}
// SetNillableRole sets the "role" field if the given value is not nil.
func (uc *UserCreate) SetNillableRole(u *user.Role) *UserCreate {
if u != nil {
uc.SetRole(*u)
}
return uc
}
// SetSuperuser sets the "superuser" field.
func (uc *UserCreate) SetSuperuser(b bool) *UserCreate {
uc.mutation.SetSuperuser(b)
return uc
}
// SetNillableSuperuser sets the "superuser" field if the given value is not nil.
func (uc *UserCreate) SetNillableSuperuser(b *bool) *UserCreate {
if b != nil {
uc.SetSuperuser(*b)
}
return uc
}
// SetActivatedOn sets the "activated_on" field.
func (uc *UserCreate) SetActivatedOn(t time.Time) *UserCreate {
uc.mutation.SetActivatedOn(t)
return uc
}
// SetNillableActivatedOn sets the "activated_on" field if the given value is not nil.
func (uc *UserCreate) SetNillableActivatedOn(t *time.Time) *UserCreate {
if t != nil {
uc.SetActivatedOn(*t)
}
return uc
}
// SetID sets the "id" field.
func (uc *UserCreate) SetID(u uuid.UUID) *UserCreate {
uc.mutation.SetID(u)
@ -212,6 +254,14 @@ func (uc *UserCreate) defaults() {
v := user.DefaultIsSuperuser
uc.mutation.SetIsSuperuser(v)
}
if _, ok := uc.mutation.Role(); !ok {
v := user.DefaultRole
uc.mutation.SetRole(v)
}
if _, ok := uc.mutation.Superuser(); !ok {
v := user.DefaultSuperuser
uc.mutation.SetSuperuser(v)
}
if _, ok := uc.mutation.ID(); !ok {
v := user.DefaultID()
uc.mutation.SetID(v)
@ -253,6 +303,17 @@ func (uc *UserCreate) check() error {
if _, ok := uc.mutation.IsSuperuser(); !ok {
return &ValidationError{Name: "is_superuser", err: errors.New(`ent: missing required field "User.is_superuser"`)}
}
if _, ok := uc.mutation.Role(); !ok {
return &ValidationError{Name: "role", err: errors.New(`ent: missing required field "User.role"`)}
}
if v, ok := uc.mutation.Role(); ok {
if err := user.RoleValidator(v); err != nil {
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "User.role": %w`, err)}
}
}
if _, ok := uc.mutation.Superuser(); !ok {
return &ValidationError{Name: "superuser", err: errors.New(`ent: missing required field "User.superuser"`)}
}
if _, ok := uc.mutation.GroupID(); !ok {
return &ValidationError{Name: "group", err: errors.New(`ent: missing required edge "User.group"`)}
}
@ -340,6 +401,30 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
})
_node.IsSuperuser = value
}
if value, ok := uc.mutation.Role(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeEnum,
Value: value,
Column: user.FieldRole,
})
_node.Role = value
}
if value, ok := uc.mutation.Superuser(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeBool,
Value: value,
Column: user.FieldSuperuser,
})
_node.Superuser = value
}
if value, ok := uc.mutation.ActivatedOn(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: user.FieldActivatedOn,
})
_node.ActivatedOn = value
}
if nodes := uc.mutation.GroupIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,

View file

@ -69,6 +69,54 @@ func (uu *UserUpdate) SetNillableIsSuperuser(b *bool) *UserUpdate {
return uu
}
// SetRole sets the "role" field.
func (uu *UserUpdate) SetRole(u user.Role) *UserUpdate {
uu.mutation.SetRole(u)
return uu
}
// SetNillableRole sets the "role" field if the given value is not nil.
func (uu *UserUpdate) SetNillableRole(u *user.Role) *UserUpdate {
if u != nil {
uu.SetRole(*u)
}
return uu
}
// SetSuperuser sets the "superuser" field.
func (uu *UserUpdate) SetSuperuser(b bool) *UserUpdate {
uu.mutation.SetSuperuser(b)
return uu
}
// SetNillableSuperuser sets the "superuser" field if the given value is not nil.
func (uu *UserUpdate) SetNillableSuperuser(b *bool) *UserUpdate {
if b != nil {
uu.SetSuperuser(*b)
}
return uu
}
// SetActivatedOn sets the "activated_on" field.
func (uu *UserUpdate) SetActivatedOn(t time.Time) *UserUpdate {
uu.mutation.SetActivatedOn(t)
return uu
}
// SetNillableActivatedOn sets the "activated_on" field if the given value is not nil.
func (uu *UserUpdate) SetNillableActivatedOn(t *time.Time) *UserUpdate {
if t != nil {
uu.SetActivatedOn(*t)
}
return uu
}
// ClearActivatedOn clears the value of the "activated_on" field.
func (uu *UserUpdate) ClearActivatedOn() *UserUpdate {
uu.mutation.ClearActivatedOn()
return uu
}
// SetGroupID sets the "group" edge to the Group entity by ID.
func (uu *UserUpdate) SetGroupID(id uuid.UUID) *UserUpdate {
uu.mutation.SetGroupID(id)
@ -213,6 +261,11 @@ func (uu *UserUpdate) check() error {
return &ValidationError{Name: "password", err: fmt.Errorf(`ent: validator failed for field "User.password": %w`, err)}
}
}
if v, ok := uu.mutation.Role(); ok {
if err := user.RoleValidator(v); err != nil {
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "User.role": %w`, err)}
}
}
if _, ok := uu.mutation.GroupID(); uu.mutation.GroupCleared() && !ok {
return errors.New(`ent: clearing a required unique edge "User.group"`)
}
@ -272,6 +325,33 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
Column: user.FieldIsSuperuser,
})
}
if value, ok := uu.mutation.Role(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeEnum,
Value: value,
Column: user.FieldRole,
})
}
if value, ok := uu.mutation.Superuser(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeBool,
Value: value,
Column: user.FieldSuperuser,
})
}
if value, ok := uu.mutation.ActivatedOn(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: user.FieldActivatedOn,
})
}
if uu.mutation.ActivatedOnCleared() {
_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Column: user.FieldActivatedOn,
})
}
if uu.mutation.GroupCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
@ -418,6 +498,54 @@ func (uuo *UserUpdateOne) SetNillableIsSuperuser(b *bool) *UserUpdateOne {
return uuo
}
// SetRole sets the "role" field.
func (uuo *UserUpdateOne) SetRole(u user.Role) *UserUpdateOne {
uuo.mutation.SetRole(u)
return uuo
}
// SetNillableRole sets the "role" field if the given value is not nil.
func (uuo *UserUpdateOne) SetNillableRole(u *user.Role) *UserUpdateOne {
if u != nil {
uuo.SetRole(*u)
}
return uuo
}
// SetSuperuser sets the "superuser" field.
func (uuo *UserUpdateOne) SetSuperuser(b bool) *UserUpdateOne {
uuo.mutation.SetSuperuser(b)
return uuo
}
// SetNillableSuperuser sets the "superuser" field if the given value is not nil.
func (uuo *UserUpdateOne) SetNillableSuperuser(b *bool) *UserUpdateOne {
if b != nil {
uuo.SetSuperuser(*b)
}
return uuo
}
// SetActivatedOn sets the "activated_on" field.
func (uuo *UserUpdateOne) SetActivatedOn(t time.Time) *UserUpdateOne {
uuo.mutation.SetActivatedOn(t)
return uuo
}
// SetNillableActivatedOn sets the "activated_on" field if the given value is not nil.
func (uuo *UserUpdateOne) SetNillableActivatedOn(t *time.Time) *UserUpdateOne {
if t != nil {
uuo.SetActivatedOn(*t)
}
return uuo
}
// ClearActivatedOn clears the value of the "activated_on" field.
func (uuo *UserUpdateOne) ClearActivatedOn() *UserUpdateOne {
uuo.mutation.ClearActivatedOn()
return uuo
}
// SetGroupID sets the "group" edge to the Group entity by ID.
func (uuo *UserUpdateOne) SetGroupID(id uuid.UUID) *UserUpdateOne {
uuo.mutation.SetGroupID(id)
@ -575,6 +703,11 @@ func (uuo *UserUpdateOne) check() error {
return &ValidationError{Name: "password", err: fmt.Errorf(`ent: validator failed for field "User.password": %w`, err)}
}
}
if v, ok := uuo.mutation.Role(); ok {
if err := user.RoleValidator(v); err != nil {
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "User.role": %w`, err)}
}
}
if _, ok := uuo.mutation.GroupID(); uuo.mutation.GroupCleared() && !ok {
return errors.New(`ent: clearing a required unique edge "User.group"`)
}
@ -651,6 +784,33 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error)
Column: user.FieldIsSuperuser,
})
}
if value, ok := uuo.mutation.Role(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeEnum,
Value: value,
Column: user.FieldRole,
})
}
if value, ok := uuo.mutation.Superuser(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeBool,
Value: value,
Column: user.FieldSuperuser,
})
}
if value, ok := uuo.mutation.ActivatedOn(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: user.FieldActivatedOn,
})
}
if uuo.mutation.ActivatedOnCleared() {
_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Column: user.FieldActivatedOn,
})
}
if uuo.mutation.GroupCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,

View file

@ -0,0 +1,14 @@
-- disable the enforcement of foreign-keys constraints
PRAGMA foreign_keys = off;
-- create "new_users" table
CREATE TABLE `new_users` (`id` uuid NOT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `name` text NOT NULL, `email` text NOT NULL, `password` text NOT NULL, `is_superuser` bool NOT NULL DEFAULT false, `role` text NOT NULL DEFAULT 'user', `superuser` bool NOT NULL DEFAULT false, `activated_on` datetime NULL, `group_users` uuid NOT NULL, PRIMARY KEY (`id`), CONSTRAINT `users_groups_users` FOREIGN KEY (`group_users`) REFERENCES `groups` (`id`) ON DELETE CASCADE);
-- copy rows from old table "users" to new temporary table "new_users"
INSERT INTO `new_users` (`id`, `created_at`, `updated_at`, `name`, `email`, `password`, `is_superuser`, `group_users`) SELECT `id`, `created_at`, `updated_at`, `name`, `email`, `password`, `is_superuser`, `group_users` FROM `users`;
-- drop "users" table after copying rows
DROP TABLE `users`;
-- rename temporary table "new_users" to "users"
ALTER TABLE `new_users` RENAME TO `users`;
-- create index "users_email_key" to table: "users"
CREATE UNIQUE INDEX `users_email_key` ON `users` (`email`);
-- enable back the enforcement of foreign-keys constraints
PRAGMA foreign_keys = on;

View file

@ -1,3 +1,4 @@
h1:JE1IHs4N6SqydqXavjqcO40KuPMZ4uA9q9eQmqeYI/o=
h1:nN8ZUHScToap+2yJKsb+AnKu8o2DubUoiKc9neQJ93M=
20220929052825_init.sql h1:ZlCqm1wzjDmofeAcSX3jE4h4VcdTNGpRg2eabztDy9Q=
20221001210956_group_invitations.sql h1:YQKJFtE39wFOcRNbZQ/d+ZlHwrcfcsZlcv/pLEYdpjw=
20221009173029_add_user_roles.sql h1:vWmzAfgEWQeGk0Vn70zfVPCcfEZth3E0JcvyKTjpYyU=

View file

@ -22,6 +22,7 @@ type (
Password string `json:"password"`
IsSuperuser bool `json:"isSuperuser"`
GroupID uuid.UUID `json:"groupID"`
IsOwner bool `json:"isOwner"`
}
UserUpdate struct {
@ -37,6 +38,7 @@ type (
GroupID uuid.UUID `json:"groupId"`
GroupName string `json:"groupName"`
PasswordHash string `json:"-"`
IsOwner bool `json:"isOwner"`
}
)
@ -54,6 +56,7 @@ func mapUserOut(user *ent.User) UserOut {
GroupID: user.Edges.Group.ID,
GroupName: user.Edges.Group.Name,
PasswordHash: user.Password,
IsOwner: user.Role == "owner",
}
}
@ -77,6 +80,11 @@ func (e *UserRepository) GetAll(ctx context.Context) ([]UserOut, error) {
}
func (e *UserRepository) Create(ctx context.Context, usr UserCreate) (UserOut, error) {
role := user.RoleUser
if usr.IsOwner {
role = user.RoleOwner
}
entUser, err := e.db.User.
Create().
SetName(usr.Name).
@ -84,6 +92,7 @@ func (e *UserRepository) Create(ctx context.Context, usr UserCreate) (UserOut, e
SetPassword(usr.Password).
SetIsSuperuser(usr.IsSuperuser).
SetGroupID(usr.GroupID).
SetRole(role).
Save(ctx)
if err != nil {
return UserOut{}, err

View file

@ -49,18 +49,21 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
Msg("Registering new user")
var (
err error
group repo.Group
token repo.GroupInvitation
err error
group repo.Group
token repo.GroupInvitation
isOwner = false
)
if data.GroupToken == "" {
switch data.GroupToken {
case "":
isOwner = true
group, err = svc.repos.Groups.GroupCreate(ctx, "Home")
if err != nil {
log.Err(err).Msg("Failed to create group")
return repo.UserOut{}, err
}
} else {
default:
token, err = svc.repos.Groups.InvitationGet(ctx, hasher.HashToken(data.GroupToken))
if err != nil {
log.Err(err).Msg("Failed to get invitation token")
@ -76,6 +79,7 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
Password: hashed,
IsSuperuser: false,
GroupID: group.ID,
IsOwner: isOwner,
}
usr, err := svc.repos.Users.Create(ctx, usrCreate)

View file

@ -192,6 +192,7 @@ export interface UserOut {
groupId: string;
groupName: string;
id: string;
isOwner: boolean;
isSuperuser: boolean;
name: string;
}