Skip to content

Commit b3abd90

Browse files
committed
Account activation has been enabled.
On branch account_authorization Changes to be committed: modified: api/urls.py modified: api/views.py modified: authentication/apis.py modified: authentication/selectors.py modified: authentication/services.py modified: authentication/urls.py
1 parent 448b1e9 commit b3abd90

File tree

6 files changed

+105
-94
lines changed

6 files changed

+105
-94
lines changed

api/urls.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from drf_yasg import openapi
1919

2020
from api.views import (
21-
ApiAccountsActivateUsernameTempIdentifier,
2221
ApiAccountsDescribe,
2322
ApiGroupsCreate,
2423
ApiGroupsInfo,
@@ -127,10 +126,6 @@
127126
ObjectIdRootObjectIdVersion.as_view(),
128127
),
129128
path("<str:object_id_root>", ObjectIdRootObjectId.as_view()),
130-
path(
131-
"api/accounts/activate/<str:username>/<str:temp_identifier>",
132-
ApiAccountsActivateUsernameTempIdentifier.as_view(),
133-
),
134129
path("api/accounts/describe/", ApiAccountsDescribe.as_view()),
135130
path("api/groups/group_info/", ApiGroupsInfo.as_view()),
136131
path("api/groups/create/", ApiGroupsCreate.as_view()),

api/views.py

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -130,71 +130,6 @@ def check_get(request) -> Response:
130130
# Placeholder
131131
return Response(status=status.HTTP_200_OK)
132132

133-
134-
class ApiAccountsActivateUsernameTempIdentifier(APIView):
135-
"""
136-
Activate an account
137-
138-
--------------------
139-
140-
This endpoint is a GET request to activate a new account.
141-
To activate an account during registration we receive an email or a
142-
temporary identifier to authenticate and activate account. This endpoint
143-
will check the validity of the provided temporary identifier for a specific
144-
user account. This is open to anyone to activate a new account, as long as
145-
they have a valid token generated by this host. This allows other users
146-
to act as the verification layer in addition to the system.
147-
148-
"""
149-
150-
authentication_classes = []
151-
permission_classes = []
152-
153-
# For the success and error messages
154-
renderer_classes = [TemplateHTMLRenderer]
155-
template_name = "api/account_activation_message.html"
156-
157-
auth = []
158-
auth.append(
159-
openapi.Parameter(
160-
"username",
161-
openapi.IN_PATH,
162-
description="Username to be authenticated.",
163-
type=openapi.TYPE_STRING,
164-
)
165-
)
166-
auth.append(
167-
openapi.Parameter(
168-
"temp_identifier",
169-
openapi.IN_PATH,
170-
description="The temporary identifier needed to authenticate the activation. This "
171-
"is found in the temporary account table (i.e. where an account is "
172-
"staged).",
173-
type=openapi.TYPE_STRING,
174-
)
175-
)
176-
177-
@swagger_auto_schema(
178-
manual_parameters=auth,
179-
responses={
180-
200: "Account has been activated.",
181-
403: "Requestor's credentials were rejected.",
182-
},
183-
tags=["Account Management"],
184-
)
185-
def get(self, request, username: str, temp_identifier: str):
186-
check_get(request)
187-
checked = None
188-
if checked is None:
189-
return GET_activate_account(
190-
username=username, temp_identifier=temp_identifier
191-
)
192-
else:
193-
return Response(
194-
{"activation_success": False, "status": status.HTTP_400_BAD_REQUEST}
195-
)
196-
197-
198133
# Source: https://www.django-rest-framework.org/api-guide/authentication/#by-exposing-an-api-endpoint
199134
class ApiAccountsDescribe(APIView):
200135
"""

authentication/apis.py

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
create_bcodb_user,
1919
send_bcodb,
2020
validate_auth_service,
21-
new_user_email
21+
send_new_user_email
2222
)
2323

2424
class NewAccountApi(APIView):
@@ -33,14 +33,6 @@ class NewAccountApi(APIView):
3333
The account create depends on creation of an account in the associated
3434
user database. The authentication as well as the user database host
3535
information is used to make this request.
36-
37-
```JSON
38-
{
39-
"hostname": "http://localhost:8000",
40-
"email": "[email protected]",
41-
"token": "eyJ1c2VyX2lkIjoyNCwidXNlcm5hbWUiOiJoYWRsZXlraW5nIiwiZXhwIjoxNjQwNzE5NTUwLCJlbWFpbCI6ImhhZGxleV9raW5nQGd3dS5lZHUiLCJvcmlnX2lhdCI6MTY0MDExNDc1MH0.7G3VPmxUBOWFfu-fMt1_UsWAcH_Gd1DfpQa83EwFwYY"
42-
}
43-
```
4436
"""
4537

