diff --git a/server/server_test.go b/server/server_test.go index 312c0de9..e0647196 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -1281,7 +1281,9 @@ func TestPasswordDB(t *testing.T) { s.CreatePassword(ctx, storage.Password{ Email: "jane@example.com", Username: "jane", + Name: "Jane Doe", PreferredUsername: "jane-public", + EmailVerified: boolPtr(false), UserID: "foobar", Groups: []string{"team-a", "team-a/admins"}, Hash: h, @@ -1301,10 +1303,10 @@ func TestPasswordDB(t *testing.T) { password: pw, wantIdentity: connector.Identity{ Email: "jane@example.com", - Username: "jane", + Username: "Jane Doe", PreferredUsername: "jane-public", UserID: "foobar", - EmailVerified: true, + EmailVerified: false, Groups: []string{"team-a", "team-a/admins"}, }, }, diff --git a/storage/conformance/conformance.go b/storage/conformance/conformance.go index 333561d9..b8c1b96d 100644 --- a/storage/conformance/conformance.go +++ b/storage/conformance/conformance.go @@ -447,6 +447,10 @@ func (n byEmail) Len() int { return len(n) } func (n byEmail) Less(i, j int) bool { return n[i].Email < n[j].Email } func (n byEmail) Swap(i, j int) { n[i], n[j] = n[j], n[i] } +func boolPtr(v bool) *bool { + return &v +} + func testPasswordCRUD(t *testing.T, s storage.Storage) { ctx := t.Context() // Use bcrypt.MinCost to keep the tests short. @@ -459,7 +463,9 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) { Email: "jane@example.com", Hash: passwordHash1, Username: "jane", + Name: "Jane Doe", PreferredUsername: "jane-public", + EmailVerified: boolPtr(true), UserID: "foobar", Groups: []string{"team-a", "team-a/admins"}, } @@ -480,7 +486,9 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) { Email: "john@example.com", Hash: passwordHash2, Username: "john", + Name: "John Smith", PreferredUsername: "john-public", + EmailVerified: boolPtr(false), UserID: "barfoo", Groups: []string{"team-b"}, } diff --git a/storage/conformance/transactions.go b/storage/conformance/transactions.go index a67a6d7d..1383c8e7 100644 --- a/storage/conformance/transactions.go +++ b/storage/conformance/transactions.go @@ -110,10 +110,14 @@ func testPasswordConcurrentUpdate(t *testing.T, s storage.Storage) { } password := storage.Password{ - Email: "jane@example.com", - Hash: passwordHash, - Username: "jane", - UserID: "foobar", + Email: "jane@example.com", + Hash: passwordHash, + Username: "jane", + Name: "Jane Doe", + PreferredUsername: "jane-public", + EmailVerified: boolPtr(true), + UserID: "foobar", + Groups: []string{"team-a"}, } if err := s.CreatePassword(ctx, password); err != nil { t.Fatalf("create password token: %v", err) diff --git a/storage/ent/client/password.go b/storage/ent/client/password.go index c2dc07ca..183c5b14 100644 --- a/storage/ent/client/password.go +++ b/storage/ent/client/password.go @@ -14,7 +14,9 @@ func (d *Database) CreatePassword(ctx context.Context, password storage.Password SetEmail(password.Email). SetHash(password.Hash). SetUsername(password.Username). + SetName(password.Name). SetPreferredUsername(password.PreferredUsername). + SetNillableEmailVerified(password.EmailVerified). SetUserID(password.UserID). SetGroups(password.Groups). Save(ctx) @@ -88,7 +90,9 @@ func (d *Database) UpdatePassword(ctx context.Context, email string, updater fun SetEmail(newPassword.Email). SetHash(newPassword.Hash). SetUsername(newPassword.Username). + SetName(newPassword.Name). SetPreferredUsername(newPassword.PreferredUsername). + SetNillableEmailVerified(newPassword.EmailVerified). SetUserID(newPassword.UserID). SetGroups(newPassword.Groups). Save(ctx) diff --git a/storage/ent/client/types.go b/storage/ent/client/types.go index 27f20cfa..ab8ee83f 100644 --- a/storage/ent/client/types.go +++ b/storage/ent/client/types.go @@ -142,7 +142,9 @@ func toStoragePassword(p *db.Password) storage.Password { Email: p.Email, Hash: p.Hash, Username: p.Username, + Name: p.Name, PreferredUsername: p.PreferredUsername, + EmailVerified: p.EmailVerified, UserID: p.UserID, Groups: p.Groups, } diff --git a/storage/ent/db/migrate/schema.go b/storage/ent/db/migrate/schema.go index 3fee7bd5..b61d4697 100644 --- a/storage/ent/db/migrate/schema.go +++ b/storage/ent/db/migrate/schema.go @@ -161,7 +161,9 @@ var ( {Name: "email", Type: field.TypeString, Unique: true, Size: 2147483647, SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}}, {Name: "hash", Type: field.TypeBytes}, {Name: "username", Type: field.TypeString, Size: 2147483647, SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}}, + {Name: "name", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}}, {Name: "preferred_username", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}}, + {Name: "email_verified", Type: field.TypeBool, Nullable: true}, {Name: "user_id", Type: field.TypeString, Size: 2147483647, SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}}, {Name: "groups", Type: field.TypeJSON, Nullable: true}, } diff --git a/storage/ent/db/mutation.go b/storage/ent/db/mutation.go index e0c1cc48..a5cb61d2 100644 --- a/storage/ent/db/mutation.go +++ b/storage/ent/db/mutation.go @@ -6320,7 +6320,9 @@ type PasswordMutation struct { email *string hash *[]byte username *string + name *string preferred_username *string + email_verified *bool user_id *string groups *[]string appendgroups []string @@ -6536,6 +6538,42 @@ func (m *PasswordMutation) ResetUsername() { m.username = nil } +// SetName sets the "name" field. +func (m *PasswordMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *PasswordMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the Password entity. +// If the Password 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 *PasswordMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *PasswordMutation) ResetName() { + m.name = nil +} + // SetPreferredUsername sets the "preferred_username" field. func (m *PasswordMutation) SetPreferredUsername(s string) { m.preferred_username = &s @@ -6572,6 +6610,55 @@ func (m *PasswordMutation) ResetPreferredUsername() { m.preferred_username = nil } +// SetEmailVerified sets the "email_verified" field. +func (m *PasswordMutation) SetEmailVerified(b bool) { + m.email_verified = &b +} + +// EmailVerified returns the value of the "email_verified" field in the mutation. +func (m *PasswordMutation) EmailVerified() (r bool, exists bool) { + v := m.email_verified + if v == nil { + return + } + return *v, true +} + +// OldEmailVerified returns the old "email_verified" field's value of the Password entity. +// If the Password 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 *PasswordMutation) OldEmailVerified(ctx context.Context) (v *bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldEmailVerified is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldEmailVerified requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldEmailVerified: %w", err) + } + return oldValue.EmailVerified, nil +} + +// ClearEmailVerified clears the value of the "email_verified" field. +func (m *PasswordMutation) ClearEmailVerified() { + m.email_verified = nil + m.clearedFields[password.FieldEmailVerified] = struct{}{} +} + +// EmailVerifiedCleared returns if the "email_verified" field was cleared in this mutation. +func (m *PasswordMutation) EmailVerifiedCleared() bool { + _, ok := m.clearedFields[password.FieldEmailVerified] + return ok +} + +// ResetEmailVerified resets all changes to the "email_verified" field. +func (m *PasswordMutation) ResetEmailVerified() { + m.email_verified = nil + delete(m.clearedFields, password.FieldEmailVerified) +} + // SetUserID sets the "user_id" field. func (m *PasswordMutation) SetUserID(s string) { m.user_id = &s @@ -6707,7 +6794,7 @@ func (m *PasswordMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *PasswordMutation) Fields() []string { - fields := make([]string, 0, 6) + fields := make([]string, 0, 8) if m.email != nil { fields = append(fields, password.FieldEmail) } @@ -6717,9 +6804,15 @@ func (m *PasswordMutation) Fields() []string { if m.username != nil { fields = append(fields, password.FieldUsername) } + if m.name != nil { + fields = append(fields, password.FieldName) + } if m.preferred_username != nil { fields = append(fields, password.FieldPreferredUsername) } + if m.email_verified != nil { + fields = append(fields, password.FieldEmailVerified) + } if m.user_id != nil { fields = append(fields, password.FieldUserID) } @@ -6740,8 +6833,12 @@ func (m *PasswordMutation) Field(name string) (ent.Value, bool) { return m.Hash() case password.FieldUsername: return m.Username() + case password.FieldName: + return m.Name() case password.FieldPreferredUsername: return m.PreferredUsername() + case password.FieldEmailVerified: + return m.EmailVerified() case password.FieldUserID: return m.UserID() case password.FieldGroups: @@ -6761,8 +6858,12 @@ func (m *PasswordMutation) OldField(ctx context.Context, name string) (ent.Value return m.OldHash(ctx) case password.FieldUsername: return m.OldUsername(ctx) + case password.FieldName: + return m.OldName(ctx) case password.FieldPreferredUsername: return m.OldPreferredUsername(ctx) + case password.FieldEmailVerified: + return m.OldEmailVerified(ctx) case password.FieldUserID: return m.OldUserID(ctx) case password.FieldGroups: @@ -6797,6 +6898,13 @@ func (m *PasswordMutation) SetField(name string, value ent.Value) error { } m.SetUsername(v) return nil + case password.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil case password.FieldPreferredUsername: v, ok := value.(string) if !ok { @@ -6804,6 +6912,13 @@ func (m *PasswordMutation) SetField(name string, value ent.Value) error { } m.SetPreferredUsername(v) return nil + case password.FieldEmailVerified: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetEmailVerified(v) + return nil case password.FieldUserID: v, ok := value.(string) if !ok { @@ -6848,6 +6963,9 @@ func (m *PasswordMutation) AddField(name string, value ent.Value) error { // mutation. func (m *PasswordMutation) ClearedFields() []string { var fields []string + if m.FieldCleared(password.FieldEmailVerified) { + fields = append(fields, password.FieldEmailVerified) + } if m.FieldCleared(password.FieldGroups) { fields = append(fields, password.FieldGroups) } @@ -6865,6 +6983,9 @@ func (m *PasswordMutation) FieldCleared(name string) bool { // error if the field is not defined in the schema. func (m *PasswordMutation) ClearField(name string) error { switch name { + case password.FieldEmailVerified: + m.ClearEmailVerified() + return nil case password.FieldGroups: m.ClearGroups() return nil @@ -6885,9 +7006,15 @@ func (m *PasswordMutation) ResetField(name string) error { case password.FieldUsername: m.ResetUsername() return nil + case password.FieldName: + m.ResetName() + return nil case password.FieldPreferredUsername: m.ResetPreferredUsername() return nil + case password.FieldEmailVerified: + m.ResetEmailVerified() + return nil case password.FieldUserID: m.ResetUserID() return nil diff --git a/storage/ent/db/password.go b/storage/ent/db/password.go index 26f4089b..2bcd0217 100644 --- a/storage/ent/db/password.go +++ b/storage/ent/db/password.go @@ -23,8 +23,12 @@ type Password struct { Hash []byte `json:"hash,omitempty"` // Username holds the value of the "username" field. Username string `json:"username,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` // PreferredUsername holds the value of the "preferred_username" field. PreferredUsername string `json:"preferred_username,omitempty"` + // EmailVerified holds the value of the "email_verified" field. + EmailVerified *bool `json:"email_verified,omitempty"` // UserID holds the value of the "user_id" field. UserID string `json:"user_id,omitempty"` // Groups holds the value of the "groups" field. @@ -39,9 +43,11 @@ func (*Password) scanValues(columns []string) ([]any, error) { switch columns[i] { case password.FieldHash, password.FieldGroups: values[i] = new([]byte) + case password.FieldEmailVerified: + values[i] = new(sql.NullBool) case password.FieldID: values[i] = new(sql.NullInt64) - case password.FieldEmail, password.FieldUsername, password.FieldPreferredUsername, password.FieldUserID: + case password.FieldEmail, password.FieldUsername, password.FieldName, password.FieldPreferredUsername, password.FieldUserID: values[i] = new(sql.NullString) default: values[i] = new(sql.UnknownType) @@ -82,12 +88,25 @@ func (_m *Password) assignValues(columns []string, values []any) error { } else if value.Valid { _m.Username = value.String } + case password.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + _m.Name = value.String + } case password.FieldPreferredUsername: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field preferred_username", values[i]) } else if value.Valid { _m.PreferredUsername = value.String } + case password.FieldEmailVerified: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field email_verified", values[i]) + } else if value.Valid { + _m.EmailVerified = new(bool) + *_m.EmailVerified = value.Bool + } case password.FieldUserID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field user_id", values[i]) @@ -147,9 +166,17 @@ func (_m *Password) String() string { builder.WriteString("username=") builder.WriteString(_m.Username) builder.WriteString(", ") + builder.WriteString("name=") + builder.WriteString(_m.Name) + builder.WriteString(", ") builder.WriteString("preferred_username=") builder.WriteString(_m.PreferredUsername) builder.WriteString(", ") + if v := _m.EmailVerified; v != nil { + builder.WriteString("email_verified=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") builder.WriteString("user_id=") builder.WriteString(_m.UserID) builder.WriteString(", ") diff --git a/storage/ent/db/password/password.go b/storage/ent/db/password/password.go index 4502db30..62080ecf 100644 --- a/storage/ent/db/password/password.go +++ b/storage/ent/db/password/password.go @@ -17,8 +17,12 @@ const ( FieldHash = "hash" // FieldUsername holds the string denoting the username field in the database. FieldUsername = "username" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" // FieldPreferredUsername holds the string denoting the preferred_username field in the database. FieldPreferredUsername = "preferred_username" + // FieldEmailVerified holds the string denoting the email_verified field in the database. + FieldEmailVerified = "email_verified" // FieldUserID holds the string denoting the user_id field in the database. FieldUserID = "user_id" // FieldGroups holds the string denoting the groups field in the database. @@ -33,7 +37,9 @@ var Columns = []string{ FieldEmail, FieldHash, FieldUsername, + FieldName, FieldPreferredUsername, + FieldEmailVerified, FieldUserID, FieldGroups, } @@ -53,6 +59,8 @@ var ( EmailValidator func(string) error // UsernameValidator is a validator for the "username" field. It is called by the builders before save. UsernameValidator func(string) error + // DefaultName holds the default value on creation for the "name" field. + DefaultName string // DefaultPreferredUsername holds the default value on creation for the "preferred_username" field. DefaultPreferredUsername string // UserIDValidator is a validator for the "user_id" field. It is called by the builders before save. @@ -77,11 +85,21 @@ func ByUsername(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldUsername, opts...).ToFunc() } +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + // ByPreferredUsername orders the results by the preferred_username field. func ByPreferredUsername(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldPreferredUsername, opts...).ToFunc() } +// ByEmailVerified orders the results by the email_verified field. +func ByEmailVerified(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldEmailVerified, opts...).ToFunc() +} + // ByUserID orders the results by the user_id field. func ByUserID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldUserID, opts...).ToFunc() diff --git a/storage/ent/db/password/where.go b/storage/ent/db/password/where.go index f710e248..91607186 100644 --- a/storage/ent/db/password/where.go +++ b/storage/ent/db/password/where.go @@ -67,11 +67,21 @@ func Username(v string) predicate.Password { return predicate.Password(sql.FieldEQ(FieldUsername, v)) } +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.Password { + return predicate.Password(sql.FieldEQ(FieldName, v)) +} + // PreferredUsername applies equality check predicate on the "preferred_username" field. It's identical to PreferredUsernameEQ. func PreferredUsername(v string) predicate.Password { return predicate.Password(sql.FieldEQ(FieldPreferredUsername, v)) } +// EmailVerified applies equality check predicate on the "email_verified" field. It's identical to EmailVerifiedEQ. +func EmailVerified(v bool) predicate.Password { + return predicate.Password(sql.FieldEQ(FieldEmailVerified, v)) +} + // UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. func UserID(v string) predicate.Password { return predicate.Password(sql.FieldEQ(FieldUserID, v)) @@ -247,6 +257,71 @@ func UsernameContainsFold(v string) predicate.Password { return predicate.Password(sql.FieldContainsFold(FieldUsername, v)) } +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.Password { + return predicate.Password(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.Password { + return predicate.Password(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.Password { + return predicate.Password(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.Password { + return predicate.Password(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.Password { + return predicate.Password(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.Password { + return predicate.Password(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.Password { + return predicate.Password(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.Password { + return predicate.Password(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.Password { + return predicate.Password(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.Password { + return predicate.Password(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.Password { + return predicate.Password(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.Password { + return predicate.Password(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.Password { + return predicate.Password(sql.FieldContainsFold(FieldName, v)) +} + // PreferredUsernameEQ applies the EQ predicate on the "preferred_username" field. func PreferredUsernameEQ(v string) predicate.Password { return predicate.Password(sql.FieldEQ(FieldPreferredUsername, v)) @@ -312,6 +387,26 @@ func PreferredUsernameContainsFold(v string) predicate.Password { return predicate.Password(sql.FieldContainsFold(FieldPreferredUsername, v)) } +// EmailVerifiedEQ applies the EQ predicate on the "email_verified" field. +func EmailVerifiedEQ(v bool) predicate.Password { + return predicate.Password(sql.FieldEQ(FieldEmailVerified, v)) +} + +// EmailVerifiedNEQ applies the NEQ predicate on the "email_verified" field. +func EmailVerifiedNEQ(v bool) predicate.Password { + return predicate.Password(sql.FieldNEQ(FieldEmailVerified, v)) +} + +// EmailVerifiedIsNil applies the IsNil predicate on the "email_verified" field. +func EmailVerifiedIsNil() predicate.Password { + return predicate.Password(sql.FieldIsNull(FieldEmailVerified)) +} + +// EmailVerifiedNotNil applies the NotNil predicate on the "email_verified" field. +func EmailVerifiedNotNil() predicate.Password { + return predicate.Password(sql.FieldNotNull(FieldEmailVerified)) +} + // UserIDEQ applies the EQ predicate on the "user_id" field. func UserIDEQ(v string) predicate.Password { return predicate.Password(sql.FieldEQ(FieldUserID, v)) diff --git a/storage/ent/db/password_create.go b/storage/ent/db/password_create.go index b5cbf325..229b3a93 100644 --- a/storage/ent/db/password_create.go +++ b/storage/ent/db/password_create.go @@ -37,6 +37,20 @@ func (_c *PasswordCreate) SetUsername(v string) *PasswordCreate { return _c } +// SetName sets the "name" field. +func (_c *PasswordCreate) SetName(v string) *PasswordCreate { + _c.mutation.SetName(v) + return _c +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_c *PasswordCreate) SetNillableName(v *string) *PasswordCreate { + if v != nil { + _c.SetName(*v) + } + return _c +} + // SetPreferredUsername sets the "preferred_username" field. func (_c *PasswordCreate) SetPreferredUsername(v string) *PasswordCreate { _c.mutation.SetPreferredUsername(v) @@ -51,6 +65,20 @@ func (_c *PasswordCreate) SetNillablePreferredUsername(v *string) *PasswordCreat return _c } +// SetEmailVerified sets the "email_verified" field. +func (_c *PasswordCreate) SetEmailVerified(v bool) *PasswordCreate { + _c.mutation.SetEmailVerified(v) + return _c +} + +// SetNillableEmailVerified sets the "email_verified" field if the given value is not nil. +func (_c *PasswordCreate) SetNillableEmailVerified(v *bool) *PasswordCreate { + if v != nil { + _c.SetEmailVerified(*v) + } + return _c +} + // SetUserID sets the "user_id" field. func (_c *PasswordCreate) SetUserID(v string) *PasswordCreate { _c.mutation.SetUserID(v) @@ -98,6 +126,10 @@ func (_c *PasswordCreate) ExecX(ctx context.Context) { // defaults sets the default values of the builder before save. func (_c *PasswordCreate) defaults() { + if _, ok := _c.mutation.Name(); !ok { + v := password.DefaultName + _c.mutation.SetName(v) + } if _, ok := _c.mutation.PreferredUsername(); !ok { v := password.DefaultPreferredUsername _c.mutation.SetPreferredUsername(v) @@ -125,6 +157,9 @@ func (_c *PasswordCreate) check() error { return &ValidationError{Name: "username", err: fmt.Errorf(`db: validator failed for field "Password.username": %w`, err)} } } + if _, ok := _c.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`db: missing required field "Password.name"`)} + } if _, ok := _c.mutation.PreferredUsername(); !ok { return &ValidationError{Name: "preferred_username", err: errors.New(`db: missing required field "Password.preferred_username"`)} } @@ -174,10 +209,18 @@ func (_c *PasswordCreate) createSpec() (*Password, *sqlgraph.CreateSpec) { _spec.SetField(password.FieldUsername, field.TypeString, value) _node.Username = value } + if value, ok := _c.mutation.Name(); ok { + _spec.SetField(password.FieldName, field.TypeString, value) + _node.Name = value + } if value, ok := _c.mutation.PreferredUsername(); ok { _spec.SetField(password.FieldPreferredUsername, field.TypeString, value) _node.PreferredUsername = value } + if value, ok := _c.mutation.EmailVerified(); ok { + _spec.SetField(password.FieldEmailVerified, field.TypeBool, value) + _node.EmailVerified = &value + } if value, ok := _c.mutation.UserID(); ok { _spec.SetField(password.FieldUserID, field.TypeString, value) _node.UserID = value diff --git a/storage/ent/db/password_update.go b/storage/ent/db/password_update.go index 3c5f7f05..bda17ab6 100644 --- a/storage/ent/db/password_update.go +++ b/storage/ent/db/password_update.go @@ -62,6 +62,20 @@ func (_u *PasswordUpdate) SetNillableUsername(v *string) *PasswordUpdate { return _u } +// SetName sets the "name" field. +func (_u *PasswordUpdate) SetName(v string) *PasswordUpdate { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *PasswordUpdate) SetNillableName(v *string) *PasswordUpdate { + if v != nil { + _u.SetName(*v) + } + return _u +} + // SetPreferredUsername sets the "preferred_username" field. func (_u *PasswordUpdate) SetPreferredUsername(v string) *PasswordUpdate { _u.mutation.SetPreferredUsername(v) @@ -76,6 +90,26 @@ func (_u *PasswordUpdate) SetNillablePreferredUsername(v *string) *PasswordUpdat return _u } +// SetEmailVerified sets the "email_verified" field. +func (_u *PasswordUpdate) SetEmailVerified(v bool) *PasswordUpdate { + _u.mutation.SetEmailVerified(v) + return _u +} + +// SetNillableEmailVerified sets the "email_verified" field if the given value is not nil. +func (_u *PasswordUpdate) SetNillableEmailVerified(v *bool) *PasswordUpdate { + if v != nil { + _u.SetEmailVerified(*v) + } + return _u +} + +// ClearEmailVerified clears the value of the "email_verified" field. +func (_u *PasswordUpdate) ClearEmailVerified() *PasswordUpdate { + _u.mutation.ClearEmailVerified() + return _u +} + // SetUserID sets the "user_id" field. func (_u *PasswordUpdate) SetUserID(v string) *PasswordUpdate { _u.mutation.SetUserID(v) @@ -181,9 +215,18 @@ func (_u *PasswordUpdate) sqlSave(ctx context.Context) (_node int, err error) { if value, ok := _u.mutation.Username(); ok { _spec.SetField(password.FieldUsername, field.TypeString, value) } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(password.FieldName, field.TypeString, value) + } if value, ok := _u.mutation.PreferredUsername(); ok { _spec.SetField(password.FieldPreferredUsername, field.TypeString, value) } + if value, ok := _u.mutation.EmailVerified(); ok { + _spec.SetField(password.FieldEmailVerified, field.TypeBool, value) + } + if _u.mutation.EmailVerifiedCleared() { + _spec.ClearField(password.FieldEmailVerified, field.TypeBool) + } if value, ok := _u.mutation.UserID(); ok { _spec.SetField(password.FieldUserID, field.TypeString, value) } @@ -252,6 +295,20 @@ func (_u *PasswordUpdateOne) SetNillableUsername(v *string) *PasswordUpdateOne { return _u } +// SetName sets the "name" field. +func (_u *PasswordUpdateOne) SetName(v string) *PasswordUpdateOne { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *PasswordUpdateOne) SetNillableName(v *string) *PasswordUpdateOne { + if v != nil { + _u.SetName(*v) + } + return _u +} + // SetPreferredUsername sets the "preferred_username" field. func (_u *PasswordUpdateOne) SetPreferredUsername(v string) *PasswordUpdateOne { _u.mutation.SetPreferredUsername(v) @@ -266,6 +323,26 @@ func (_u *PasswordUpdateOne) SetNillablePreferredUsername(v *string) *PasswordUp return _u } +// SetEmailVerified sets the "email_verified" field. +func (_u *PasswordUpdateOne) SetEmailVerified(v bool) *PasswordUpdateOne { + _u.mutation.SetEmailVerified(v) + return _u +} + +// SetNillableEmailVerified sets the "email_verified" field if the given value is not nil. +func (_u *PasswordUpdateOne) SetNillableEmailVerified(v *bool) *PasswordUpdateOne { + if v != nil { + _u.SetEmailVerified(*v) + } + return _u +} + +// ClearEmailVerified clears the value of the "email_verified" field. +func (_u *PasswordUpdateOne) ClearEmailVerified() *PasswordUpdateOne { + _u.mutation.ClearEmailVerified() + return _u +} + // SetUserID sets the "user_id" field. func (_u *PasswordUpdateOne) SetUserID(v string) *PasswordUpdateOne { _u.mutation.SetUserID(v) @@ -401,9 +478,18 @@ func (_u *PasswordUpdateOne) sqlSave(ctx context.Context) (_node *Password, err if value, ok := _u.mutation.Username(); ok { _spec.SetField(password.FieldUsername, field.TypeString, value) } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(password.FieldName, field.TypeString, value) + } if value, ok := _u.mutation.PreferredUsername(); ok { _spec.SetField(password.FieldPreferredUsername, field.TypeString, value) } + if value, ok := _u.mutation.EmailVerified(); ok { + _spec.SetField(password.FieldEmailVerified, field.TypeBool, value) + } + if _u.mutation.EmailVerifiedCleared() { + _spec.ClearField(password.FieldEmailVerified, field.TypeBool) + } if value, ok := _u.mutation.UserID(); ok { _spec.SetField(password.FieldUserID, field.TypeString, value) } diff --git a/storage/ent/db/runtime.go b/storage/ent/db/runtime.go index 055a7217..fdb47bd7 100644 --- a/storage/ent/db/runtime.go +++ b/storage/ent/db/runtime.go @@ -212,12 +212,16 @@ func init() { passwordDescUsername := passwordFields[2].Descriptor() // password.UsernameValidator is a validator for the "username" field. It is called by the builders before save. password.UsernameValidator = passwordDescUsername.Validators[0].(func(string) error) + // passwordDescName is the schema descriptor for name field. + passwordDescName := passwordFields[3].Descriptor() + // password.DefaultName holds the default value on creation for the name field. + password.DefaultName = passwordDescName.Default.(string) // passwordDescPreferredUsername is the schema descriptor for preferred_username field. - passwordDescPreferredUsername := passwordFields[3].Descriptor() + passwordDescPreferredUsername := passwordFields[4].Descriptor() // password.DefaultPreferredUsername holds the default value on creation for the preferred_username field. password.DefaultPreferredUsername = passwordDescPreferredUsername.Default.(string) // passwordDescUserID is the schema descriptor for user_id field. - passwordDescUserID := passwordFields[4].Descriptor() + passwordDescUserID := passwordFields[6].Descriptor() // password.UserIDValidator is a validator for the "user_id" field. It is called by the builders before save. password.UserIDValidator = passwordDescUserID.Validators[0].(func(string) error) refreshtokenFields := schema.RefreshToken{}.Fields() diff --git a/storage/ent/schema/password.go b/storage/ent/schema/password.go index af7513c1..adc0fbfd 100644 --- a/storage/ent/schema/password.go +++ b/storage/ent/schema/password.go @@ -32,9 +32,15 @@ func (Password) Fields() []ent.Field { field.Text("username"). SchemaType(textSchema). NotEmpty(), + field.Text("name"). + SchemaType(textSchema). + Default(""), field.Text("preferred_username"). SchemaType(textSchema). Default(""), + field.Bool("email_verified"). + Optional(). + Nillable(), field.Text("user_id"). SchemaType(textSchema). NotEmpty(), diff --git a/storage/kubernetes/types.go b/storage/kubernetes/types.go index a9806add..9e0f7e68 100644 --- a/storage/kubernetes/types.go +++ b/storage/kubernetes/types.go @@ -433,7 +433,9 @@ type Password struct { Hash []byte `json:"hash,omitempty"` Username string `json:"username,omitempty"` + Name string `json:"name,omitempty"` PreferredUsername string `json:"preferredUsername,omitempty"` + EmailVerified *bool `json:"emailVerified,omitempty"` UserID string `json:"userID,omitempty"` Groups []string `json:"groups,omitempty"` } @@ -459,7 +461,9 @@ func (cli *client) fromStoragePassword(p storage.Password) Password { Email: email, Hash: p.Hash, Username: p.Username, + Name: p.Name, PreferredUsername: p.PreferredUsername, + EmailVerified: p.EmailVerified, UserID: p.UserID, Groups: p.Groups, } @@ -470,7 +474,9 @@ func toStoragePassword(p Password) storage.Password { Email: p.Email, Hash: p.Hash, Username: p.Username, + Name: p.Name, PreferredUsername: p.PreferredUsername, + EmailVerified: p.EmailVerified, UserID: p.UserID, Groups: p.Groups, } diff --git a/storage/sql/crud.go b/storage/sql/crud.go index b7b32650..e60f29d5 100644 --- a/storage/sql/crud.go +++ b/storage/sql/crud.go @@ -598,13 +598,13 @@ func (c *conn) CreatePassword(ctx context.Context, p storage.Password) error { p.Email = strings.ToLower(p.Email) _, err := c.Exec(` insert into password ( - email, hash, username, preferred_username, user_id, groups + email, hash, username, preferred_username, user_id, groups, name, email_verified ) values ( - $1, $2, $3, $4, $5, $6 + $1, $2, $3, $4, $5, $6, $7, $8 ); `, - p.Email, p.Hash, p.Username, p.PreferredUsername, p.UserID, encoder(p.Groups), + p.Email, p.Hash, p.Username, p.PreferredUsername, p.UserID, encoder(p.Groups), p.Name, p.EmailVerified, ) if err != nil { if c.alreadyExistsCheck(err) { @@ -629,10 +629,10 @@ func (c *conn) UpdatePassword(ctx context.Context, email string, updater func(p _, err = tx.Exec(` update password set - hash = $1, username = $2, preferred_username = $3, user_id = $4, groups = $5 - where email = $6; + hash = $1, username = $2, preferred_username = $3, user_id = $4, groups = $5, name = $6, email_verified = $7 + where email = $8; `, - np.Hash, np.Username, np.PreferredUsername, np.UserID, encoder(np.Groups), p.Email, + np.Hash, np.Username, np.PreferredUsername, np.UserID, encoder(np.Groups), np.Name, np.EmailVerified, p.Email, ) if err != nil { return fmt.Errorf("update password: %v", err) @@ -648,7 +648,7 @@ func (c *conn) GetPassword(ctx context.Context, email string) (storage.Password, func getPassword(ctx context.Context, q querier, email string) (p storage.Password, err error) { return scanPassword(q.QueryRow(` select - email, hash, username, preferred_username, user_id, groups + email, hash, username, preferred_username, user_id, groups, name, email_verified from password where email = $1; `, strings.ToLower(email))) } @@ -656,7 +656,7 @@ func getPassword(ctx context.Context, q querier, email string) (p storage.Passwo func (c *conn) ListPasswords(ctx context.Context) ([]storage.Password, error) { rows, err := c.Query(` select - email, hash, username, preferred_username, user_id, groups + email, hash, username, preferred_username, user_id, groups, name, email_verified from password; `) if err != nil { @@ -679,8 +679,9 @@ func (c *conn) ListPasswords(ctx context.Context) ([]storage.Password, error) { } func scanPassword(s scanner) (p storage.Password, err error) { + var emailVerified sql.NullBool err = s.Scan( - &p.Email, &p.Hash, &p.Username, &p.PreferredUsername, &p.UserID, decoder(&p.Groups), + &p.Email, &p.Hash, &p.Username, &p.PreferredUsername, &p.UserID, decoder(&p.Groups), &p.Name, &emailVerified, ) if err != nil { if err == sql.ErrNoRows { @@ -688,6 +689,9 @@ func scanPassword(s scanner) (p storage.Password, err error) { } return p, fmt.Errorf("select password: %v", err) } + if emailVerified.Valid { + p.EmailVerified = &emailVerified.Bool + } return p, nil } diff --git a/storage/sql/migrate.go b/storage/sql/migrate.go index dc8eee05..9a1807c9 100644 --- a/storage/sql/migrate.go +++ b/storage/sql/migrate.go @@ -338,4 +338,40 @@ var migrations = []migration{ }, flavor: &flavorMySQL, }, + // Migration for adding name and email_verified to password table (Postgres) + { + stmts: []string{ + ` + alter table password + add column name text not null default '';`, + ` + alter table password + add column email_verified boolean;`, + }, + flavor: &flavorPostgres, + }, + // Migration for adding name and email_verified to password table (SQLite3) + { + stmts: []string{ + ` + alter table password + add column name text not null default '';`, + ` + alter table password + add column email_verified boolean;`, + }, + flavor: &flavorSQLite3, + }, + // Migration for adding name and email_verified to password table (MySQL) + { + stmts: []string{ + ` + alter table password + add column name text not null default '';`, + ` + alter table password + add column email_verified boolean;`, + }, + flavor: &flavorMySQL, + }, }