Skip to content

Commit 4f810d2

Browse files
authored
Merge pull request #307 from authorizerdev/feat/mobile-basic-auth
feat: add mobile based basic auth
2 parents 105d9be + 313b510 commit 4f810d2

File tree

29 files changed

+2082
-759
lines changed

29 files changed

+2082
-759
lines changed

server/constants/auth_methods.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package constants
33
const (
44
// AuthRecipeMethodBasicAuth is the basic_auth auth method
55
AuthRecipeMethodBasicAuth = "basic_auth"
6+
// AuthRecipeMethodMobileBasicAuth is the mobile basic_auth method, where user can signup using mobile number and password
7+
AuthRecipeMethodMobileBasicAuth = "mobile_basic_auth"
68
// AuthRecipeMethodMagicLinkLogin is the magic_link_login auth method
79
AuthRecipeMethodMagicLinkLogin = "magic_link_login"
810
// AuthRecipeMethodGoogle is the google auth method

server/constants/env.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ const (
125125
EnvKeyDisableEmailVerification = "DISABLE_EMAIL_VERIFICATION"
126126
// EnvKeyDisableBasicAuthentication key for env variable DISABLE_BASIC_AUTH
127127
EnvKeyDisableBasicAuthentication = "DISABLE_BASIC_AUTHENTICATION"
128+
// EnvKeyDisableBasicAuthentication key for env variable DISABLE_MOBILE_BASIC_AUTH
129+
EnvKeyDisableMobileBasicAuthentication = "DISABLE_MOBILE_BASIC_AUTHENTICATION"
128130
// EnvKeyDisableMagicLinkLogin key for env variable DISABLE_MAGIC_LINK_LOGIN
129131
EnvKeyDisableMagicLinkLogin = "DISABLE_MAGIC_LINK_LOGIN"
130132
// EnvKeyDisableLoginPage key for env variable DISABLE_LOGIN_PAGE

server/db/providers/arangodb/user.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/authorizerdev/authorizer/server/db/models"
1616
"github.com/authorizerdev/authorizer/server/graph/model"
1717
"github.com/authorizerdev/authorizer/server/memorystore"
18+
"github.com/authorizerdev/authorizer/server/refs"
1819
)
1920

2021
// AddUser to save user information in database
@@ -32,6 +33,12 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
3233
user.Roles = defaultRoles
3334
}
3435

36+
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
37+
if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil && u.ID != user.ID {
38+
return user, fmt.Errorf("user with given phone number already exists")
39+
}
40+
}
41+
3542
user.CreatedAt = time.Now().Unix()
3643
user.UpdatedAt = time.Now().Unix()
3744
userCollection, _ := p.db.Collection(ctx, models.Collections.User)
@@ -48,6 +55,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
4855
// UpdateUser to update user information in database
4956
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
5057
user.UpdatedAt = time.Now().Unix()
58+
5159
collection, _ := p.db.Collection(ctx, models.Collections.User)
5260
meta, err := collection.UpdateDocument(ctx, user.Key, user)
5361
if err != nil {
@@ -211,3 +219,34 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
211219

212220
return nil
213221
}
222+
223+
// GetUserByPhoneNumber to get user information from database using phone number
224+
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
225+
var user models.User
226+
227+
query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.User)
228+
bindVars := map[string]interface{}{
229+
"phone_number": phoneNumber,
230+
}
231+
232+
cursor, err := p.db.Query(ctx, query, bindVars)
233+
if err != nil {
234+
return nil, err
235+
}
236+
defer cursor.Close()
237+
238+
for {
239+
if !cursor.HasMore() {
240+
if user.Key == "" {
241+
return nil, fmt.Errorf("user not found")
242+
}
243+
break
244+
}
245+
_, err := cursor.ReadDocument(ctx, &user)
246+
if err != nil {
247+
return nil, err
248+
}
249+
}
250+
251+
return &user, nil
252+
}