4638
class InputSerializer(serializers.Serializer):
@@ -109,6 +101,7 @@ def post(self, request) -> Response:
109101
status=status.HTTP_201_CREATED,
110102
data={"message":"Testing account request successful!!"}
111103
)
104+
112105
if check_user_email(email) is True:
113106
return Response(
114107
status=status.HTTP_409_CONFLICT,
@@ -129,14 +122,84 @@ def post(self, request) -> Response:
129122
)
130123

131124
try:
132-
new_user_email(serializer.validated_data)
133-
return Response(status=status.HTTP_201_CREATED, data={"message":""})
125+
send_new_user_email(serializer.validated_data)
126+
return Response(
127+
status=status.HTTP_201_CREATED,
128+
data={"message":"Account request granted. Check your email"\
129+
+ " for an activation link."}
130+
)
134131
except Exception as error:
135132
return Response(
136133
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
137134
data={"message": str(error)}
138135
)
139136

137+
class AccountActivateApi(APIView):
138+
"""
139+
Activate an account
140+
141+
--------------------
142+
143+
This endpoint is a GET request to activate a new account.
144+
To activate an account during registration the userwill receive an email
145+
or a temporary identifier to authenticate and activate account. This
146+
endpoint will check the validity of the provided temporary identifier for
147+
a specific user account. This is open to anyone to activate a new account,
148+
as long as they have a valid token generated by this host. This can allow
149+
other users to act as the verification layer in addition to the system.
150+
"""
151+
152+
authentication_classes = []
153+
permission_classes = []
154+
155+
auth = []
156+
auth.append(
157+
openapi.Parameter(
158+
"username",
159+
openapi.IN_PATH,
160+
description="Username to be authenticated.",
161+
type=openapi.TYPE_STRING,
162+
163+
)
164+
)
165+
auth.append(
166+
openapi.Parameter(
167+
"temp_identifier",
168+
openapi.IN_PATH,
169+
description="The temporary identifier sent",
170+
type=openapi.TYPE_STRING,
171+
default="testTempIdentifier123456789"
172+
)
173+
)
174+
175+
@swagger_auto_schema(
176+
manual_parameters=auth,
177+
responses={
178+
200: "Account has been activated.",
179+
403: "Requestor's credentials were rejected.",
180+
},
181+
tags=["Authentication and Account Management"],
182+
)
183+
184+
def get(self, request, username: str, temp_identifier: str) -> Response:
185+
if check_user_email(username) is True:
186+
return Response(
187+
status=status.HTTP_409_CONFLICT,
188+
data={
189+
"message":f"CONFLICT: That account, {username}, has already "\
190+
+ "been activated."
191+
}
192+
)
193+
new_user = check_new_user(username, temp_identifier)
194+
print(new_user)
195+
create_bcodb_user(new_user.email)
196+
new_user.delete()
197+
return Response(
198+
status=status.HTTP_200_OK,
199+
data={"message":f"Account for {username} has been activated"}
200+
)
201+
202+
140203
class RegisterUserNoVerificationAPI(APIView):
141204
"""Register BCODB
142205
API View to register a new BCODB user with out an email verification step.
@@ -181,14 +244,15 @@ def post(self, request):
181244
user_info.is_valid(raise_exception=True)
182245
token = user_info.validated_data['token']
183246
url = user_info.validated_data['hostname']
247+
email = user_info.validated_data['email']
184248
if validate_token(token, url) is False:
185249
return Response(status=status.HTTP_401_UNAUTHORIZED, data={"message": "portal authentication was invalid"})
186-
if check_user_email(user_info.validated_data['email']) is True:
250+
if check_user_email(email) is True:
187251
return Response(
188252
status=status.HTTP_409_CONFLICT,
189253
data={"message": "A BCODB account with that email already exists"}
190254
)
191-
user = create_bcodb_user(user_info=user_info.validated_data)
255+
user = create_bcodb_user(email)
192256
data = json.dumps(get_user_info(user), default=str)
193257
response = send_bcodb(
194258
data=data, request_info=user_info.validated_data

authentication/selectors.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,18 @@ def check_user_email(email: str)-> bool:
4545
except User.DoesNotExist:
4646
return False
4747

48-
def check_new_user(email: str)-> bool:
48+
def check_new_user(email: str, temp_identifier:str=None):
4949
"""Check for new user
5050
51-
Using the provided email check for a new user in the DB
51+
Using the provided email check for a new user in the DB.
52+
If the temp id is supplied and matches it will return the new user object.
5253
"""
53-
54+
5455
try:
55-
if NewUser.objects.get(email=email):
56+
new_user = NewUser.objects.get(email=email)
57+
if new_user.temp_identifier == temp_identifier:
58+
return new_user
59+
else:
5660
return True
5761
except NewUser.DoesNotExist:
5862
return False

authentication/services.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def validate_token(token: str, url: str)-> bool:
153153
return True
154154

155155
@transaction.atomic
156-
def new_user_email(user_info: dict) -> 0:
156+
def send_new_user_email(user_info: dict) -> 0:
157157
"""Send New User Email
158158
159159
New BCODB user authentication email
@@ -171,7 +171,7 @@ def new_user_email(user_info: dict) -> 0:
171171
subject="Registration for BioCompute Portal",
172172
message="Testing.",
173173
html_message='<html><body><p>Please click this link within the next' \
174-
+ ' 10 minutes to activate your BioCompute Portal account: ' \
174+
+ ' 24 hours to activate your BioCompute Portal account: ' \
175175
+ f'<a href={activation_link} target="_blank">{activation_link}' \
176176
+ '</a>.</p></body></html>',
177177
from_email="[email protected]",
@@ -182,13 +182,13 @@ def new_user_email(user_info: dict) -> 0:
182182
print("Email signal sent")
183183
return 0
184184

