Skip to content

Commit

Permalink
Added and ran Black
Browse files Browse the repository at this point in the history
Changes to be committed:
	modified:   server/authentication/apis.py
	modified:   server/authentication/selectors.py
	modified:   server/authentication/services.py
	modified:   server/authentication/urls.py
	modified:   server/bcodb/admin.py
	modified:   server/bcodb/apis.py
	modified:   server/bcodb/migrations/0004_alter_bcodb_group_permissions_and_more.py
	modified:   server/bcodb/migrations/0005_alter_bcodb_user_permissions.py
	modified:   server/bcodb/migrations/0006_alter_bcodb_group_permissions_and_more.py
	modified:   server/bcodb/migrations/0007_bco.py
	modified:   server/bcodb/migrations/0008_remove_bcodb_group_permissions.py
	modified:   server/bcodb/models.py
	modified:   server/bcodb/selectors.py
	modified:   server/bcodb/services.py
	modified:   server/bcodb/urls.py
	modified:   server/config/settings.py
	modified:   server/config/urls.py
	modified:   server/manage.py
	modified:   server/portaluserdb/settings.py
	modified:   server/prefix/admin.py
	modified:   server/prefix/apis.py
	modified:   server/prefix/migrations/0001_initial.py
	modified:   server/prefix/migrations/0002_prefix_public_prefix_public_hostname.py
	modified:   server/prefix/models.py
	modified:   server/prefix/selectors.py
	modified:   server/prefix/services.py
	modified:   server/prefix/urls.py
	modified:   server/requirements.txt
	modified:   server/tests/__init__.py
	modified:   server/tests/test_views/__init__.py
	modified:   server/tests/test_views/test_auth_register.py
	modified:   server/tests/test_views/test_draft_bco_add.py
	modified:   server/tests/test_views/test_draft_bco_delete.py
	modified:   server/tests/test_views/test_draft_bco_get.py
	modified:   server/tests/test_views/test_orcid_add.py
	modified:   server/tests/test_views/test_orcid_auth.py
	modified:   server/tests/test_views/test_orcid_remove.py
	modified:   server/users/apis.py
	modified:   server/users/migrations/0002_alter_profile_affiliation_alter_profile_orcid.py
	modified:   server/users/selectors.py
	modified:   server/users/services.py
  • Loading branch information
HadleyKing committed Jun 21, 2024
1 parent 76ab2dc commit b939bee
Show file tree
Hide file tree
Showing 41 changed files with 730 additions and 639 deletions.
147 changes: 72 additions & 75 deletions server/authentication/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@
from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.blacklist.serializers import BlacklistTokenSerializer
from authentication.services import custom_jwt_handler, google_authentication, orcid_auth_code, authenticate_orcid
from authentication.services import (
custom_jwt_handler,
google_authentication,
orcid_auth_code,
authenticate_orcid,
)
from users.models import Profile
from users.services import user_create
from users.selectors import user_from_email, user_from_orcid, profile_from_username