server/db/providers/cassandradb/provider.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ func NewProvider() (*provider, error) {
161161
if err != nil {
162162
return nil, err
163163
}
164+
165+
userPhoneNumberIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.User)
166+
err = session.Query(userPhoneNumberIndexQuery).Exec()
167+
if err != nil {
168+
return nil, err
169+
}
164170
// add is_multi_factor_auth_enabled on users table
165171
userTableAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD is_multi_factor_auth_enabled boolean`, KeySpace, models.Collections.User)
166172
err = session.Query(userTableAlterQuery).Exec()

server/db/providers/cassandradb/user.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/authorizerdev/authorizer/server/db/models"
1313
"github.com/authorizerdev/authorizer/server/graph/model"
1414
"github.com/authorizerdev/authorizer/server/memorystore"
15+
"github.com/authorizerdev/authorizer/server/refs"
1516
"github.com/gocql/gocql"
1617
"github.com/google/uuid"
1718
)
@@ -30,6 +31,12 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
3031
user.Roles = defaultRoles
3132
}
3233

34+
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
35+
if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil && u.ID != user.ID {
36+
return user, fmt.Errorf("user with given phone number already exists")
37+
}
38+
}
39+
3340
user.CreatedAt = time.Now().Unix()
3441
user.UpdatedAt = time.Now().Unix()
3542

@@ -299,3 +306,14 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
299306

300307
return nil
301308
}
309+
310+
// GetUserByPhoneNumber to get user information from database using phone number
311+
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
312+
var user models.User
313+
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, phoneNumber)
314+
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt)
315+
if err != nil {
316+
return nil, err
317+
}
318+
return &user, nil
319+
}

server/db/providers/dynamodb/env.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
3434

3535
// UpdateEnv to update environment information in database
3636
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
37-
3837
collection := p.db.Table(models.Collections.Env)
3938
env.UpdatedAt = time.Now().Unix()
4039

server/db/providers/dynamodb/user.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ package dynamodb
33
import (
44
"context"
55
"errors"
6+
"fmt"
7+
"strings"
68
"time"
79

810
"github.com/authorizerdev/authorizer/server/constants"
911
"github.com/authorizerdev/authorizer/server/db/models"
1012
"github.com/authorizerdev/authorizer/server/graph/model"
1113
"github.com/authorizerdev/authorizer/server/memorystore"
14+
"github.com/authorizerdev/authorizer/server/refs"
1215
"github.com/google/uuid"
1316
"github.com/guregu/dynamo"
1417
log "github.com/sirupsen/logrus"
@@ -30,6 +33,12 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
3033
user.Roles = defaultRoles
3134
}
3235

36+
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
37+
if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil {
38+
return user, fmt.Errorf("user with given phone number already exists")
39+
}
40+
}
41+
3342
user.CreatedAt = time.Now().Unix()
3443
user.UpdatedAt = time.Now().Unix()
3544

@@ -193,3 +202,23 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
193202
}
194203
return nil
195204
}
205+
206+
// GetUserByPhoneNumber to get user information from database using phone number
207+
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
208+
var users []models.User
209+
var user models.User
210+
211+
collection := p.db.Table(models.Collections.User)
212+
err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).AllWithContext(ctx, &users)
213+
214+
if err != nil {
215+
return nil, err
216+
}
217+
218+
if len(users) > 0 {
219+
user = users[0]
220+
return &user, nil
221+
} else {
222+
return nil, errors.New("no record found")
223+
}
224+
}

server/db/providers/mongodb/user.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,16 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
155155
}
156156
return nil
157157
}
158+
159+
// GetUserByPhoneNumber to get user information from database using phone number
160+
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
161+
var user models.User
162+
163+
userCollection := p.db.Collection(models.Collections.User, options.Collection())
164+
err := userCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&user)
165+
if err != nil {
166+
return nil, err
167+
}
168+
169+
return &user, nil
170+
}

server/db/providers/provider_template/user.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,10 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
6969

7070
return nil
7171
}
72+
73+
// GetUserByPhoneNumber to get user information from database using phone number
74+
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
75+
var user *models.User
76+
77+
return user, nil
78+
}

server/db/providers/providers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ type Provider interface {
1818
ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error)
1919
// GetUserByEmail to get user information from database using email address
2020
GetUserByEmail(ctx context.Context, email string) (models.User, error)
21+
// GetUserByPhoneNumber to get user information from database using phone number
22+
GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error)
2123
// GetUserByID to get user information from database using user ID
2224
GetUserByID(ctx context.Context, id string) (models.User, error)
2325
// UpdateUsers to update multiple users, with parameters of user IDs slice

0 commit comments

Comments
 (0)