185-
def create_bcodb_user(user_info: dict) -> User:
185+
def create_bcodb_user(email: str) -> User:
186186
"""Create BCODB user
187187
"""
188188

189-
username = user_info["email"].split("@")[0]
189+
username = email.split("@")[0]
190190
user = User.objects.create_user(
191-
username=username, email=user_info["email"]
191+
username=username, email=email
192192
)
193193
user.set_unusable_password()
194194
user.full_clean()

authentication/urls.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
# authentication/urls.py
22

33
from django.urls import path
4-
from authentication.apis import RegisterBcodbAPI, AddAuthenticationApi, RemoveAuthenticationApi, ResetTokenApi
4+
from authentication.apis import (
5+
NewAccountApi,
6+
AccountActivateApi,
7+
RegisterUserNoVerificationAPI,
8+
AddAuthenticationApi,
9+
RemoveAuthenticationApi,
10+
ResetTokenApi
11+
)
512

613
urlpatterns = [
7-
path("auth/register/", RegisterBcodbAPI.as_view()),
14+
path(
15+
"accounts/activate/<str:username>/<str:temp_identifier>",
16+
AccountActivateApi.as_view(),
17+
),
18+
# path("api/accounts/describe/", ApiAccountsDescribe.as_view()),
19+
path("accounts/new/", NewAccountApi.as_view()),
20+
path("auth/register/", RegisterUserNoVerificationAPI.as_view()),
821
path("auth/add/", AddAuthenticationApi.as_view()),
922
path("auth/remove/", RemoveAuthenticationApi.as_view()),
1023
path("auth/reset_token/", ResetTokenApi.as_view())

0 commit comments

Comments
 (0)