def method_check(self, request, allowed=None): """ Check for an OPTIONS request. If so return the Allow- headers """ if allowed is None: allowed = [] request_method = request.method.lower() allows = ','.join(map(lambda s: s.upper(), allowed)) if request_method == 'options': response = HttpResponse(allows) response['Access-Control-Allow-Origin'] = '*' response[ 'Access-Control-Allow-Headers'] = 'Content-Type, Authorization' response['Access-Control-Allow-Methods'] = "GET, PUT, POST, PATCH" response['Allow'] = allows raise ImmediateHttpResponse(response=response) if not request_method in allowed: response = http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) return request_method
def delete_aip_request(self, request, bundle, **kwargs): request_info = bundle.data package = bundle.obj if package.package_type not in Package.PACKAGE_TYPE_CAN_DELETE: # Can only request deletion on AIPs response = {"message": "Deletes not allowed on this package type."} response_json = json.dumps(response) return http.HttpMethodNotAllowed(response_json, content_type='application/json') (status_code, response) = self._attempt_package_request_event( package, request_info, Event.DELETE, Package.DEL_REQ) if status_code == 202: # This isn't configured by default site_url = getattr(settings, "SITE_BASE_URL", None) signals.deletion_request.send(sender=self, url=site_url, uuid=package.uuid, location=package.full_path) else: response = { 'message': 'A deletion request already exists for this AIP.' } self.log_throttled_access(request) response_json = json.dumps(response) return http.HttpResponse(status=status_code, content=response_json, mimetype='application/json')
def patch_list(self, request=None, **kwargs): """ Exactly copied from https://github.com/toastdriven/django-tastypie/blob/v0.9.14/tastypie/resources.py#L1466 (BSD licensed) and modified to pass the kwargs to `obj_create` and support only create method """ request = convert_post_to_patch(request) deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json')) collection_name = self._meta.collection_name if collection_name not in deserialized: raise BadRequest("Invalid data sent: missing '%s'" % collection_name) if len(deserialized[collection_name]) and 'put' not in self._meta.detail_allowed_methods: raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed()) bundles_seen = [] status = http.HttpAccepted for data in deserialized[collection_name]: data = self.alter_deserialized_detail_data(request, data) bundle = self.build_bundle(data=dict_strip_unicode_keys(data), request=request) try: self.obj_create(bundle=bundle, **self.remove_api_resource_names(kwargs)) except AssertionError as ex: status = http.HttpBadRequest bundle.data['_id'] = ex.message bundles_seen.append(bundle) to_be_serialized = [bundle.data['_id'] for bundle in bundles_seen] return self.create_response(request, to_be_serialized, response_class=status)
def patch_list(self, request, **kwargs): """ Specialization of patch_list to do bulk target creation in a single RPC to job_scheduler (and consequently in a single command). """ deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json')) if "objects" not in deserialized: raise BadRequest("Invalid data sent.") if len(deserialized["objects"]) and 'put' not in self._meta.detail_allowed_methods: raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed()) # If any of the included targets is not a creation, then # skip to a normal PATCH instead of this special case one for target_data in deserialized['objects']: if 'id' in target_data or 'resource_uri' in target_data: super(TargetResource, self).patch_list(request, **kwargs) # Validate and prepare each target dict for consumption by job_scheduler for target_data in deserialized['objects']: data = self.alter_deserialized_detail_data(request, target_data) bundle = self.build_bundle(data=dict_strip_unicode_keys(data)) bundle.request = request self.is_valid(bundle) target_data['content_type'] = ContentType.objects.get_for_model(KIND_TO_KLASS[target_data['kind']]).natural_key() targets, command = JobSchedulerClient.create_targets(deserialized['objects']) raise custom_response(self, request, http.HttpAccepted, {'command': dehydrate_command(command), 'targets': [self.get_resource_uri(target) for target in targets]})
def get_list(self, request, **kwargs): ## override the list retrieval part to verify additionally that an ``user`` filter exists ## otherwise reject the call with a HttpMethodNotAllowed if 'user' in request.GET: return super(AnnotationResource, self).get_list(request, **kwargs) else: raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())
def get_list(self, request, **kwargs): ## override the list retrieval part to verify additionally that an ``environment`` or ``area`` filter exists ## otherwise reject the call with a HttpMethodNotAllowed if 'environment' in request.GET or 'area' in request.GET: return super(UserResource, self).get_list(request, **kwargs) else: raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())
def get_list(self, request, **kwargs): """ override the list retrieval part to verify additionally that an ``area`` or ``environment`` and a ``category`` filter exist otherwise reject the call with a HttpMethodNotAllowed """ if ('area' in request.GET or 'environment' in request.GET) and 'category' in request.GET: return super(FeatureResource, self).get_list(request, **kwargs) else: raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())
def disable(self, request, **kwargs): ''' Disable the currently authenticated user ''' if request.user.is_anonymous(): raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed()) request.user.is_active = False request.user.save() auth_logout(request) return self.create_response(request, dict(status="success"))
def api_auth(request): """ authentication gate for the REST clients. Wraps the normal login method into JSON shell """ if not request.method == "POST": return http.HttpMethodNotAllowed() form = AuthenticationForm(data=request.POST) if form.is_valid(): login(request, form.get_user()) return http.HttpAccepted() else: return http.HttpUnauthorized("Invalid credentials")
def get_extra_data(self, request, **kwargs): if request.method != "GET": raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed()) election = None electionid = kwargs.get('electionid', -1) try: election = Election.objects.get(id=electionid) except: raise ImmediateHttpResponse(response=http.HttpNotFound()) return self.create_response(request, election.extra_data)
def method_check(self, request, allowed=None): if allowed is None: allowed = [] request_method = request.method.lower() allows = ','.join(map(lambda x: x.upper(), allowed)) if request_method == "options": response = HttpResponse(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) if not request_method in allowed: response = http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) return request_method
def method_check(self, request, allowed=None): if allowed is None: allowed = [] request_method = request.method.lower() allows = ', '.join([x.upper() for x in allowed if x]) if request_method == 'options': response = HttpResponse(allows) add_cors_headers_to_response(response, allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) if request_method not in allowed: response = http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) return request_method
def action(self, request, **kwargs): ''' Requests an action on this election actions: DONE * get_permissions * approve * start * stop * archive * vote * cancel_vote ''' actions = { 'get_permissions': self.get_permissions_action, 'approve': self.approve_action, 'start': self.start_action, 'stop': self.stop_action, 'archive': self.archive_action, 'vote': self.vote_action, 'cancel_vote': self.cancel_vote_action, } if request.method != "POST": raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed()) data = self.deserialize_post_data(request) election = None electionid = kwargs.get('electionid', -1) try: election = Election.objects.get(id=electionid) except: raise ImmediateHttpResponse(response=http.HttpNotFound()) action = data.get("action", False) if not action or not action in actions: raise ImmediateHttpResponse(response=http.HttpNotFound()) kwargs.update(data) return actions[action](request, election, **kwargs)
def method_check(self, request, allowed=None): if allowed is None: allowed = [] request_method = request.method.lower() allows = ','.join([meth.upper() for meth in allowed]) if request_method == "options": response = http.HttpResponse(allows) response['Allow'] = allows self.add_cors_headers(response) raise exceptions.ImmediateHttpResponse(response=response) if request_method not in allowed: response = tastypie_http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise exceptions.ImmediateHttpResponse(response=response) return request_method
def recover_aip_request(self, request, bundle, **kwargs): request_info = bundle.data package = bundle.obj if package.package_type not in Package.PACKAGE_TYPE_CAN_RECOVER: # Can only request recovery of AIPs response = { "message": "Recovery not allowed on this package type." } response_json = json.dumps(response) return http.HttpMethodNotAllowed(response_json, content_type='application/json') (status_code, response) = self._attempt_package_request_event( package, request_info, Event.RECOVER, Package.RECOVER_REQ) self.log_throttled_access(request) response_json = json.dumps(response) return http.HttpResponse(status=status_code, content=response_json, mimetype='application/json')
def method_check(self, request, allowed=None): if allowed is None: allowed = [] request_method = request.method.lower() allows = ','.join([x.upper() for x in allowed if x]) if request_method == 'options': response = HttpResponse(allows) response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' response['Allow'] = allows raise ImmediateHttpResponse(response=response) if request_method not in allowed: response = http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) return request_method
def method_check(self, request, allowed=None): if allowed is None: allowed = [] request_method = request.method.lower() allows = ','.join(map(lambda s: s.upper(), allowed)) if request_method == 'options': response = HttpResponse(allows) response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Headers'] = 'Content-Type' response['Allow'] = allows raise ImmediateHttpResponse(response=response) if not request_method in allowed: response = http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) return request_method
def dispatch(self, request_type, request, **kw): method = request.META['REQUEST_METHOD'] delay = request.META.get('HTTP_SOLITUDE_ASYNC', False) if delay: # Move the import here to remove warnings in management commands. from lib.delayable.tasks import delayable # Only do async on these requests. if method not in ['PATCH', 'POST', 'PUT']: raise ImmediateHttpResponse( response=http.HttpMethodNotAllowed()) # Create a delayed dispatch. uid = str(uuid.uuid4()) # We only need a subset of meta. whitelist = ['PATH_INFO', 'REQUEST_METHOD', 'QUERY_STRING'] meta = dict([k, request.META[k]] for k in whitelist) # Celery could magically serialise some of this, but I don't # trust it that much. delayable.delay(self.__class__.__module__, self.__class__.__name__, request_type, meta, request.body, kw, uid) content = json.dumps({ 'replay': '/delay/replay/%s/' % uid, 'result': '/delay/result/%s/' % uid }) return http.HttpResponse(content, status=202, content_type='application/json') # Log the call with CEF and logging. if settings.DUMP_REQUESTS: print colorize('brace', method), request.get_full_path() else: log.info('%s %s' % (colorize('brace', method), request.get_full_path())) msg = '%s:%s' % (kw.get('api_name', 'unknown'), kw.get('resource_name', 'unknown')) log_cef(msg, request, severity=2) return super(TastypieBaseResource, self).dispatch(request_type, request, **kw)
def method_check(self, request, allowed=None): if allowed is None: allowed = [] request_method = request.method.lower() for i,method in enumerate(allowed): allowed[i] = method.encode('ascii','ignore') allows = ','.join(map(str.upper, allowed)) if request_method == 'options': response = HttpResponse(allows) response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Headers'] = 'Content-Type' response['Allow'] = allows raise ImmediateHttpResponse(response=response) if not request_method in allowed: response = http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) return request_method
def method_check(self, request, allowed=None): """ For this base resource, check that the HTTP request method is permitted. """ if allowed is None: allowed = [] # Get the method (GET/POST/PUT, etc) from the django request object request_method = request.method.lower() allows = ','.join([str(i).upper() for i in allowed]) if request_method == 'options': response = HttpResponse(allows) response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Headers'] = 'Content-Type' response['Allow'] = allows raise ImmediateHttpResponse(response=response) if not request_method in allowed: response = http.HttpMethodNotAllowed(allows) response['Allow'] = allows raise ImmediateHttpResponse(response=response) return request_method
def get_object_list(self, request): ## override the usual obj_list retrieval by filtering out only the yet to be given announcements ## for the current environment (which we **know** must exist) timestamp = datetime.now() ## get default object list announcement_obj_list = super(AnnouncementResource, self).get_object_list(request) if 'environment' in request.GET: try: env_id = request.GET['environment'] environ = Environment.objects.get(id=env_id) announcement_obj_list = announcement_obj_list.filter( environment=environ) except Exception: pass if 'area' in request.GET: try: area_id = request.GET['area'] area = Area.objects.get(id=area_id) announcement_obj_list = announcement_obj_list.filter(area=area) except Exception: pass try: id_list = [] ## loop through each announcement and see if any of its ## triggers are greater than the current timestamp for obj in announcement_obj_list: triggers = obj.triggers.getList() ## maybe make the following a little less hardcoded if obj.repeatEvery == "day": for trig in triggers: trig.replace(year=timestamp.year, month=timestamp.month, day=timestamp.day) elif obj.repeatEvery == "week": ## see which triggers are within "weeks" of the timestamp for trig in triggers: diff = timestamp.date() - trig.date() if diff.days % 7 != 0: triggers.remove(trig) ## and then update the day only for those for trig in triggers: trig.replace(year=timestamp.year, month=timestamp.month, day=timestamp.day) ## and now we can do easy comparisons should_be_included = False for dt in obj.triggers.getList(): if dt >= timestamp: should_be_included = True break if should_be_included: id_list.append(obj.id) return announcement_obj_list.filter(id__in=id_list) except Exception: raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed())
def process_file(self, request, **kwargs): """ :param request: incoming http request :param pk: ID of the object that has file fields :param attr_name: name of the attribute where the file is stored :return: Http Response """ attr_name = kwargs.pop('attr_name') if not request.method in ['GET', 'POST']: return http.HttpMethodNotAllowed("Use GET or POST to manage files") try: bundle = self.build_bundle(data={'pk': kwargs['pk']}, request=request) obj = self.cached_obj_get(bundle=bundle, **self.remove_api_resource_names(kwargs)) except ObjectDoesNotExist: return http.HttpGone() except MultipleObjectsReturned: return http.HttpMultipleChoices("More than one object found " "at this URL.") try: field = self._meta.object_class._meta.get_field_by_name( attr_name)[0] except FieldDoesNotExist: return http.HttpBadRequest("Attribute %s does not exist" % attr_name) if not isinstance(field, models.FileField): return http.HttpBadRequest("Attribute %s is not a data-field" % attr_name) if request.method == 'GET': ffile = getattr(obj, attr_name) try: filepath = ffile.path except ValueError: # file is not set, empty return http.HttpNoContent() with open(filepath, 'r') as f: response = HttpResponse(f.read(), content_type='application/x-hdf') response['Content-Disposition'] = "attachment; filename=%s" % \ os.path.basename(filepath) response['Content-Length'] = os.path.getsize(f.name) return response if not obj.is_editable(request.user): return http.HttpUnauthorized("No access to the update this object") if not len(request.FILES) > 0: return http.HttpNoContent() # take first file in the multipart/form request setattr(obj, attr_name, request.FILES.values()[0]) obj.save() return http.HttpAccepted("File content updated successfully")
def user_invite(self, request, **kwargs): if request.method != 'POST': raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed()) try: data = self.deserialize_post_data(request) emails = map(str.strip, data['emails']) agoraid = data['agoraid'] except: raise ImmediateHttpResponse(response=http.HttpBadRequest()) agora = get_object_or_404(Agora, pk=agoraid) welcome_message = data.get('welcome_message', _("Welcome to this agora")) if not agora.has_perms('admin', request.user): raise ImmediateHttpResponse(response=http.HttpMethodNotAllowed()) for email in emails: q = User.objects.filter(Q(email=email) | Q(username=email)) exists = q.exists() if not exists and not validate_email(email): # invalid email address, cannot send an email there! raise ImmediateHttpResponse(response=http.HttpBadRequest()) for email in emails: q = User.objects.filter(Q(email=email) | Q(username=email)) exists = q.exists() if exists: # if user exists in agora, we'll add it directly user = q[0] if user in agora.members.all(): continue # if user exists in agora, we'll add it directly status, resp = rest('/agora/%s/action/' % agoraid, data={ 'action': 'add_membership', 'username': user.username, 'welcome_message': welcome_message }, method="POST", request=request) if status != 200: raise ImmediateHttpResponse(response=http.HttpBadRequest()) else: # send invitation # maximum 30 characters in username username = str(uuid4())[:30] password = str(uuid4()) user = UserenaSignup.objects.create_user( username, email, password, False, False) profile = user.get_profile() profile.lang_code = request.user.get_profile().lang_code profile.extra = {'join_agora_id': agoraid} profile.save() # Mail to the user translation.activate(user.get_profile().lang_code) context = get_base_email_context(request) context.update( dict(agora=agora, other_user=request.user, to=user, invitation_link=reverse( 'register-complete-invite', kwargs=dict(activation_key=user.userena_signup. activation_key)), welcome_message=welcome_message)) email = EmailMultiAlternatives( subject=_('%(site)s - invitation to join %(agora)s') % dict(site=Site.objects.get_current().domain, agora=agora.get_full_name()), body=render_to_string( 'agora_core/emails/join_invitation.txt', context), to=[user.email]) email.attach_alternative( render_to_string('agora_core/emails/join_invitation.html', context), "text/html") email.send() translation.deactivate() # add user to the default agoras if any for agora_name in settings.AGORA_REGISTER_AUTO_JOIN: profile.add_to_agora(agora_name=agora_name, request=request) return self.create_response(request, {})