def view_history(self, request, pk=None, **kwargs): if not pk: raise BinderNotFound() # We must have permission to view the object. If not we can not view the history data = self._get_objs(self.get_queryset(request), request=request) if not data: raise BinderNotFound() return super().view_history(request, pk, **kwargs)
def activate(self, request, pk=None): """ Adds an endpoint to activate an user. Also logs in the user Request: PUT user/{id}/activate/ { "activation_code": string } Response: Same as GET user/{id}/ """ if request.method != 'PUT': raise BinderMethodNotAllowed() self._require_model_perm('activate', request) decoded = request.body.decode() try: body = json.loads(decoded) except ValueError: raise BinderRequestError( _('Invalid request body: not a JSON document.')) errors = {} for item in ['activation_code']: if body.get(item) is None: errors[item] = ['missing'] if len(errors) != 0: raise BinderValidationError(errors) try: user = self.model._default_manager.get(pk=pk) except (TypeError, ValueError, OverflowError, self.model.DoesNotExist): user = None if user is None or not self.token_generator.check_token( user, body.get('activation_code')): raise BinderNotFound() logger.info('login for {}/{} via successful activation'.format( user.id, user)) user.is_active = True user.save() self.auth_login(request, user) return self.respond_with_user(request, user.id)
def masquerade(self, request, pk=None): from hijack.helpers import login_user if request.method != 'POST': raise BinderMethodNotAllowed() try: user = self.model._default_manager.get(pk=pk) except self.model.DoesNotExist: raise BinderNotFound() self._require_model_perm('masquerade', request) login_user(request, user) # Ignore returned redirect response object return self.respond_with_user(request, user.id)
def dispatch_file_field(self, request, pk=None, file_field=None): if isinstance(pk, self.model): obj = pk else: try: obj = self.get_queryset(request).get(pk=int(pk)) except ObjectDoesNotExist: raise BinderNotFound() if request.method in {'POST', 'DELETE'}: # Here we pretend that a DELETE scope is done. We only need a change # scope, but the dispatch checks if have a DELETE scope done. request._scopes.append(Scope.DELETE) self.scope_change(request, obj, {file_field:...}) return super().dispatch_file_field(request, obj, file_field)
def dispatch_file_field(self, request, pk=None, file_field=None): if isinstance(pk, self.model): obj = pk else: try: obj = self.get_queryset(request).get(pk=int(pk)) except self.model.DoesNotExist: raise BinderNotFound() res = super().dispatch_file_field(request, obj, file_field) if request.method == 'POST': data = jsonloads(res.content) field = next(iter(data['data'])) data['data'][field] += self._get_params(obj, field) return JsonResponse(data) return res
def _reset_pass_for_user(self, request, user_id, token, password): """ Helper function that actually resets the password for an user """ try: user = self.model._default_manager.get(pk=user_id) except (TypeError, ValueError, OverflowError, self.model.DoesNotExist): user = None if user is None or not self.token_generator.check_token(user, token): raise BinderNotFound() logger.info('login for {}/{} via successful password reset'.format( user.id, user)) try: password_validation.validate_password(password, user) except ValidationError as ve: raise BinderValidationError({'password': ve.messages}) user.set_password(password) user.save() self.auth_login(request, user) return self.respond_with_user(request, user.id)
def send_activation_email(self, request): """ Endpoint that can be used to send an activation mail for an user. Calls the _send_activation_email callback if the user is succesfully activated Request: POST { "email": "email" } Response: { "code": code } Possible codes: sent Mail is send sucessfully already active User is already active, no mail was send blacklisted User was not activated """ if request.method != 'PUT': raise BinderMethodNotAllowed() # For lack of a better check self._require_model_perm('reset_password', request) decoded = request.body.decode() try: body = json.loads(decoded) except ValueError: raise BinderRequestError( _('Invalid request body: not a JSON document.')) logger.info('activation email attempt for {}'.format( body.get('email', ''))) if body.get('email') is None: raise BinderValidationError({'email': ['missing']}) try: user = self.model._default_manager.get(email=body.get('email')) except self.model.DoesNotExist: raise BinderNotFound() if user.is_active: if user.last_login is None: # TODO: Figure out a way to make this customisable without # allowing injection of arbitrary URLs (phishing!) self._send_activation_email(request, user) response = JsonResponse({'code': 'sent'}) response.status_code = 201 else: response = JsonResponse({'code': 'already active'}) else: response = JsonResponse({'code': 'blacklisted'}) response.status_code = 400 return response