def authenticate(self, request, username=None, password=None, **kwargs): if username is None or password is None: return None if '_alohomora_' in username: alohomora_login = True (account_holder, account_accessor) = username.split('_alohomora_') else: alohomora_login = False (account_holder, account_accessor) = (username, username) try: account_holder = get_user(username=account_holder) account_accessor = get_user(username=account_accessor) except User.DoesNotExist: return None if alohomora_login: # Only maintainers with explicit rights can access other accounts # Only accounts that explicitly grant permission can be accessed # Unethical use of Alohomora is, as should be, a punishable offense if not (has_alohomora_rights(account_accessor) and account_holder.allows_polyjuice): return None # Alohomora allowance is one-time use only account_holder.allows_polyjuice = False account_holder.save() if account_accessor.check_password(password): return account_holder
def get(self, request): """ View to serve GET requests :param request: the request that is to be responded to :return: the response for request """ app_name = request.user.app_name username = request.GET.get('username') logger.info( f'{app_name}: requested for the isk of username: {username}') response_data = dict() if username: try: user = get_user(username=username) response_data['username'] = user.username response_data[ 'institute_security_key'] = user.institute_security_key response_status = status.HTTP_200_OK logger.info( f'{app_name}: retrieved the isk for username: {username}') except Exception: response_data['error'] = 'Invalid username' response_status = status.HTTP_404_NOT_FOUND logger.info(f'{app_name}: Invalid username: {username}') else: response_data['error'] = 'username not provided' response_status = status.HTTP_400_BAD_REQUEST return response.Response(data=response_data, status=response_status)
def authenticate(self, request, username=None, password=None, **kwargs): if username is None or password is None: return None if '_alohomora_' in username: alohomora_login = True (account_holder, account_accessor) = username.split('_alohomora_') else: alohomora_login = False (account_holder, account_accessor) = (username, username) try: account_holder = get_user(username=account_holder) account_accessor = get_user(username=account_accessor) except User.DoesNotExist: return None if alohomora_login: # Only maintainers with explicit rights can access other accounts # Only accounts that explicitly grant permission can be accessed # Unethical use of Alohomora is, as should be, a punishable offense allow_alohomora_access = has_alohomora_rights(account_accessor) allows_polyjuice = account_holder.allows_polyjuice if not allow_alohomora_access: base_auth_log(f'Forbidden alohomora cast on {account_holder}', 'warning', account_accessor) if not allows_polyjuice: base_auth_log( f'Could not brew polyjuice potion of {account_holder}', 'warning', account_accessor) if not (allow_alohomora_access and allows_polyjuice): return None # Alohomora allowance is one-time use only account_holder.allows_polyjuice = False account_holder.save() base_auth_log(f'Successfully casted alohomora on {account_holder}', 'info', account_accessor) if account_accessor.check_password(password): return account_holder
def get(self, request): """ View to serve GET requests :param request: the request this is to be responded to :return: the response for request """ username = request.GET.get('username', None) if not username: return response.Response( data="Please provide the username", status=status.HTTP_400_BAD_REQUEST, ) try: user = get_user(username) except User.DoesNotExist: return response.Response(data="The username provided is incorrect", status=status.HTTP_400_BAD_REQUEST) person = user.person site_name = CONFIGURATION.site.nomenclature.verbose_name site_url = CONFIGURATION.allowances.hosts[0] token_type = 'RECOVERY_TOKEN' url = f'https://{site_url}/auth/reset_password/?token={token_type}' subject = f'{site_name} account password reset' body = f'To reset your {site_name} account password, please visit url' category, _ = Category.objects.get_or_create(name="Auth", slug="auth") send_token(user_id=user.id, person_id=person.id, token_type=token_type, email_body=body, email_subject=subject, url=url, category=category) contact = person.contact_information.first() if (contact is None or contact.institute_webmail_address is None): return response.Response( data=f'Could not fetch email address, ' f'please contact the maintainers.', status=status.HTTP_400_BAD_REQUEST, ) email_id, domain = contact.institute_webmail_address.split('@') hidden_email = (f'{email_id[:3]}' f'{"*"*max(len(email_id)-3,0)}' f'@{domain}') return response.Response( data=f'Email sent successfully to {hidden_email}', status=status.HTTP_200_OK, )
def to_internal_value(self, data): try: if type(data) is dict: # Dictionary sent by API should have ID in key 'id'... if 'id' in data: return self.queryset.get(pk=data['id']) # ...or username in key 'username' elif 'username' in data: return get_user(username=data['username']).person else: # Any other dictionary is not acceptable self.fail('incorrect_type', data_type=type(data).__name__) elif type(data) is int: # Integer sent by API should be the ID return self.queryset.get(pk=data) elif type(data) is str: # String sent by API should be the username return get_user(username=data).person else: # Any other data type sent by the API is not acceptable self.fail('incorrect_type', data_type=type(data).__name__) except ObjectDoesNotExist: self.fail('does_not_exist', pk_value=data)
def validate_username(self, username): """ Validates the username by seeing if any User object matches it :param username: the username whose existence is being checked :return: the username after validation :raise serializers.ValidationError: if no user has the given username """ try: user = get_user(username=username) self.user = user except User.DoesNotExist: raise serializers.ValidationError('Username does not exist.') return username
def validate_username(self, username): """ Validate the supplied username by checking if a user with the supplied username even exists :param username: the supplied username :return: the username if it is valid :raise serializers.ValidationError: if the username does not exist """ try: self.user = get_user(username=username) except User.DoesNotExist: raise serializers.ValidationError('Invalid username') return username
def get(self, request): """ View to serve GET requests :param request: the request that is to be responded to :return: the response for request """ app_name = request.user.app_name username = request.GET.get('username') institute_security_key = request.GET.get('isk') logger.info( f'{app_name}: requested to verify isk for username: {username}') response_data = { 'valid': False, } response_status = status.HTTP_401_UNAUTHORIZED if username and institute_security_key: try: user = get_user(username=username) if user.institute_security_key == institute_security_key: response_data['valid'] = True response_status = status.HTTP_200_OK logger.info( f'{app_name}: successfully verified the security key for username: {username}' ) else: response_data['error'] = 'Invalid institute security key' response_status = status.HTTP_401_UNAUTHORIZED logger.info( f'{app_name}: Invalid security key for username: {username}' ) except Exception: response_data['error'] = 'Invalid username' response_status = status.HTTP_404_NOT_FOUND logger.info(f'{app_name}: Invalid username: {username}') else: response_data[ 'error'] = 'username and institute_security_key not provided' response_status = status.HTTP_400_BAD_REQUEST return response.Response(data=response_data, status=response_status)
def __call__(self, request): """ Perform actual processing on the request before it goes to the view and on response returned by the view :param request: the request being processed :return: the processed response """ source_user = request.user try: guest_user = get_user(settings.GUEST_USERNAME) except User.DoesNotExist: guest_user = None if source_user != guest_user: response = self.get_response(request) return response if request.method != 'GET': raise Http404 DISCOVERY = settings.DISCOVERY all_apps = DISCOVERY.apps for app, app_configuration in all_apps: base_url = app_configuration.base_urls.http.strip('/') if (app_configuration.guest_allowed or from_acceptable_person( request.roles, app_configuration.acceptables.roles)): excluded_paths = app_configuration.excluded_paths for excluded_path in excluded_paths: if re.match(f'^/{base_url}/{excluded_path}/', request.path): raise Http404 else: if re.match(f'^/{base_url}/', request.path): raise Http404 response = self.get_response(request) return response
def get(self, request, *args, **kwargs): """ View to serve POST requests :param request: the request that is to be responded to :param args: arguments :param kwargs: keyword arguments :return: the response for request """ try: guest_user = get_user(settings.GUEST_USERNAME) except User.DoesNotExist: guest_user = create_guest() login( request=request, user=guest_user, backend='base_auth.backends.generalised.GeneralisedAuthBackend' ) SessionMap.create_session_map( request=request, user=guest_user, new=False ) try: user_data = AvatarSerializer(guest_user.person).data except Person.DoesNotExist: user_data = None response_data = { 'status': 'Successfully logged in.', 'user': user_data, } return response.Response( data=response_data, status=status.HTTP_200_OK )