@receiver(reset_password_token_created)
def password_reset_token_created(
sender, instance, reset_password_token, *args, **kwargs
Expand All @@ -42,12 +48,7 @@ def password_reset_token_created(
activation_link = ""
template = ""

activation_link = (
settings.PUBLIC_HOSTNAME
+ "/password/confirm/?"
+ f"{token}"
)

activation_link = settings.PUBLIC_HOSTNAME + "/password/confirm/?" + f"{token}"

template = '<html><body><p>Please click this link within the next 10 minutes to reset your BioCompute Portal password: <a href="{}" target="_blank">{}</a>.</p></body></html>'.format(
activation_link, activation_link
Expand Down Expand Up @@ -77,6 +78,7 @@ def password_reset_token_created(
},
)


class OrcidUserInfoApi(APIView):
auth = [
openapi.Parameter(
Expand All @@ -94,19 +96,18 @@ class OrcidUserInfoApi(APIView):
responses={
200: "Request is successful.",
401: "A user with that ORCID does not exist.",
403: "Authentication credentials were not provided, or were not valid."
403: "Authentication credentials were not provided, or were not valid.",
},
tags=["Account Management"],
)

def post(self, request):
"""Orcid User Info Api
API view for getting user info in with ORCID OAuth authentication.
"""

if 'Authorization' in request.headers:
type, token = request.headers['Authorization'].split(' ')
if "Authorization" in request.headers:
type, token = request.headers["Authorization"].split(" ")

try:
unverified_payload = jwt.decode(
Expand All @@ -115,25 +116,25 @@ def post(self, request):
except Exception as exp:
raise exceptions.AuthenticationFailed(exp)

if request.META['HTTP_REFERER'] == 'http://localhost:8080/users/docs/':
unverified_payload['iss'] = 'https://sandbox.orcid.org/'
if request.META["HTTP_REFERER"] == "http://localhost:8080/users/docs/":
unverified_payload["iss"] = "https://sandbox.orcid.org/"
else:
unverified_payload['iss'] = 'https://orcid.org/'
unverified_payload["iss"] = "https://orcid.org/"

try:
user = authenticate_orcid(unverified_payload, token)
except Exception as exp:
raise exceptions.AuthenticationFailed(exp)

return Response(
status=status.HTTP_200_OK,
data=custom_jwt_handler(token, user)
status=status.HTTP_200_OK, data=custom_jwt_handler(token, user)
)
return Response(
status=status.HTTP_403_FORBIDDEN,
data={"message": "Authentication credentials were not provided."}
data={"message": "Authentication credentials were not provided."},
)


class OrcidLoginApi(APIView):
permission_classes = (permissions.AllowAny,)
auth = [
Expand All @@ -146,7 +147,7 @@ class OrcidLoginApi(APIView):
]

@swagger_auto_schema(
manual_parameters = auth,
manual_parameters=auth,
responses={
200: "Login is successful.",
401: "Unathorized.",
Expand All @@ -159,11 +160,14 @@ def get(self, request):
API view for logging in with ORCID OAuth authentication.
"""

auth_code = self.request.GET['code']
orcid_auth = orcid_auth_code(auth_code, path='/login')
auth_code = self.request.GET["code"]
orcid_auth = orcid_auth_code(auth_code, path="/login")
if "access_token" not in orcid_auth:
return Response(status=status.HTTP_401_UNAUTHORIZED, data={"message": orcid_auth['error_description']})
user = user_from_orcid(orcid_auth['orcid'])
return Response(
status=status.HTTP_401_UNAUTHORIZED,
data={"message": orcid_auth["error_description"]},
)
user = user_from_orcid(orcid_auth["orcid"])
if user != 0:
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
Expand All @@ -180,6 +184,7 @@ def get(self, request):
data={"message": "That account does not exist"},
)


class OrcidAddApi(APIView):
auth = [
openapi.Parameter(
Expand All @@ -191,31 +196,27 @@ class OrcidAddApi(APIView):
]

@swagger_auto_schema(
manual_parameters = auth,
responses={
200: "Add ORCID successful.",
401: "Unathorized.",
500: "Error"
},
manual_parameters=auth,
responses={200: "Add ORCID successful.", 401: "Unathorized.", 500: "Error"},
tags=["Account Management"],
)
def post(self, request):
"""Add Orcid API
"""Add Orcid API
This API view allows for a user to add an ORCID for OAuth authentication. The
request should include a valid JWT token in the authorization header.
Returns the updated user information in the response body.
"""
auth_code = self.request.GET['code']
orcid_auth = orcid_auth_code(auth_code, path='/profile')
auth_code = self.request.GET["code"]
orcid_auth = orcid_auth_code(auth_code, path="/profile")
if "access_token" not in orcid_auth:
return Response(
status=status.HTTP_401_UNAUTHORIZED,
data={"message": orcid_auth['error_description']}
data={"message": orcid_auth["error_description"]},
)
conflict = user_from_orcid(orcid_auth['orcid'])

conflict = user_from_orcid(orcid_auth["orcid"])
if conflict != 0:
return Response(
status=status.HTTP_403_FORBIDDEN,
Expand All @@ -226,20 +227,16 @@ def post(self, request):
token = request.headers["Authorization"].removeprefix("Bearer ")
profile = profile_from_username(user.username)
bcodbs = get_all_bcodbs(profile)
profile.orcid = settings.ORCID_URL + '/' + orcid_auth['orcid']
profile.orcid = settings.ORCID_URL + "/" + orcid_auth["orcid"]
profile.save()
auth_obj = {
"iss": settings.ORCID_URL,
"sub": orcid_auth['orcid']
}
auth_obj = {"iss": settings.ORCID_URL, "sub": orcid_auth["orcid"]}
for bcodb in bcodbs:
add_authentication(auth_obj, bcodb)
return Response(
status=status.HTTP_200_OK, data=custom_jwt_handler(token, user)
)
return Response(status=status.HTTP_200_OK, data=custom_jwt_handler(token, user))


class OrcidRemoveApi(APIView):
permission_classes=[permissions.IsAuthenticated]
permission_classes = [permissions.IsAuthenticated]
auth = [
openapi.Parameter(
"Authorization",
Expand All @@ -250,11 +247,11 @@ class OrcidRemoveApi(APIView):
]

@swagger_auto_schema(
manual_parameters = auth,
manual_parameters=auth,
responses={
200: "Remove ORCID successful.",
401: "Unathorized.",
403: "Bad request"
403: "Bad request",
},
tags=["Account Management"],
)
Expand All @@ -269,34 +266,33 @@ def post(self, request):
user = request.user
profile = profile_from_username(user.username)
token = request.headers["Authorization"].removeprefix("Bearer ")
auth_obj = {
"iss": settings.ORCID_URL,
"sub": profile.orcid.split('/')[-1]
}
auth_obj = {"iss": settings.ORCID_URL, "sub": profile.orcid.split("/")[-1]}
profile.orcid = ""
profile.save()
bcodbs = get_all_bcodbs(profile)
for bcodb in bcodbs:
remove_authentication(auth_obj, bcodb)
return Response(
status=status.HTTP_200_OK, data=custom_jwt_handler(token, user)
)
return Response(status=status.HTTP_200_OK, data=custom_jwt_handler(token, user))


class GoogleUsername(serializers.CharField):
"""Google Username Serializer
Custom serializer field for Google username that removes whitespace from
the input value.
"""

def convert(self, value):
username = value.replace(" ", "")
return super().convert(username)


class GoogleInputSerializer(serializers.Serializer):
"""Google Input Serializer
Serializer class for Google authentication input data, including email,
first name, last name, and username.
"""

email = serializers.EmailField()
first_name = serializers.CharField(required=False, default="")
last_name = serializers.CharField(required=False, default="")
Expand All @@ -312,19 +308,21 @@ def to_internal_value(self, data):
Call the parent method to handle validation and processing
"""

if not data.get('username'):
username = (data.get('given_name', '') + data.get('family_name', ''))
if not data.get("username"):
username = data.get("given_name", "") + data.get("family_name", "")
username = username.replace(" ", "")
data['username'] = username
data["username"] = username

return super().to_internal_value(data)


class GoogleRegisterApi(APIView):
"""
API view for registering a user with Google OAuth authentication.
Handle POST requests for user registration with Google OAuth
authentication.
"""

permission_classes = (permissions.AllowAny,)

@swagger_auto_schema(
Expand All @@ -334,26 +332,25 @@ class GoogleRegisterApi(APIView):
},
tags=["Account Management"],
)

def post(self, request):
"""Google Register
API view for registering a user with Google OAuth authentication.
Handle POST requests for user registration with Google OAuth
authentication.
"""
user_data = request.data['data']
user_data['username'] = user_data['username'].replace(" ","")
user_data = request.data["data"]
user_data["username"] = user_data["username"].replace(" ", "")
user_serializer = GoogleInputSerializer(data=request.data["data"])
user_serializer.is_valid(raise_exception=True)

try:
user_from_email(user_data['email'])
user_from_email(user_data["email"])
return Response(
status=status.HTTP_409_CONFLICT,
data={"message": "A user with that email address already exists."}
data={"message": "A user with that email address already exists."},
)

except User.DoesNotExist:
user = user_create(**user_serializer.validated_data)
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
Expand All @@ -366,6 +363,7 @@ def post(self, request):
status=status.HTTP_200_OK, data=custom_jwt_handler(token, user)
)


class GoogleLoginApi(APIView):

permission_classes = (permissions.AllowAny,)
Expand All @@ -377,13 +375,12 @@ class GoogleLoginApi(APIView):
},
tags=["Account Management"],
)

def post(self, request):
"""Google Login
API view for logging in with Google OAuth authentication.
"""

google_response = google_authentication(request)
if type(google_response) == Response:
return google_response
Expand All @@ -408,28 +405,28 @@ def post(self, request):
data={"message": "That account does not exist"},
)


class LogOutApi(ModelViewSet):

queryset = BlacklistedToken.objects.all()
serializer_class = BlacklistTokenSerializer
permission_classes = (IsAuthenticated, )
permission_classes = (IsAuthenticated,)

@swagger_auto_schema(
responses={
200: "Logout is successful.",
401: "A user with that ORCID does not exist.",
403: "Authentication credentials were not provided."
403: "Authentication credentials were not provided.",
},
tags=["Account Management"],
)

def create(self, request, *args, **kwargs):
"""Logout API
Adds submited token to the list of blackli
"""
if 'token' not in request.data:
request.data.update({
'token': JSONWebTokenAuthentication.get_token_from_request(request)
})
if "token" not in request.data:
request.data.update(
{"token": JSONWebTokenAuthentication.get_token_from_request(request)}
)

return super(LogOutApi, self).create(request, *args, **kwargs)
return super(LogOutApi, self).create(request, *args, **kwargs)
Loading

0 comments on commit b939bee

Please sign in to comment.