Skip to content

Commit fc65139

Browse files
committed
feat(backend): Initial account creation endpoints
1 parent e48e28c commit fc65139

File tree

9 files changed

+150
-1
lines changed

9 files changed

+150
-1
lines changed

backend-services/src/common/types.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
from typing import NewType
1+
from typing import NewType, TypeAlias
2+
from odmantic import AIOEngine
23

34
WalletAddress = NewType("WalletAddress", str)
45
"""
56
A type for vault wallet addresses.
67
"""
8+
9+
Engine: TypeAlias = AIOEngine
10+
"""
11+
A database engine instance.
12+
"""
13+
14+
HashString = NewType("HashString", str)
15+
"""
16+
HashString
17+
"""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
User Authentication service for the Nautilus Vault backend.
3+
"""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
The collection of operations provided by the user authenticatioin service.
3+
"""

backend-services/src/user_auth_service/operations/authenticate_user.py

Whitespace-only changes.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from user_auth_service.schema.actions import CreateNewUser, CreateNewUserResult, CreateNewUserSuccess, CreateNewUserFailure
2+
from user_auth_service.schema.entites import UserDetailsStorable, UserDisplay
3+
from common.types import Engine
4+
from passlib.context import CryptContext
5+
6+
argon2_context = CryptContext(schemes=['argon2'], depricated='auto')
7+
8+
def password_hash(password: str):
9+
return argon2_context.hash(password)
10+
11+
12+
async def create_new_user(engine: Engine, params: CreateNewUser) -> CreateNewUserResult:
13+
"""
14+
User Creation.
15+
"""
16+
hash_password = password_hash(params.password)
17+
18+
new_user = UserDetailsStorable(
19+
email_address = params.email_address,
20+
full_name = params.full_name,
21+
phone_number = params.phone_number,
22+
password_hash_string = hash_password
23+
)
24+
try:
25+
await engine.save(new_user)
26+
user_display = UserDisplay(
27+
email_address = params.email_address,
28+
full_name = params.full_name,
29+
phone_number = params.phone_number
30+
)
31+
return CreateNewUserSuccess(created=user_display)
32+
except:
33+
return CreateNewUserFailure(
34+
Failed = 'Unable to create new user.'
35+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
Internals and abstractions for the User Authentication service.
3+
"""
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from user_auth_service.schema.entites import UserDisplay
2+
from pydantic import BaseModel
3+
4+
from common.types import WalletAddress
5+
from datetime import datetime
6+
from typing import TypeAlias
7+
8+
9+
class CreateNewUser(BaseModel):
10+
"""
11+
User creation parameters.
12+
"""
13+
14+
full_name: str
15+
phone_number: str
16+
email_address: str
17+
password: str
18+
19+
class CreateNewUserSuccess(BaseModel):
20+
"""
21+
Return email address, full name, and phone number.
22+
"""
23+
24+
Created: UserDisplay
25+
26+
class CreateNewUserFailure(BaseModel):
27+
"""
28+
Return Failure if user's credentials is not created.
29+
"""
30+
Failed: str
31+
32+
CreateNewUserResult: TypeAlias = CreateNewUserSuccess | CreateNewUserFailure
33+
34+
class AuthenticateUser(BaseModel):
35+
"""
36+
Authentic user parameters.
37+
"""
38+
email_address: str
39+
password: str
40+
41+
class AuthenticateUserSuccess(BaseModel):
42+
"""
43+
Successfully authenticated user.
44+
"""
45+
46+
Opened: str
47+
48+
class AuthenticateUserFailure(BaseModel):
49+
"""
50+
Failed to authenticate user.
51+
"""
52+
53+
Failed: str
54+
55+
class AuthenticateUserResult: TypeAlias = AuthenticateUserSuccess | AuthenticateUserFailure
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import TypeAlias
2+
from common.types import HashString
3+
4+
from odmantic import Model
5+
from pydantic import BaseModel
6+
7+
from common.types import HashString
8+
9+
class UserDetailsStorable(Model):
10+
"""
11+
Storing new ueser's credentials.
12+
"""
13+
14+
email_address: str
15+
full_name: str;
16+
phone_number: str
17+
password_hash_string: HashString;
18+
19+
class UserDisplay(BaseModel):
20+
"""
21+
Return User credentials when user is created or opened.
22+
"""
23+
24+
email_address: str
25+
owner_name: str
26+
phone_number: str
27+

backend-services/src/web_asgi/main.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
from data_service.schema.entities import Dataset, DatasetList, Datapool, DatapoolList, Dataschema
1515

1616
from data_service.operations.datapool import datapools, create_datapool, delete_datapool
17+
from data_service.operations.dataschema import create_dataschema
18+
19+
from user_auth_service.schema.actions import CreateNewUser
20+
from user_auth_service.schema.actions import CreateNewUserResult
21+
from user_auth_service.operations import create_new_user
1722

1823
from web_asgi.settings import AppSettings
1924

@@ -85,3 +90,10 @@ async def post_delete_datapool(request: DeleteDatapool) -> None:
8590
)
8691
async def post_dataschema_create(request: CreateDataschema) -> Dataschema:
8792
return await create_dataschema(mongo_engine, request)
93+
94+
95+
@app.post(
96+
"/auth/create", response_model=CreateNewUserResult, status_code=status.HTTP_201_CREATED
97+
)
98+
async def post_create_new_user(request: CreateNewUser) -> CreateNewUserResult:
99+
return await create_new_user(mongo_engine, request)

0 commit comments

Comments
 (0)