[#276] added support for linking external auths by provider id

This commit is contained in:
Gani Georgiev
2022-08-31 13:38:31 +03:00
parent 9fe94f5c7d
commit f5ff7193a9
33 changed files with 924 additions and 223 deletions
+6 -6
View File
@@ -22,15 +22,15 @@ type AdminLogin struct {
//
// NB! App is a required struct member.
type AdminLoginConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewAdminLogin creates a new [AdminLogin] form with initializer
// config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewAdminLoginWithConfig] with explicitly set TxDao.
// [NewAdminLoginWithConfig] with explicitly set Dao.
func NewAdminLogin(app core.App) *AdminLogin {
return NewAdminLoginWithConfig(AdminLoginConfig{
App: app,
@@ -46,8 +46,8 @@ func NewAdminLoginWithConfig(config AdminLoginConfig) *AdminLogin {
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -68,7 +68,7 @@ func (form *AdminLogin) Submit() (*models.Admin, error) {
return nil, err
}
admin, err := form.config.TxDao.FindAdminByEmail(form.Email)
admin, err := form.config.Dao.FindAdminByEmail(form.Email)
if err != nil {
return nil, err
}
+8 -8
View File
@@ -21,15 +21,15 @@ type AdminPasswordResetConfirm struct {
//
// NB! App is required struct member.
type AdminPasswordResetConfirmConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewAdminPasswordResetConfirm creates a new [AdminPasswordResetConfirm]
// form with initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewAdminPasswordResetConfirmWithConfig] with explicitly set TxDao.
// [NewAdminPasswordResetConfirmWithConfig] with explicitly set Dao.
func NewAdminPasswordResetConfirm(app core.App) *AdminPasswordResetConfirm {
return NewAdminPasswordResetConfirmWithConfig(AdminPasswordResetConfirmConfig{
App: app,
@@ -45,8 +45,8 @@ func NewAdminPasswordResetConfirmWithConfig(config AdminPasswordResetConfirmConf
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -67,7 +67,7 @@ func (form *AdminPasswordResetConfirm) checkToken(value any) error {
return nil // nothing to check
}
admin, err := form.config.TxDao.FindAdminByToken(
admin, err := form.config.Dao.FindAdminByToken(
v,
form.config.App.Settings().AdminPasswordResetToken.Secret,
)
@@ -85,7 +85,7 @@ func (form *AdminPasswordResetConfirm) Submit() (*models.Admin, error) {
return nil, err
}
admin, err := form.config.TxDao.FindAdminByToken(
admin, err := form.config.Dao.FindAdminByToken(
form.Token,
form.config.App.Settings().AdminPasswordResetToken.Secret,
)
@@ -97,7 +97,7 @@ func (form *AdminPasswordResetConfirm) Submit() (*models.Admin, error) {
return nil, err
}
if err := form.config.TxDao.SaveAdmin(admin); err != nil {
if err := form.config.Dao.SaveAdmin(admin); err != nil {
return nil, err
}
+6 -6
View File
@@ -24,7 +24,7 @@ type AdminPasswordResetRequest struct {
// NB! App is required struct member.
type AdminPasswordResetRequestConfig struct {
App core.App
TxDao *daos.Dao
Dao *daos.Dao
ResendThreshold float64 // in seconds
}
@@ -32,7 +32,7 @@ type AdminPasswordResetRequestConfig struct {
// form with initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewAdminPasswordResetRequestWithConfig] with explicitly set TxDao.
// [NewAdminPasswordResetRequestWithConfig] with explicitly set Dao.
func NewAdminPasswordResetRequest(app core.App) *AdminPasswordResetRequest {
return NewAdminPasswordResetRequestWithConfig(AdminPasswordResetRequestConfig{
App: app,
@@ -49,8 +49,8 @@ func NewAdminPasswordResetRequestWithConfig(config AdminPasswordResetRequestConf
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -77,7 +77,7 @@ func (form *AdminPasswordResetRequest) Submit() error {
return err
}
admin, err := form.config.TxDao.FindAdminByEmail(form.Email)
admin, err := form.config.Dao.FindAdminByEmail(form.Email)
if err != nil {
return err
}
@@ -95,5 +95,5 @@ func (form *AdminPasswordResetRequest) Submit() error {
// update last sent timestamp
admin.LastResetSentAt = types.NowDateTime()
return form.config.TxDao.SaveAdmin(admin)
return form.config.Dao.SaveAdmin(admin)
}
+7 -7
View File
@@ -25,8 +25,8 @@ type AdminUpsert struct {
//
// NB! App is a required struct member.
type AdminUpsertConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewAdminUpsert creates a new [AdminUpsert] form with initializer
@@ -34,7 +34,7 @@ type AdminUpsertConfig struct {
// (for create you could pass a pointer to an empty Admin - `&models.Admin{}`).
//
// If you want to submit the form as part of another transaction, use
// [NewAdminUpsertWithConfig] with explicitly set TxDao.
// [NewAdminUpsertWithConfig] with explicitly set Dao.
func NewAdminUpsert(app core.App, admin *models.Admin) *AdminUpsert {
return NewAdminUpsertWithConfig(AdminUpsertConfig{
App: app,
@@ -54,8 +54,8 @@ func NewAdminUpsertWithConfig(config AdminUpsertConfig, admin *models.Admin) *Ad
panic("Invalid initializer config or nil upsert model.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
// load defaults
@@ -105,7 +105,7 @@ func (form *AdminUpsert) Validate() error {
func (form *AdminUpsert) checkUniqueEmail(value any) error {
v, _ := value.(string)
if form.config.TxDao.IsAdminEmailUnique(v, form.admin.Id) {
if form.config.Dao.IsAdminEmailUnique(v, form.admin.Id) {
return nil
}
@@ -135,6 +135,6 @@ func (form *AdminUpsert) Submit(interceptors ...InterceptorFunc) error {
}
return runInterceptors(func() error {
return form.config.TxDao.SaveAdmin(form.admin)
return form.config.Dao.SaveAdmin(form.admin)
}, interceptors...)
}
+10 -10
View File
@@ -36,8 +36,8 @@ type CollectionUpsert struct {
//
// NB! App is a required struct member.
type CollectionUpsertConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewCollectionUpsert creates a new [CollectionUpsert] form with initializer
@@ -45,7 +45,7 @@ type CollectionUpsertConfig struct {
// (for create you could pass a pointer to an empty Collection - `&models.Collection{}`).
//
// If you want to submit the form as part of another transaction, use
// [NewCollectionUpsertWithConfig] with explicitly set TxDao.
// [NewCollectionUpsertWithConfig] with explicitly set Dao.
func NewCollectionUpsert(app core.App, collection *models.Collection) *CollectionUpsert {
return NewCollectionUpsertWithConfig(CollectionUpsertConfig{
App: app,
@@ -65,8 +65,8 @@ func NewCollectionUpsertWithConfig(config CollectionUpsertConfig, collection *mo
panic("Invalid initializer config or nil upsert model.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
// load defaults
@@ -130,11 +130,11 @@ func (form *CollectionUpsert) Validate() error {
func (form *CollectionUpsert) checkUniqueName(value any) error {
v, _ := value.(string)
if !form.config.TxDao.IsCollectionNameUnique(v, form.collection.Id) {
if !form.config.Dao.IsCollectionNameUnique(v, form.collection.Id) {
return validation.NewError("validation_collection_name_exists", "Collection name must be unique (case insensitive).")
}
if (form.collection.IsNew() || !strings.EqualFold(v, form.collection.Name)) && form.config.TxDao.HasTable(v) {
if (form.collection.IsNew() || !strings.EqualFold(v, form.collection.Name)) && form.config.Dao.HasTable(v) {
return validation.NewError("validation_collection_name_table_exists", "The collection name must be also unique table name.")
}
@@ -191,7 +191,7 @@ func (form *CollectionUpsert) ensureExistingRelationCollectionId(value any) erro
continue
}
if _, err := form.config.TxDao.FindCollectionByNameOrId(options.CollectionId); err != nil {
if _, err := form.config.Dao.FindCollectionByNameOrId(options.CollectionId); err != nil {
return validation.Errors{fmt.Sprint(i): validation.NewError(
"validation_field_invalid_relation",
"The relation collection doesn't exist.",
@@ -228,7 +228,7 @@ func (form *CollectionUpsert) checkRule(value any) error {
}
dummy := &models.Collection{Schema: form.Schema}
r := resolvers.NewRecordFieldResolver(form.config.TxDao, dummy, nil)
r := resolvers.NewRecordFieldResolver(form.config.Dao, dummy, nil)
_, err := search.FilterData(*v).BuildExpr(r)
if err != nil {
@@ -273,6 +273,6 @@ func (form *CollectionUpsert) Submit(interceptors ...InterceptorFunc) error {
form.collection.DeleteRule = form.DeleteRule
return runInterceptors(func() error {
return form.config.TxDao.SaveCollection(form.collection)
return form.config.Dao.SaveCollection(form.collection)
}, interceptors...)
}
+8 -8
View File
@@ -24,15 +24,15 @@ type CollectionsImport struct {
//
// NB! App is a required struct member.
type CollectionsImportConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewCollectionsImport creates a new [CollectionsImport] form with
// initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewCollectionsImportWithConfig] with explicitly set TxDao.
// [NewCollectionsImportWithConfig] with explicitly set Dao.
func NewCollectionsImport(app core.App) *CollectionsImport {
return NewCollectionsImportWithConfig(CollectionsImportConfig{
App: app,
@@ -48,8 +48,8 @@ func NewCollectionsImportWithConfig(config CollectionsImportConfig) *Collections
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -79,7 +79,7 @@ func (form *CollectionsImport) Submit(interceptors ...InterceptorFunc) error {
}
return runInterceptors(func() error {
return form.config.TxDao.RunInTransaction(func(txDao *daos.Dao) error {
return form.config.Dao.RunInTransaction(func(txDao *daos.Dao) error {
importErr := txDao.ImportCollections(
form.Collections,
form.DeleteMissing,
@@ -122,8 +122,8 @@ func (form *CollectionsImport) beforeRecordsSync(txDao *daos.Dao, mappedNew, map
}
upsertForm := NewCollectionUpsertWithConfig(CollectionUpsertConfig{
App: form.config.App,
TxDao: txDao,
App: form.config.App,
Dao: txDao,
}, upsertModel)
// load form fields with the refreshed collection state
+8 -8
View File
@@ -37,8 +37,8 @@ type RecordUpsert struct {
//
// NB! App is required struct member.
type RecordUpsertConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewRecordUpsert creates a new [RecordUpsert] form with initializer
@@ -46,7 +46,7 @@ type RecordUpsertConfig struct {
// (for create you could pass a pointer to an empty Record - `models.NewRecord(collection)`).
//
// If you want to submit the form as part of another transaction, use
// [NewRecordUpsertWithConfig] with explicitly set TxDao.
// [NewRecordUpsertWithConfig] with explicitly set Dao.
func NewRecordUpsert(app core.App, record *models.Record) *RecordUpsert {
return NewRecordUpsertWithConfig(RecordUpsertConfig{
App: app,
@@ -68,8 +68,8 @@ func NewRecordUpsertWithConfig(config RecordUpsertConfig, record *models.Record)
panic("Invalid initializer config or nil upsert model.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
form.Id = record.Id
@@ -286,7 +286,7 @@ func (form *RecordUpsert) Validate() error {
// record data validator
dataValidator := validators.NewRecordDataValidator(
form.config.TxDao,
form.config.Dao,
form.record,
form.filesToUpload,
)
@@ -316,7 +316,7 @@ func (form *RecordUpsert) DrySubmit(callback func(txDao *daos.Dao) error) error
return err
}
return form.config.TxDao.RunInTransaction(func(txDao *daos.Dao) error {
return form.config.Dao.RunInTransaction(func(txDao *daos.Dao) error {
tx, ok := txDao.DB().(*dbx.Tx)
if !ok {
return errors.New("failed to get transaction db")
@@ -366,7 +366,7 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc) error {
}
return runInterceptors(func() error {
return form.config.TxDao.RunInTransaction(func(txDao *daos.Dao) error {
return form.config.Dao.RunInTransaction(func(txDao *daos.Dao) error {
// persist record model
if err := txDao.SaveRecord(form.record); err != nil {
return err
+10 -10
View File
@@ -20,16 +20,16 @@ type SettingsUpsert struct {
//
// NB! App is required struct member.
type SettingsUpsertConfig struct {
App core.App
TxDao *daos.Dao
TxLogsDao *daos.Dao
App core.App
Dao *daos.Dao
LogsDao *daos.Dao
}
// NewSettingsUpsert creates a new [SettingsUpsert] form with initializer
// config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewSettingsUpsertWithConfig] with explicitly set TxDao.
// [NewSettingsUpsertWithConfig] with explicitly set Dao.
func NewSettingsUpsert(app core.App) *SettingsUpsert {
return NewSettingsUpsertWithConfig(SettingsUpsertConfig{
App: app,
@@ -45,12 +45,12 @@ func NewSettingsUpsertWithConfig(config SettingsUpsertConfig) *SettingsUpsert {
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
if form.config.TxLogsDao == nil {
form.config.TxLogsDao = form.config.App.LogsDao()
if form.config.LogsDao == nil {
form.config.LogsDao = form.config.App.LogsDao()
}
// load the application settings into the form
@@ -78,7 +78,7 @@ func (form *SettingsUpsert) Submit(interceptors ...InterceptorFunc) error {
encryptionKey := os.Getenv(form.config.App.EncryptionEnv())
return runInterceptors(func() error {
saveErr := form.config.TxDao.SaveParam(
saveErr := form.config.Dao.SaveParam(
models.ParamAppSettings,
form.Settings,
encryptionKey,
@@ -88,7 +88,7 @@ func (form *SettingsUpsert) Submit(interceptors ...InterceptorFunc) error {
}
// explicitly trigger old logs deletion
form.config.TxLogsDao.DeleteOldRequests(
form.config.LogsDao.DeleteOldRequests(
time.Now().AddDate(0, 0, -1*form.Settings.Logs.MaxDays),
)
+8 -8
View File
@@ -20,8 +20,8 @@ type UserEmailChangeConfirm struct {
//
// NB! App is required struct member.
type UserEmailChangeConfirmConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewUserEmailChangeConfirm creates a new [UserEmailChangeConfirm]
@@ -29,7 +29,7 @@ type UserEmailChangeConfirmConfig struct {
//
// This factory method is used primarily for convenience (and backward compatibility).
// If you want to submit the form as part of another transaction, use
// [NewUserEmailChangeConfirmWithConfig] with explicitly set TxDao.
// [NewUserEmailChangeConfirmWithConfig] with explicitly set Dao.
func NewUserEmailChangeConfirm(app core.App) *UserEmailChangeConfirm {
return NewUserEmailChangeConfirmWithConfig(UserEmailChangeConfirmConfig{
App: app,
@@ -45,8 +45,8 @@ func NewUserEmailChangeConfirmWithConfig(config UserEmailChangeConfirmConfig) *U
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -103,12 +103,12 @@ func (form *UserEmailChangeConfirm) parseToken(token string) (*models.User, stri
}
// ensure that there aren't other users with the new email
if !form.config.TxDao.IsUserEmailUnique(newEmail, "") {
if !form.config.Dao.IsUserEmailUnique(newEmail, "") {
return nil, "", validation.NewError("validation_existing_token_email", "The new email address is already registered: "+newEmail)
}
// verify that the token is not expired and its signature is valid
user, err := form.config.TxDao.FindUserByToken(
user, err := form.config.Dao.FindUserByToken(
token,
form.config.App.Settings().UserEmailChangeToken.Secret,
)
@@ -135,7 +135,7 @@ func (form *UserEmailChangeConfirm) Submit() (*models.User, error) {
user.Verified = true
user.RefreshTokenKey() // invalidate old tokens
if err := form.config.TxDao.SaveUser(user); err != nil {
if err := form.config.Dao.SaveUser(user); err != nil {
return nil, err
}
+6 -6
View File
@@ -21,15 +21,15 @@ type UserEmailChangeRequest struct {
//
// NB! App is required struct member.
type UserEmailChangeRequestConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewUserEmailChangeRequest creates a new [UserEmailChangeRequest]
// form with initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewUserEmailChangeConfirmWithConfig] with explicitly set TxDao.
// [NewUserEmailChangeConfirmWithConfig] with explicitly set Dao.
func NewUserEmailChangeRequest(app core.App, user *models.User) *UserEmailChangeRequest {
return NewUserEmailChangeRequestWithConfig(UserEmailChangeRequestConfig{
App: app,
@@ -48,8 +48,8 @@ func NewUserEmailChangeRequestWithConfig(config UserEmailChangeRequestConfig, us
panic("Invalid initializer config or nil user model.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -71,7 +71,7 @@ func (form *UserEmailChangeRequest) Validate() error {
func (form *UserEmailChangeRequest) checkUniqueEmail(value any) error {
v, _ := value.(string)
if !form.config.TxDao.IsUserEmailUnique(v, "") {
if !form.config.Dao.IsUserEmailUnique(v, "") {
return validation.NewError("validation_user_email_exists", "User email already exists.")
}
+6 -6
View File
@@ -20,8 +20,8 @@ type UserEmailLogin struct {
//
// NB! App is required struct member.
type UserEmailLoginConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewUserEmailLogin creates a new [UserEmailLogin] form with
@@ -29,7 +29,7 @@ type UserEmailLoginConfig struct {
//
// This factory method is used primarily for convenience (and backward compatibility).
// If you want to submit the form as part of another transaction, use
// [NewUserEmailLoginWithConfig] with explicitly set TxDao.
// [NewUserEmailLoginWithConfig] with explicitly set Dao.
func NewUserEmailLogin(app core.App) *UserEmailLogin {
return NewUserEmailLoginWithConfig(UserEmailLoginConfig{
App: app,
@@ -45,8 +45,8 @@ func NewUserEmailLoginWithConfig(config UserEmailLoginConfig) *UserEmailLogin {
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -67,7 +67,7 @@ func (form *UserEmailLogin) Submit() (*models.User, error) {
return nil, err
}
user, err := form.config.TxDao.FindUserByEmail(form.Email)
user, err := form.config.Dao.FindUserByEmail(form.Email)
if err != nil {
return nil, err
}
+70 -44
View File
@@ -35,15 +35,15 @@ type UserOauth2Login struct {
//
// NB! App is required struct member.
type UserOauth2LoginConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewUserOauth2Login creates a new [UserOauth2Login] form with
// initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewUserOauth2LoginWithConfig] with explicitly set TxDao.
// [NewUserOauth2LoginWithConfig] with explicitly set Dao.
func NewUserOauth2Login(app core.App) *UserOauth2Login {
return NewUserOauth2LoginWithConfig(UserOauth2LoginConfig{
App: app,
@@ -59,8 +59,8 @@ func NewUserOauth2LoginWithConfig(config UserOauth2LoginConfig) *UserOauth2Login
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -99,8 +99,11 @@ func (form *UserOauth2Login) Submit() (*models.User, *auth.AuthUser, error) {
return nil, nil, err
}
// load provider configuration
config := form.config.App.Settings().NamedAuthProviderConfigs()[form.Provider]
config.SetupProvider(provider)
if err := config.SetupProvider(provider); err != nil {
return nil, nil, err
}
provider.SetRedirectUrl(form.RedirectUrl)
@@ -113,55 +116,78 @@ func (form *UserOauth2Login) Submit() (*models.User, *auth.AuthUser, error) {
return nil, nil, err
}
// fetch auth user
// fetch external auth user
authData, err := provider.FetchAuthUser(token)
if err != nil {
return nil, nil, err
}
// login/register the auth user
user, _ := form.config.TxDao.FindUserByEmail(authData.Email)
if user != nil {
// update the existing user's verified state
if !user.Verified {
var user *models.User
// check for existing relation with the external auth user
rel, _ := form.config.Dao.FindExternalAuthByProvider(form.Provider, authData.Id)
if rel != nil {
user, err = form.config.Dao.FindUserById(rel.UserId)
if err != nil {
return nil, authData, err
}
} else if authData.Email != "" {
// look for an existing user by the external user's email
user, _ = form.config.Dao.FindUserByEmail(authData.Email)
}
if user == nil && !config.AllowRegistrations {
return nil, authData, errors.New("New users registration is not allowed for the authorized provider.")
}
saveErr := form.config.Dao.RunInTransaction(func(txDao *daos.Dao) error {
if user == nil {
user = &models.User{}
user.Verified = true
if err := form.config.TxDao.SaveUser(user); err != nil {
return nil, authData, err
user.Email = authData.Email
user.SetPassword(security.RandomString(30))
// create the new user
if err := txDao.SaveUser(user); err != nil {
return err
}
} else {
// update the existing user verified state
if !user.Verified {
user.Verified = true
if err := txDao.SaveUser(user); err != nil {
return err
}
}
// update the existing user empty email if the authData has one
// (this in case previously the user was created with
// an OAuth2 provider that didn't return an email address)
if user.Email == "" && authData.Email != "" {
user.Email = authData.Email
if err := txDao.SaveUser(user); err != nil {
return err
}
}
}
return user, authData, nil
}
if !config.AllowRegistrations {
// registration of new users is not allowed via the Oauth2 provider
return nil, authData, errors.New("Cannot find user with the authorized email.")
}
// create ExternalAuth relation if missing
if rel == nil {
rel = &models.ExternalAuth{
UserId: user.Id,
Provider: form.Provider,
ProviderId: authData.Id,
}
if err := txDao.SaveExternalAuth(rel); err != nil {
return err
}
}
// create new user
user = &models.User{Verified: true}
upsertForm := NewUserUpsertWithConfig(UserUpsertConfig{
App: form.config.App,
TxDao: form.config.TxDao,
}, user)
upsertForm.Email = authData.Email
upsertForm.Password = security.RandomString(30)
upsertForm.PasswordConfirm = upsertForm.Password
return nil
})
event := &core.UserOauth2RegisterEvent{
User: user,
AuthData: authData,
}
if err := form.config.App.OnUserBeforeOauth2Register().Trigger(event); err != nil {
return nil, authData, err
}
if err := upsertForm.Submit(); err != nil {
return nil, authData, err
}
if err := form.config.App.OnUserAfterOauth2Register().Trigger(event); err != nil {
return nil, authData, err
if saveErr != nil {
return nil, authData, saveErr
}
return user, authData, nil
+8 -8
View File
@@ -22,15 +22,15 @@ type UserPasswordResetConfirm struct {
//
// NB! App is required struct member.
type UserPasswordResetConfirmConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewUserPasswordResetConfirm creates a new [UserPasswordResetConfirm]
// form with initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewUserPasswordResetConfirmWithConfig] with explicitly set TxDao.
// [NewUserPasswordResetConfirmWithConfig] with explicitly set Dao.
func NewUserPasswordResetConfirm(app core.App) *UserPasswordResetConfirm {
return NewUserPasswordResetConfirmWithConfig(UserPasswordResetConfirmConfig{
App: app,
@@ -46,8 +46,8 @@ func NewUserPasswordResetConfirmWithConfig(config UserPasswordResetConfirmConfig
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -70,7 +70,7 @@ func (form *UserPasswordResetConfirm) checkToken(value any) error {
return nil // nothing to check
}
user, err := form.config.TxDao.FindUserByToken(
user, err := form.config.Dao.FindUserByToken(
v,
form.config.App.Settings().UserPasswordResetToken.Secret,
)
@@ -88,7 +88,7 @@ func (form *UserPasswordResetConfirm) Submit() (*models.User, error) {
return nil, err
}
user, err := form.config.TxDao.FindUserByToken(
user, err := form.config.Dao.FindUserByToken(
form.Token,
form.config.App.Settings().UserPasswordResetToken.Secret,
)
@@ -100,7 +100,7 @@ func (form *UserPasswordResetConfirm) Submit() (*models.User, error) {
return nil, err
}
if err := form.config.TxDao.SaveUser(user); err != nil {
if err := form.config.Dao.SaveUser(user); err != nil {
return nil, err
}
+6 -6
View File
@@ -25,7 +25,7 @@ type UserPasswordResetRequest struct {
// NB! App is required struct member.
type UserPasswordResetRequestConfig struct {
App core.App
TxDao *daos.Dao
Dao *daos.Dao
ResendThreshold float64 // in seconds
}
@@ -33,7 +33,7 @@ type UserPasswordResetRequestConfig struct {
// form with initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewUserPasswordResetRequestWithConfig] with explicitly set TxDao.
// [NewUserPasswordResetRequestWithConfig] with explicitly set Dao.
func NewUserPasswordResetRequest(app core.App) *UserPasswordResetRequest {
return NewUserPasswordResetRequestWithConfig(UserPasswordResetRequestConfig{
App: app,
@@ -50,8 +50,8 @@ func NewUserPasswordResetRequestWithConfig(config UserPasswordResetRequestConfig
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -78,7 +78,7 @@ func (form *UserPasswordResetRequest) Submit() error {
return err
}
user, err := form.config.TxDao.FindUserByEmail(form.Email)
user, err := form.config.Dao.FindUserByEmail(form.Email)
if err != nil {
return err
}
@@ -96,5 +96,5 @@ func (form *UserPasswordResetRequest) Submit() error {
// update last sent timestamp
user.LastResetSentAt = types.NowDateTime()
return form.config.TxDao.SaveUser(user)
return form.config.Dao.SaveUser(user)
}
+7 -7
View File
@@ -28,8 +28,8 @@ type UserUpsert struct {
//
// NB! App is required struct member.
type UserUpsertConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewUserUpsert creates a new [UserUpsert] form with initializer
@@ -37,7 +37,7 @@ type UserUpsertConfig struct {
// (for create you could pass a pointer to an empty User - `&models.User{}`).
//
// If you want to submit the form as part of another transaction, use
// [NewUserEmailChangeConfirmWithConfig] with explicitly set TxDao.
// [NewUserEmailChangeConfirmWithConfig] with explicitly set Dao.
func NewUserUpsert(app core.App, user *models.User) *UserUpsert {
return NewUserUpsertWithConfig(UserUpsertConfig{
App: app,
@@ -57,8 +57,8 @@ func NewUserUpsertWithConfig(config UserUpsertConfig, user *models.User) *UserUp
panic("Invalid initializer config or nil upsert model.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
// load defaults
@@ -103,7 +103,7 @@ func (form *UserUpsert) Validate() error {
func (form *UserUpsert) checkUniqueEmail(value any) error {
v, _ := value.(string)
if v == "" || form.config.TxDao.IsUserEmailUnique(v, form.user.Id) {
if v == "" || form.config.Dao.IsUserEmailUnique(v, form.user.Id) {
return nil
}
@@ -160,6 +160,6 @@ func (form *UserUpsert) Submit(interceptors ...InterceptorFunc) error {
form.user.Email = form.Email
return runInterceptors(func() error {
return form.config.TxDao.SaveUser(form.user)
return form.config.Dao.SaveUser(form.user)
}, interceptors...)
}
+8 -8
View File
@@ -19,15 +19,15 @@ type UserVerificationConfirm struct {
//
// NB! App is required struct member.
type UserVerificationConfirmConfig struct {
App core.App
TxDao *daos.Dao
App core.App
Dao *daos.Dao
}
// NewUserVerificationConfirm creates a new [UserVerificationConfirm]
// form with initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewUserVerificationConfirmWithConfig] with explicitly set TxDao.
// [NewUserVerificationConfirmWithConfig] with explicitly set Dao.
func NewUserVerificationConfirm(app core.App) *UserVerificationConfirm {
return NewUserVerificationConfirmWithConfig(UserVerificationConfirmConfig{
App: app,
@@ -43,8 +43,8 @@ func NewUserVerificationConfirmWithConfig(config UserVerificationConfirmConfig)
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -63,7 +63,7 @@ func (form *UserVerificationConfirm) checkToken(value any) error {
return nil // nothing to check
}
user, err := form.config.TxDao.FindUserByToken(
user, err := form.config.Dao.FindUserByToken(
v,
form.config.App.Settings().UserVerificationToken.Secret,
)
@@ -81,7 +81,7 @@ func (form *UserVerificationConfirm) Submit() (*models.User, error) {
return nil, err
}
user, err := form.config.TxDao.FindUserByToken(
user, err := form.config.Dao.FindUserByToken(
form.Token,
form.config.App.Settings().UserVerificationToken.Secret,
)
@@ -95,7 +95,7 @@ func (form *UserVerificationConfirm) Submit() (*models.User, error) {
user.Verified = true
if err := form.config.TxDao.SaveUser(user); err != nil {
if err := form.config.Dao.SaveUser(user); err != nil {
return nil, err
}
+6 -6
View File
@@ -25,7 +25,7 @@ type UserVerificationRequest struct {
// NB! App is required struct member.
type UserVerificationRequestConfig struct {
App core.App
TxDao *daos.Dao
Dao *daos.Dao
ResendThreshold float64 // in seconds
}
@@ -33,7 +33,7 @@ type UserVerificationRequestConfig struct {
// form with initializer config created from the provided [core.App] instance.
//
// If you want to submit the form as part of another transaction, use
// [NewUserVerificationRequestWithConfig] with explicitly set TxDao.
// [NewUserVerificationRequestWithConfig] with explicitly set Dao.
func NewUserVerificationRequest(app core.App) *UserVerificationRequest {
return NewUserVerificationRequestWithConfig(UserVerificationRequestConfig{
App: app,
@@ -50,8 +50,8 @@ func NewUserVerificationRequestWithConfig(config UserVerificationRequestConfig)
panic("Missing required config.App instance.")
}
if form.config.TxDao == nil {
form.config.TxDao = form.config.App.Dao()
if form.config.Dao == nil {
form.config.Dao = form.config.App.Dao()
}
return form
@@ -78,7 +78,7 @@ func (form *UserVerificationRequest) Submit() error {
return err
}
user, err := form.config.TxDao.FindUserByEmail(form.Email)
user, err := form.config.Dao.FindUserByEmail(form.Email)
if err != nil {
return err
}
@@ -100,5 +100,5 @@ func (form *UserVerificationRequest) Submit() error {
// update last sent timestamp
user.LastVerificationSentAt = types.NowDateTime()
return form.config.TxDao.SaveUser(user)
return form.config.Dao.SaveUser(user)
}