def is_valid(self, bundle, request=None): """Overridden to perform validation and persistence in one step""" files = {} # FIXME avatar file translation and persistence avatar_data = bundle.data.get('avatar') if avatar_data: try: files['avatar'] = SimpleUploadedFile( avatar_data['name'], base64.b64decode(avatar_data['file']), avatar_data.get("content_type", "application/octet-stream") ) except Exception: raise ImmediateHttpResponse(HttpBadRequest(content='ERROR PROCESSING IMAGE')) # instantiate and validate the form form = self._meta.validation.form_class(data=bundle.data, files=files) if form.is_valid(): user = form.save() # update request with the new user request.user = user request.user_created = True # error handling else: if request: desired_format = self.determine_format(request) else: desired_format = self._meta.default_format serialized = self.serialize(request, form.errors, desired_format) response = HttpBadRequest(content=serialized, content_type=build_content_type(desired_format)) raise ImmediateHttpResponse(response=response)
def update_managed_by(self, request, **kwargs): self.method_check(request, allowed=['post']) try: obj = models.Computer.objects.get(pk=kwargs['pk']) except models.Computer.DoesNotExist: return HttpBadRequest('Unknown computer object') new_managed_by_id = request.REQUEST.get('managed_by_id', None) if not new_managed_by_id: return HttpBadRequest('No managed_by Manager supplied') # If the device is linked to an AD object, ensure that the changes are # first pushed to AD before saving in Incredibus. if obj.ad_guid: # Object is linked to AD. obj.managed_by_id = new_managed_by_id res = obj.push_managed_by( ) # Push the updated managed_by to AD first. if res: obj.save() return self.create_response(request, data=obj) else: return HttpResponseServerError( 'Unable to update managed_by in AD') else: # No link to AD. obj.managed_by_id = new_managed_by_id obj.save() return self.create_response(request, data=obj)
def obj_create(self, bundle, request=None, **kwargs): try: assignment_id = bundle.data['course'].split( '/')[4] + '_' + bundle.data['assignment_name'] course = (Course.objects.all().get( course_id=bundle.data['course'].split('/')[4])) except (ObjectDoesNotExist, KeyError): raise ImmediateHttpResponse( HttpBadRequest("This course does not exist.")) students = course.students.all() try: Assignment.objects.create( assignment_id=assignment_id, assignment_name=bundle.data['assignment_name'], assignment_type=bundle.data['assignment_type'], course=course, due_date=bundle.data['due_date'], expected_difficulty=bundle.data['expected_difficulty'], expected_time=bundle.data['expected_time'], description=bundle.data['description']) except (KeyError, IntegrityError): raise ImmediateHttpResponse( HttpBadRequest( "Duplicate assignment or you're forgetting something")) for stud in students: StudentAssignment.objects.create( student_assignment_id=assignment_id + '_' + stud.user_name, student=stud, assignment=Assignment.objects.all().get( assignment_id=assignment_id)) bundle = self.full_hydrate(bundle) return bundle
def respond_to_request(self, request, **kwargs): """Allows a user to respond to a request for their location""" self._verify(request) data = self.deserialize(request, request.body, format=request.META.get( 'Content-Type', 'application/json')) allow_request = data.get('allow_request', None) requestor_id = data.get('requestor_id', None) access_points = data.get('access_points', None) if allow_request is None or requestor_id is None: msg = 'Need both allow_request and requestor_id' raise ImmediateHttpResponse(HttpBadRequest(msg)) if allow_request and access_points is None or len(access_points) < 1: msg = 'If allow_request, then access_points must be provided' raise ImmediateHttpResponse(HttpBadRequest(msg)) # Make sure the requestor actually exists try: requestor = User.objects.get(pk=requestor_id) requestor_device_set = requestor.userdevice_set.all() except User.DoesNotExist: msg = 'Could not find User with id {}'.format(requestor_id) raise ImmediateHttpResponse(HttpNotFound(msg)) # And also make sure the requestor has a phone if not requestor_device_set.exists(): msg = 'Could not find User with id {}'.format(requestor_id) raise ImmediateHttpResponse(HttpNotFound(msg)) if allow_request: location = self._locate_user(access_points) self._save_user_location(request.user, location) msg = { 'type': 'request_granted', 'friend': request.user.get_full_name(), 'building_name': location.building_name, 'floor_number': location.floor_number, 'x_coordinate': location.x_coordinate, 'y_coordinate': location.y_coordinate, 'friend_id': request.user.pk, 'image_url': location.image_url, } else: msg = { 'type': 'request_denied', 'friend': request.user.get_full_name(), 'friend_id': request.user.pk } response_class = self._notify_user(requestor_device_set, msg) return self.create_response(request, data={}, response_class=response_class)
def extract_credentials(self, request): public_key = request.GET.get('public_key') or request.POST.get('public_key') if public_key is None: raise ImmediateHttpResponse(response=HttpBadRequest('public_key not found')) api_key = request.GET.get('api_key') or request.POST.get('api_key') if api_key is None: raise ImmediateHttpResponse(response=HttpBadRequest('api_key not found')) timestamp = request.GET.get('timestamp') or request.POST.get('timestamp') if timestamp is None: raise ImmediateHttpResponse(response=HttpBadRequest('timestamp not found')) return public_key, api_key, timestamp
def user_preference(self, request, **kwargs): ''' Register user with valid device id Args : device id ''' load = json.loads(request.body) print "==========Load Data=====", load interests = load.get('interests') languages = load.get('languages') device_id = load.get('device_id') try: user_obj = UserProfile.objects.get(device_id=device_id) except: return HttpBadRequest("Enter valid device id") try: cat_list = [] lang_list = [] #For appending keys in a list for i in interests: for j, k in i.items(): cat_list.append(k) for i in languages: for j, k in i.items(): lang_list.append(k) #For saving list of key item in models #Saving in Categories for i in cat_list: try: cat_obj = Category.objects.get(name=i) user_obj.interests_category.add(cat_obj) except: pass #Saving in Languages for i in lang_list: try: lang_obj = Language.objects.get(name=i) user_obj.user_languages.clear() user_obj.user_languages.add(lang_obj) except: pass data = {'status': 1, 'message': 'Updated successfully'} return HttpResponse(json.dumps(data), content_type="application/json") except Exception as ex: logger.info( "Exception while updating user details with device id - {0}". format(ex)) return HttpBadRequest("Update failed")
def obj_create(self, bundle, **kwargs): try: evenement = bundle.data['evenement'] sender = bundle.data['sender'] receiver = bundle.data['receiver'] body = bundle.data['body'] except KeyError: raise ImmediateHttpResponse(response=HttpBadRequest()) evenement = get_object_or_404(Evenement, slug=evenement) sender = Indicatif.objects.get_or_create(nom=sender, evenement=evenement)[0] receiver = Indicatif.objects.get_or_create(nom=receiver, evenement=evenement)[0] thread = MessageThread(evenement=evenement) thread.save() user = bundle.request.user version = MessageVersion(thread=thread, expediteur=sender, destinataire=receiver, operateur=user, corps=body) version.save() bundle.obj = Message(thread) return bundle
def obj_update(self, bundle, **kwargs): # FIXME: I'm not exactly sure how cached cached_object_get is -- should # we be explicitly getting a fresh one? I'm just following what the ModelResource # obj_update does - jcs bundle.obj = self.cached_obj_get(bundle, **self.remove_api_resource_names(kwargs)) volume = bundle.data # Check that we're not trying to modify a Volume that is in # used by a target try: Volume.get_unused_luns(Volume.objects).get(id = volume['id']) except Volume.DoesNotExist: raise AssertionError("Volume %s is in use!" % volume['id']) lun = get_object_or_404(Volume, id = volume['id']) node_ids = [node['id'] for node in volume['nodes']] host_ids = set(lun.volumenode_set.filter(id__in=node_ids).values_list('host_id', flat=True)) # Sanity-check the primary/failover relationships and save if OK if not any(host_ids.issubset(host.id for host in cluster.peers) for cluster in HaCluster.all_clusters()): error_msg = "Attempt to set primary/secondary VolumeNodes across HA clusters for Volume %s:%s\n" % (lun.id, lun.label) error_msg += "\nVolume Node Hosts %s\n" % ", ".join([str(host) for host in ManagedHost.objects.filter(id__in = host_ids)]) error_msg += "\nKnown HA Clusters %s\n" % ", ".join(["(%s)" % ", ".join([str(host) for host in cluster.peers]) for cluster in HaCluster.all_clusters()]) raise ImmediateHttpResponse(response = HttpBadRequest(error_msg)) # Apply use,primary values from the request for node in volume['nodes']: lun.volumenode_set.filter(id=node['id']).update(primary=node['primary'], use=node['use']) # Clear use, primary on any nodes not in this request lun.volumenode_set.exclude(id__in=node_ids).update(primary=False, use=False) return bundle
def purchase(self, request, **kwargs): self.method_check(request, allowed=['post']) data = self.deserialize(request, request.body, format=request.META.get( 'CONTENT_TYPE', 'application/json')) amount = data.get('amount', '') if not amount: return HttpBadRequest() try: bundle = self.build_bundle(data={'pk': kwargs['pk']}, request=request) account = self.cached_obj_get( bundle=bundle, **self.remove_api_resource_names(kwargs)) card_payment = PendingPayment.objects.currency_purchase( account, amount) return self.create_response(request, { 'reference': card_payment.reference, 'url': settings.BASESITE_URL + reverse('payments:payment_form', kwargs={'uuid': card_payment.reference}) }, response_class=HttpCreated) except ObjectDoesNotExist: return HttpGone() except MultipleObjectsReturned: return HttpMultipleChoices( "More than one resource is found at this URI.")
def test_various_statuses(self): created = HttpCreated(location='http://example.com/thingy/1/') self.assertEqual(created.status_code, 201) self.assertEqual(created['Location'], 'http://example.com/thingy/1/') # Regression. created_2 = HttpCreated() self.assertEqual(created_2.status_code, 201) self.assertEqual(created_2['Location'], '') accepted = HttpAccepted() self.assertEqual(accepted.status_code, 202) no_content = HttpNoContent() self.assertEqual(no_content.status_code, 204) see_other = HttpSeeOther() self.assertEqual(see_other.status_code, 303) not_modified = HttpNotModified() self.assertEqual(not_modified.status_code, 304) bad_request = HttpBadRequest() self.assertEqual(bad_request.status_code, 400) unauthorized = HttpUnauthorized() self.assertEqual(unauthorized.status_code, 401) not_found = HttpNotFound() self.assertEqual(not_found.status_code, 404) not_allowed = HttpMethodNotAllowed() self.assertEqual(not_allowed.status_code, 405) conflict = HttpConflict() self.assertEqual(conflict.status_code, 409) gone = HttpGone() self.assertEqual(gone.status_code, 410) toomanyrequests = HttpTooManyRequests() self.assertEqual(toomanyrequests.status_code, 429) not_implemented = HttpNotImplemented() self.assertEqual(not_implemented.status_code, 501)
def _populate_obj_by_data(self): """Database lookup get everything except the result, 2nd try reverse lookup """ def populate(key): return { 'project': lambda: Project.objects.get_or_create(name=self.data['project'] ), 'executable': lambda: Executable.objects.get_or_create( name=self.data['executable'], project=self.obj.project), 'benchmark': lambda: Benchmark.objects.get_or_create(name=self.data[ 'benchmark']), 'environment': lambda: (Environment.objects.get(name=self.data['environment'] ), False), 'branch': lambda: Branch.objects.get_or_create(name=self.data['branch'], project=self.obj.project), }.get(key, (None, None))() try: self.obj.value = float(self.data['result_value']) except ValueError, error: logging.error( "Result value: {0} cannot be converted to float. {1}".format( self.data['result_value'], error)) raise ImmediateHttpResponse( response=HttpBadRequest(u"Value needs to be a number"))
def get_object_list(self, request): # inner get of object list... this is where you'll need to # fetch the data from what ever data source try: _data = self._meta.rinor_pipe.get_list() except RinorError, e: raise ImmediateHttpResponse(response=HttpBadRequest(e.reason))
def update_asset_number(self, request, **kwargs): self.method_check(request, allowed=['post']) try: obj = models.Computer.objects.get(pk=kwargs['pk']) except models.Computer.DoesNotExist: return HttpBadRequest('Unknown computer object') new_asset_no = request.REQUEST.get('asset_id', None) if not new_asset_no: new_asset_no = '' # If the device is linked to an AD object, ensure that the changes are # first pushed to AD before saving in Incredibus. if obj.ad_guid: # Object is linked to AD. obj.asset_id = new_asset_no res = obj.ad_set_asset_number( ) # Push the updated asset number to AD first. if res: obj.save() return self.create_response(request, data=obj) else: return HttpResponseServerError( 'Unable to update asset number in AD') else: # No link to AD. obj.asset_id = new_asset_no obj.save() return self.create_response(request, data=obj)
def save(self, bundle, skip_errors=False): """ Creates a new pending order reserving the necessary stock and scheduling a task to release the stock in case the order is not paid within the ORDER_TIMEOUT """ if not self.is_valid(bundle): raise ImmediateHttpResponse(HttpBadRequest()) # It's already validated bundle.obj.save() for product_row in bundle.data.get('products'): product = Product.objects.get(id=product_row.get('product')) quantity = int(product_row.get('quantity')) OrderProduct( order=bundle.obj, product=product, quantity=quantity, ).save() # Reserve the stock to avoid other orders buying our stock while # we are paying product.reserve_stock(quantity) # Schedule the task to check the order after ORDER_TIMEOUT check_order.apply_async( args=[ bundle.obj.id, ], countdown=settings.ORDER_TIMEOUT, ) return bundle
def obj_update(self, bundle, pk='', **kwargs): pk = int(pk) number = PhoneNumber.objects.filter(id=pk) if number[0].patron == bundle.request.user: number.update(**bundle.data) else: raise ImmediateHttpResponse(response=HttpBadRequest())
def is_api_key_valid(self, api_key, request): protocol = 'http://' if 'https' in request.scheme or \ 'HTTP_X_FORWARDED_PROTO' in request.META and 'https' in request.META['HTTP_X_FORWARDED_PROTO']: protocol = 'https://' host = request.META['HTTP_HOST'] if 'HTTP_HOST' in request.META else 'localhost' # ResourceTestCase api_client does not set HTTP_HOST path = request.META['PATH_INFO'] params = request.GET.copy() params = sorted(params.items(), key=operator.itemgetter(0)) query_string = '?' for t in params: if t[0] != 'api_key': query_string = query_string + t[0] + '=' + t[1] + '&' url = protocol + host + path + query_string url = url[:len(url) - 1] if request.method == 'POST' or request.method == 'PUT' or request.method == 'PATCH': url += request.body.decode('utf-8') digest = hmac.new(settings.SECRET_KEY, url.encode('utf-8'), hashlib.sha256).hexdigest() if digest != api_key: raise ImmediateHttpResponse(response=HttpBadRequest('api_key is not valid')) return True
def obj_create(self, bundle, **kwargs): """Creates a new inactive user""" data = bundle.data try: bundle.obj = Patron.objects.create_user(data["username"], data["email"], data["password"]) except IntegrityError: raise ImmediateHttpResponse(response=HttpBadRequest()) except ValidationError: raise ImmediateHttpResponse(response=HttpBadRequest()) except Exception: raise ImmediateHttpResponse(response=HttpBadRequest()) return bundle
def update_product_prices(request): from dateutil import parser try: if request.method == 'POST': if not is_authenticated(request): return HttpUnauthorized() data = json.loads(request.body) ids = [s.split("/")[-2] for s in data["products"]] products = Product.objects.filter(id__in=ids) prices_dicts = [{ "unit": UNIT.enum_dict[p["unit"]], "amount": p["amount"], "currency": p["currency"], "started_at": parser.parse(p["started_at"]).date(), "ended_at": parser.parse(p["ended_at"]).date() } for p in data["prices"]] for product in products: product.prices.all().delete() for price_dict in prices_dicts: Price(product=product, **price_dict).save() return HttpResponse() else: return HttpBadRequest() except Exception: traceback.print_exc()
def invite(self, request, **kwargs): self.method_check(request, allowed=['post']) data = self.deserialize(request, request.body, format=request.META.get( 'CONTENT_TYPE', 'application/json')) email = data.get('email', '') if not email: return HttpBadRequest() try: bundle = self.build_bundle(data={'pk': kwargs['pk']}, request=request) account = self.cached_obj_get( bundle=bundle, **self.remove_api_resource_names(kwargs)) invite = GuestInvitation.objects.invite_user(account=account, email=email) return self.create_response(request, {'token': invite.token}, response_class=HttpCreated) except ObjectDoesNotExist: return HttpGone() except MultipleObjectsReturned: return HttpMultipleChoices( "More than one resource is found at this URI.")
def do_append(self, request, **kwargs): """ Special view for adding the results of a search to a study group. """ self.method_check(request, allowed=['post']) obj, err = self._get_obj_for_wrapped_view(request, **kwargs) if err: return err data = self._get_json_request_data(request) if data is None: return HttpBadRequest("Need JSON request body") jq = data.get("jq", None) expr = person_query_expr(jq, obj.study_id) qs = people.Person.objects.filter(expr) existing = obj.members.all() add = qs.exclude(id__in=existing) if data.get("append", False): obj.members.add(*add) return self.create_response(request, { 'success': True, 'total': qs.count(), 'added': add.count() })
def obj_update(self, bundle, pk='', **kwargs): pk = int(pk) address = Address.objects.filter(id=pk) if address[0].patron == bundle.request.user: address.update(**bundle.data) else: raise ImmediateHttpResponse(response=HttpBadRequest())
def _populate_obj_by_data(self): """Database lookup get everything except the result, 2nd try reverse lookup """ def populate(key): return { 'project': lambda: ProjectResource().get_via_uri(self.data['project']), 'executable': lambda: ExecutableResource().get_via_uri(self.data['executable' ]), 'benchmark': lambda: BenchmarkResource().get_via_uri(self.data['benchmark'] ), 'environment': lambda: EnvironmentResource().get_via_uri(self.data[ 'environment']), 'branch': lambda: BranchResource().get_via_uri(self.data['branch']), 'revision': lambda: RevisionResource().get_via_uri(self.data['commitid']) }.get(key, None)() try: self.obj.value = float(self.data['result_value']) except ValueError, error: logging.error( "Result value: {0} cannot be converted to float. {1}".format( self.data['result_value'], error)) raise ImmediateHttpResponse( response=HttpBadRequest(u"Value needs to be a number"))
def event_receiver(request): """ This actually does nothing, called for testing purpose only """ if request.method == 'POST': data = json.loads(get_raw_post_data(request)) logger.debug(u'got event notification (%s)' % data) digest = generate_hmac_digest( settings('HMAC_KEY', DEV_HMAC_KEY), '%s%s' % ( data['event'], data['ctime'], )) logger.debug(u'hmac digest (%s)' % digest) if digest == data['hmac']: logger.debug(u'the notification has been processed normally.') return HttpResponse(u'OK') else: logger.exception(u'invalid notifcation detected.') return HttpBadRequest(u'Invalid notification detected') return HttpMethodNotAllowed()
def obj_delete(self, pk='', **kwargs): pk = int(pk) number = PhoneNumber.objects.get(id=pk) if number.patron == bundel.request.user: number.delete() else: raise ImmediateHttpResponse(response=HttpBadRequest())
def do_import(self, request, **kwargs): self.method_check(request, allowed=['post']) obj, err = self._get_obj_for_wrapped_view(request, **kwargs) if err: return err data = self._get_json_request_data(request) if not isinstance(data, dict): return HttpBadRequest("Posted data is wrong") kwargs = pluck(data, [ "resource", "key", "update", "create", "overwrite_empty", "mapping" ]) dry_run = data.get("dry_run", False) limit = int(data.get("limit", 0)) or 10 csv_import = CSVImport(obj, **kwargs) if dry_run: result = { 'success': True, 'updates': list(itertools.islice(csv_import.updates, 0, limit)), 'fields': csv_import.fields, 'limit': limit, } else: result = csv_import.apply_updates(request) result["success"] = True return self.create_response(request, result)
def is_timestamp_valid(self, timestamp): """Timestamp must be string in %Y-%m-%dT%H:%M:%S. format """ try: timestamp_server = datetime.utcnow() timestamp_client = datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S") d1_ts = time.mktime(timestamp_client.timetuple()) d2_ts = time.mktime(timestamp_server.timetuple()) diff = int(d2_ts-d1_ts) / 60 if diff > self.timestamp_window: raise ImmediateHttpResponse(response=HttpBadRequest('Exceeded timestamp window')) except Exception, e: raise ImmediateHttpResponse(response=HttpBadRequest('Unknown error on timestamp validation'))
def obj_delete(self, pk='', **kwargs): pk = int(pk) address = Address.objects.get(id=pk) if address.patron == bundle.request.user: address.delete() else: raise ImmediateHttpResponse(response=HttpBadRequest())
def dispatch(self, request, domain, indicator_type=None, *args, **kwargs): self.domain = domain try: self.indicator_class = to_function( "%s.%s" % (self.indicator_loc, indicator_type)) except AttributeError: return HttpBadRequest("%s.%s does not exist" % (self.indicator_loc, indicator_type)) status = {} if request.method == 'POST': form = BulkCopyIndicatorsForm(data=request.POST, domain=self.domain, couch_user=request.couch_user, indicator_class=self.indicator_class) if form.is_valid(): status = form.copy_indicators() else: form = BulkCopyIndicatorsForm(domain=self.domain, couch_user=request.couch_user, indicator_class=self.indicator_class) return render( request, self.template_name, { "form": form, "status": status, "domain": self.domain, "indicator_type": self.indicator_class.__name__, "indicator_name": self.indicator_class.get_nice_name(), })
def zapier_subscription_pre_save(sender, instance, *args, **kwargs): """ Creates a repeater object corresponding to the type of trigger (form or case) """ if instance.pk: return if instance.event_name == EventTypes.NEW_FORM: repeater = FormRepeater(domain=instance.domain, url=instance.url, format='form_json', include_app_id_param=False, white_listed_form_xmlns=[instance.form_xmlns]) elif instance.event_name in CASE_TYPE_REPEATER_CLASS_MAP: repeater = CASE_TYPE_REPEATER_CLASS_MAP[instance.event_name]( domain=instance.domain, url=instance.url, format='case_json', white_listed_case_types=[instance.case_type], ) else: raise ImmediateHttpResponse( HttpBadRequest('The passed event type is not valid.')) repeater.save() instance.repeater_id = repeater.get_id
def get_object_list(self, request): user_id = request.user.id if not user_id: raise ImmediateHttpResponse(HttpBadRequest("Please login first")) this_user_tags = super(TagResource, self).get_object_list(request).filter(user_id=user_id) return this_user_tags
def _unauthorized(self): response = HttpBadRequest() response.content = "Unauthorized" return response