|
100 | 100 | OSFUser, |
101 | 101 | Email, |
102 | 102 | Tag, |
| 103 | + PreprintProvider, |
103 | 104 | ) |
104 | 105 | from osf.utils.tokens import TokenHandler |
105 | 106 | from osf.utils.tokens.handlers import sanction_handler |
106 | 107 | from website import mails, settings, language |
107 | 108 | from website.project.views.contributor import send_claim_email, send_claim_registered_email |
108 | 109 | from website.util.metrics import CampaignClaimedTags, CampaignSourceTags |
109 | 110 | from framework.auth import exceptions |
| 111 | +from website.project.views.contributor import _add_related_claimed_tag_to_user |
| 112 | +from website.util import api_v2_url |
110 | 113 |
|
111 | 114 |
|
112 | 115 | class UserMixin: |
@@ -1008,6 +1011,86 @@ def post(self, request, *args, **kwargs): |
1008 | 1011 |
|
1009 | 1012 | return Response(status=status.HTTP_204_NO_CONTENT) |
1010 | 1013 |
|
| 1014 | +class ConfirmClaimUser(JSONAPIBaseView, generics.CreateAPIView, UserMixin): |
| 1015 | + |
| 1016 | + view_category = 'users' |
| 1017 | + view_name = 'confirm-claim-user' |
| 1018 | + |
| 1019 | + def verify_claim_token(self, user, token, pid): |
| 1020 | + """View helper that checks that a claim token for a given user and node ID |
| 1021 | + is valid. If not valid, throws an error with custom error messages. |
| 1022 | + """ |
| 1023 | + # if token is invalid, throw an error |
| 1024 | + if not user.verify_claim_token(token=token, project_id=pid): |
| 1025 | + if user.is_registered: |
| 1026 | + raise ValidationError('User has already been claimed.') |
| 1027 | + else: |
| 1028 | + return False |
| 1029 | + return True |
| 1030 | + |
| 1031 | + def post(self, request, *args, **kwargs): |
| 1032 | + """ |
| 1033 | + View for setting the password for a claimed user. |
| 1034 | + Sets the user's password. |
| 1035 | + HTTP Method: POST |
| 1036 | + **URL:** /v2/users/<user_id>/confirm_claim/ |
| 1037 | + **Body (JSON):** |
| 1038 | + { |
| 1039 | + "data": { |
| 1040 | + "type": "users", |
| 1041 | + "attributes": { |
| 1042 | + "guid": "node/preprint guid", |
| 1043 | + "token": "token", |
| 1044 | + "password": "password", |
| 1045 | + "accepted_terms_of_service": bool |
| 1046 | + } |
| 1047 | + } |
| 1048 | + } |
| 1049 | + """ |
| 1050 | + |
| 1051 | + uid = kwargs['user_id'] |
| 1052 | + token = request.data.get('token') |
| 1053 | + guid = request.data.get('guid') |
| 1054 | + password = request.data.get('password') |
| 1055 | + accepted_terms_of_service = request.data.get('accepted_terms_of_service', False) |
| 1056 | + user = OSFUser.load(uid) |
| 1057 | + |
| 1058 | + # If unregistered user is not in database, or url bears an invalid token raise HTTP 400 error |
| 1059 | + if not user or not self.verify_claim_token(user, token, guid): |
| 1060 | + raise ValidationError('Claim user does not exists, the token in the URL is invalid or has expired.') |
| 1061 | + |
| 1062 | + # If user is logged in, need to use 'confirm_claim_registered' view |
| 1063 | + if request.user.is_authenticated: |
| 1064 | + raise ValidationError('You are already logged in. Please log out before trying to claim a user via this view.') |
| 1065 | + |
| 1066 | + unclaimed_record = user.unclaimed_records[guid] |
| 1067 | + user.fullname = unclaimed_record['name'] |
| 1068 | + user.update_guessed_names() |
| 1069 | + username = unclaimed_record.get('claimer_email') or unclaimed_record.get('email') |
| 1070 | + |
| 1071 | + user.register(username=username, password=password, accepted_terms_of_service=accepted_terms_of_service) |
| 1072 | + # Clear unclaimed records |
| 1073 | + user.unclaimed_records = {} |
| 1074 | + user.verification_key = generate_verification_key() |
| 1075 | + user.save() |
| 1076 | + provider = PreprintProvider.load(guid) |
| 1077 | + redirect_url = None |
| 1078 | + if provider: |
| 1079 | + redirect_url = api_v2_url('auth_login', next=provider.landing_url, _absolute=True) |
| 1080 | + else: |
| 1081 | + # Add related claimed tags to user |
| 1082 | + _add_related_claimed_tag_to_user(guid, user) |
| 1083 | + redirect_url = api_v2_url('resolve_guid', guid=guid, _absolute=True) |
| 1084 | + |
| 1085 | + data = { |
| 1086 | + 'firstname': user.given_name, |
| 1087 | + 'email': username if username else '', |
| 1088 | + 'fullname': user.fullname, |
| 1089 | + 'osf_contact_email': settings.OSF_CONTACT_EMAIL, |
| 1090 | + 'next': redirect_url, |
| 1091 | + } |
| 1092 | + |
| 1093 | + return Response(status=status.HTTP_200_OK, data=data) |
1011 | 1094 |
|
1012 | 1095 | class ConfirmEmailView(generics.CreateAPIView): |
1013 | 1096 | """ |
|
0 commit comments