def activate(self, request, **kwargs): try: self.validate_request(request.GET, ['token']) token = request.GET.get("token", None) # Make sure the key we're trying conforms to the pattern of a # SHA1 hash; if it doesn't, no point trying to look it up in # the database. if SHA1_RE.search(token): profile = RegistrationProfile.objects.get(activation_key=token) if not profile.activation_key_expired(): user = profile.user user.is_active = True user.save() profile.activation_key = RegistrationProfile.ACTIVATED profile.save() return self.create_response(request, { "success": True }) else: return http.HttpForbidden('Your activation token is no longer active or valid') else: return http.HttpForbidden('Your activation token is no longer active or valid') except RegistrationProfile.DoesNotExist: return http.HttpNotFound('Your activation token is no longer active or valid') except MalformedRequestError as e: return http.HttpBadRequest("%s as request GET parameters" % e)
def import_data(self, request, **kwargs): """ Dummy endpoint for kicking off data import tasks. """ self.method_check(request, allowed=['get']) self.is_authenticated(request) self.throttle_check(request) if 'slug' in kwargs: slug = kwargs['slug'] else: slug = request.GET.get('slug') dataset = Dataset.objects.get(slug=slug) upload = DataUpload.objects.get(id=kwargs['upload_id']) # Because users may have authenticated via headers the request.user may # not be a full User instance. To be sure, we fetch one. user = UserProxy.objects.get(id=request.user.id) try: dataset.import_data(user, upload) except DatasetLockedError: raise ImmediateHttpResponse(response=http.HttpForbidden( 'Dataset is currently locked by another process.')) except DataImportError, e: raise ImmediateHttpResponse(response=http.HttpForbidden(e.message))
def obj_create(self, bundle, request=None, **kwargs): """ Handle POST requests to the resource. If the data validates, create a new Review from bundle data. """ form = ReviewForm(bundle.data) if not form.is_valid(): raise self.form_errors(form) app = self.get_app(bundle.data['app']) # Return 409 if the user has already reviewed this app. if self._meta.queryset.filter(addon=app, user=request.user).exists(): raise ImmediateHttpResponse(response=http.HttpConflict()) # Return 403 if the user is attempting to review their own app: if app.has_author(request.user): raise ImmediateHttpResponse(response=http.HttpForbidden()) # Return 403 if not a free app and the user hasn't purchased it. if app.is_premium() and not app.is_purchased(request.amo_user): raise ImmediateHttpResponse(response=http.HttpForbidden()) bundle.obj = Review.objects.create( **self._review_data(request, app, form)) amo.log(amo.LOG.ADD_REVIEW, app, bundle.obj) log.debug('[Review:%s] Created by user %s ' % (bundle.obj.id, request.user.id)) record_action('new-review', request, {'app-id': app.id}) return bundle
def discover_method(self, request=None, **kwargs): content = {} # Deduces request from bundle if request is None and "bundle" in kwargs: request = kwargs["bundle"].request # Refresh syntax cache at each request if hasattr(self, "syntax"): delattr(self, "syntax") # Get the current topic self.topic = self.get_topic_or_404(request=request) # Create a search instance self.search = Search(topic=self.topic) # Check for an optional method to do further dehydration. method = getattr(self, "summary_%s" % kwargs["pk"], None) if method: try: self.throttle_check(request) content = method(kwargs["bundle"], request) if isinstance(content, HttpResponse): response = content else: # Create an HTTP response response = self.create_response(data=content, request=request) except ForbiddenError as e: response = http.HttpForbidden(e) except UnauthorizedError as e: response = http.HttpUnauthorized(e) else: # Stop here, unkown summary type raise Http404("Sorry, not implemented yet!") # We force tastypie to render the response directly raise ImmediateHttpResponse(response=response)
def obj_create(self, bundle, request=None, **kwargs): """ Add one Data to a Dataset. """ dataset = self.get_dataset_from_kwargs(bundle, **kwargs) self.validate_bundle_data(bundle, request, dataset) if 'external_id' in bundle.data: external_id = bundle.data['external_id'] elif 'external_id' in kwargs: external_id = kwargs['external_id'] else: external_id = None # Because users may have authenticated via headers the request.user may # not be a full User instance. To be sure, we fetch one. user = UserProxy.objects.get(id=request.user.id) try: row = dataset.add_row(user, bundle.data['data'], external_id=external_id) except DatasetLockedError: raise ImmediateHttpResponse(response=http.HttpForbidden( 'Dataset is currently locked by another process.')) bundle.obj = SolrObject(row) return bundle
def hydrate(self, bundle): ## get all data from bundle.data user = bundle.request.user.get_profile() category = ProgramAnnotation.CATEGORY data = bundle.data['data'] environment = None area = None try: environment = EnvironmentResource().get_via_uri( bundle.data['environment'], request=bundle.request) except: environment = None try: area = AreaResource().get_via_uri(bundle.data['area'], request=bundle.request) except: area = None try: bundle.obj = ProgramAnnotation(user=user, environment=environment, area=area, category=category, data=data) except DuplicateAnnotationException, e: raise ImmediateHttpResponse(response=http.HttpForbidden( content=e.get_message()))
def obj_get(self, request=None, **kwargs): obj = super(AppResource, self).obj_get(request=request, **kwargs) if not AppOwnerAuthorization().is_authorized(request, object=obj): raise ImmediateHttpResponse(response=http.HttpForbidden()) log.info('App retreived: %s' % obj.pk) return obj
def obj_update(self, bundle, request, **kwargs): data = bundle.data try: obj = self.get_object_list(bundle.request).get(**kwargs) except Webapp.DoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound()) if not AppOwnerAuthorization().is_authorized(request, object=obj): raise ImmediateHttpResponse(response=http.HttpForbidden()) data['slug'] = data.get('slug', obj.app_slug) data.update(self.formset(data)) data.update(self.devices(data)) forms = [ AppDetailsBasicForm(data, instance=obj, request=request), DeviceTypeForm(data, addon=obj), CategoryFormSet(data, addon=obj, request=request) ] valid = all([f.is_valid() for f in forms]) if not valid: raise self.form_errors(forms) forms[0].save(obj) forms[1].save(obj) forms[2].save() log.info('App updated: %s' % obj.pk) bundle.obj = obj return bundle
def dispatch(self, request, *args, **kwargs): post = Post.objects.get(slug=kwargs['slug']) if post.moderator == request.user: return super(PostDeleteView, self).dispatch(request, *args, **kwargs) else: return http.HttpForbidden()
def handle(self, bundle, request, **kwargs): form = ReceiptForm(bundle.data) if not form.is_valid(): raise self.form_errors(form) bundle.obj = form.cleaned_data['app'] # Developers get handled quickly. if check_ownership(request, bundle.obj, require_owner=False, ignore_disabled=True, admin=False): return self.record(bundle, request, apps.INSTALL_TYPE_DEVELOPER) # The app must be public and if its a premium app, you # must have purchased it. if not bundle.obj.is_public(): log.info('App not public: %s' % bundle.obj.pk) raise ImmediateHttpResponse(response=http.HttpForbidden()) if (bundle.obj.is_premium() and not bundle.obj.has_purchased(request.amo_user)): log.info('App not purchased: %s' % bundle.obj.pk) raise ImmediateHttpResponse(response=HttpPaymentRequired()) # Anonymous users will fall through, they don't need anything else # handling. if request.user.is_authenticated(): return self.record(bundle, request, apps.INSTALL_TYPE_USER)
def open_elections(self, request, **kwargs): ''' Lists the open elections in which the authenticated user can participate ''' from .election import ResultsElectionResource search = request.GET.get('q', '') class UserElectionResource(ResultsElectionResource): ''' ElectionResource with some handy information for the user ''' has_user_voted = fields.BooleanField(default=False) has_user_voted_via_a_delegate = fields.BooleanField(default=False) def dehydrate_has_user_voted(self, bundle): return bundle.obj.has_user_voted(request.user) def dehydrate_has_user_voted_via_a_delegate(self, bundle): return bundle.obj.has_user_voted_via_a_delegate(request.user) if kwargs.has_key('userid'): user = get_object_or_404(User, pk=kwargs['userid']) else: user = request.user if user.is_anonymous(): raise ImmediateHttpResponse(response=http.HttpForbidden()) queryset = user.get_profile().get_open_elections(search) return UserElectionResource().get_custom_list(request=request, queryset=queryset)
def obj_delete(self, request, **kwargs): obj = self.get_by_resource_or_404(request, **kwargs) if not AppOwnerAuthorization().is_authorized(request, object=obj.addon): raise ImmediateHttpResponse(response=http.HttpForbidden()) log.info('Preview deleted: %s' % obj.pk) return super(PreviewResource, self).obj_delete(request, **kwargs)
def obj_get(self, request=None, **kwargs): if kwargs.get('pk') == 'mine': kwargs['pk'] = request.amo_user.pk # TODO: put in acl checks for admins to get other users information. obj = super(AccountResource, self).obj_get(request=request, **kwargs) if not OwnerAuthorization().is_authorized(request, object=obj): raise ImmediateHttpResponse(response=http.HttpForbidden()) return obj
def obj_delete(self, request, **kwargs): obj = self.get_by_resource_or_404(request, **kwargs) if not (AppOwnerAuthorization().is_authorized(request, object=obj.addon) or OwnerAuthorization().is_authorized(request, object=obj) or PermissionAuthorization('Users', 'Edit').is_authorized(request) or PermissionAuthorization('Addons', 'Edit').is_authorized(request)): raise ImmediateHttpResponse(response=http.HttpForbidden()) log.info('Rating %s deleted from addon %s' % (obj.pk, obj.addon.pk)) return super(RatingResource, self).obj_delete(request, **kwargs)
def signup(self, request, **kwargs): self.method_check(request, allowed=['post']) data = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json')) try: self.validate_request(data, ['username', 'email', 'password']) user = User.objects.create_user( data.get("username"), data.get("email"), data.get("password") ) # Create an inactive user setattr(user, "is_active", False) user.save() # User used a invitation token if data.get("token", None) is not None: try: topicToken = TopicToken.objects.get(token=data.get("token")) # Add the user to the topic contributor group topicToken.topic.get_contributor_group().user_set.add(user) # Remove the token topicToken.delete() except TopicToken.DoesNotExist: # Failed silently if the token is unkown pass # Could we activate the new account by email? if settings.ACCOUNT_ACTIVATION_ENABLED: # Creates the activation key activation_key = self.get_activation_key(user.username) # Create the regisration profile rp = RegistrationProfile.objects.create(user=user, activation_key=activation_key) # Send the activation email rp.send_activation_email( RequestSite(request) ) # Output the answer return http.HttpCreated() except MalformedRequestError as e: return http.HttpBadRequest(e.message) except PermissionDenied as e: return http.HttpForbidden(e.message) except IntegrityError as e: return http.HttpForbidden("%s in request payload (JSON)" % e)
def apply_filters(self, request, applicable_filters): if (request.GET.get('restricted', False) and 'email' not in applicable_filters and len(applicable_filters) != 1): raise ImmediateHttpResponse(response=http.HttpForbidden()) mega_filter = Q() for db_filter in applicable_filters.values(): mega_filter &= db_filter if request.GET.get('restricted', False): mega_filter &= Q(allows_community_sites=True) return UserProfile.objects.complete().filter(mega_filter).distinct().order_by('id')
def obj_get(self, request=None, **kwargs): # Until the perms branch lands, this is the only way to lock # permissions down on gets, since the object doesn't actually # get passed through to OwnerAuthorization. try: obj = FileUpload.objects.get(pk=kwargs['pk']) except FileUpload.DoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound()) if not OwnerAuthorization().is_authorized(request, object=obj): raise ImmediateHttpResponse(response=http.HttpForbidden()) log.info('Validation retreived: %s' % obj.pk) return obj
def obj_delete(self, request=None, **kwargs): """ Delete a ``Data``. """ dataset = Dataset.objects.get(slug=kwargs['dataset_slug']) # Because users may have authenticated via headers the request.user may # not be a full User instance. To be sure, we fetch one. user = UserProxy.objects.get(id=request.user.id) try: dataset.delete_row(user, kwargs['external_id']) except DatasetLockedError: raise ImmediateHttpResponse(response=http.HttpForbidden( 'Dataset is currently locked by another process.'))
def obj_create(self, bundle, request, **kwargs): form = UploadForm(bundle.data) if not form.is_valid(): raise self.form_errors(form) if not (OwnerAuthorization().is_authorized(request, object=form.obj)): raise ImmediateHttpResponse(response=http.HttpForbidden()) plats = [Platform.objects.get(id=amo.PLATFORM_ALL.id)] # Create app, user and fetch the icon. bundle.obj = Webapp.from_upload(form.obj, plats) AddonUser(addon=bundle.obj, user=request.amo_user).save() tasks.fetch_icon.delay(bundle.obj) log.info('App created: %s' % bundle.obj.pk) return bundle
def obj_update(self, bundle, request, **kwargs): try: obj = self.get_object_list(bundle.request).get(**kwargs) except Addon.DoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound()) if not AppOwnerAuthorization().is_authorized(request, object=obj): raise ImmediateHttpResponse(response=http.HttpForbidden()) form = StatusForm(bundle.data, instance=obj) if not form.is_valid(): raise self.form_errors(form) form.save() log.info('App status updated: %s' % obj.pk) bundle.obj = obj return bundle
def obj_create(self, bundle, request, **kwargs): addon = self.get_object_or_404(Webapp, pk=request.GET.get('app')) if not AppOwnerAuthorization().is_authorized(request, object=addon): raise ImmediateHttpResponse(response=http.HttpForbidden()) data_form = PreviewJSONForm(bundle.data) if not data_form.is_valid(): raise self.form_errors(data_form) form = PreviewForm(data_form.cleaned_data) if not form.is_valid(): raise self.form_errors(form) form.save(addon) bundle.obj = form.instance log.info('Preview created: %s' % bundle.obj.pk) return bundle
def obj_get(self, request=None, **kw): try: obj = super(StatusPayResource, self).obj_get(request=request, **kw) except ObjectDoesNotExist: # Anything that's not correct will be raised as a 404 so that it's # harder to iterate over contribution values. log.info('Contribution not found') return None if not OwnerAuthorization().is_authorized(request, object=obj): raise ImmediateHttpResponse(response=http.HttpForbidden()) if not obj.addon.has_purchased(request.amo_user): log.info('Not in AddonPurchase table') return None return obj
def obj_delete(self, request=None, **kwargs): """ Override delete to also update related Dataset's metadata. """ obj = kwargs.pop('_obj', None) if not hasattr(obj, 'delete'): try: obj = self.obj_get(request, **kwargs) except ObjectDoesNotExist: raise NotFound( "A model instance matching the provided arguments could not be found." ) try: obj.delete() except DataUploadNotDeletable, e: raise ImmediateHttpResponse(response=http.HttpForbidden(e.message))
def async_state(self, request, task_id, **kwargs): """ Task state. If request method is GET, it returns a JSON dict with state. If task has completed, that dict also contains ``result_uri`` entry. If request method is DELETE and task hasn't run yet, it revokes this task. See http://celery.readthedocs.org/en/latest/userguide/workers.html#persistent-revokes for details about running workers with persitent revokes. If task can't be revoked (is in progress or finished), we return response with HTTP Bad Request state. Other methods are forbidden. """ if not getattr(settings, 'CELERY_ALWAYS_EAGER'): task = AsyncResult(task_id) else: task = EAGER_RESULTS[task_id] if request.method == 'GET': data = { 'state': task.state, 'id': task.id, 'resource_uri': request.get_full_path() } if task.ready(): data['result_uri'] = self._build_reverse_url( 'api_async_result', kwargs={ 'api_name': self._meta.api_name, 'resource_name': self._meta.resource_name, 'task_id': task_id }) return self.create_response(request, data) elif request.method == 'DELETE': if not task.ready(): try: task.revoke(terminate=True) return http.HttpGone() except: pass return http.HttpBadRequest() else: return http.HttpForbidden()
def delete_list(self, request, **kwargs): """ Delete all ``Data`` in a ``Dataset``. Must be called from a data url nested under a Dataset. Deleting *all* ``Data`` objects is not supported. """ dataset = Dataset.objects.get(slug=kwargs['dataset_slug']) # Because users may have authenticated via headers the request.user may # not be a full User instance. To be sure, we fetch one. user = UserProxy.objects.get(id=request.user.id) try: dataset.delete_all_rows(user) except DatasetLockedError: raise ImmediateHttpResponse(response=http.HttpForbidden( 'Dataset is currently locked by another process.')) return http.HttpNoContent()
def clean(self, *args, **kwargs): cleaned_data = super(ElectionAdminForm, self).clean() if not self.instance.has_perms('edit_details', self.request.user): raise ImmediateHttpResponse(response=http.HttpForbidden()) from_date = cleaned_data.get("from_date", None) to_date = cleaned_data.get("to_date", None) if not from_date and not to_date: return cleaned_data if from_date < timezone.now(): raise django_forms.ValidationError(_('Invalid start date, must be ' 'in the future')) if from_date and to_date and ((to_date - from_date) < datetime.timedelta(hours=1)): raise django_forms.ValidationError(_('Voting time must be at least 1 hour')) return cleaned_data
def clean(self, *args, **kwargs): import markdown import html2text from agora_site.agora_core.templatetags.string_tags import urlify_markdown from django.template.defaultfilters import truncatewords_html cleaned_data = super(ElectionAdminForm, self).clean() if not self.instance.has_perms('edit_details', self.request.user): raise ImmediateHttpResponse(response=http.HttpForbidden()) cleaned_data['pretty_name'] = clean_html(cleaned_data['pretty_name'], True) cleaned_data['description'] = clean_html(cleaned_data['description']) short_description = cleaned_data['short_description'] short_description = html2text.html2text( short_description[:140]).strip() short_description = markdown.markdown( urlify_markdown(short_description), safe_mode="escape", enable_attributes=False) cleaned_data['short_description'] = truncatewords_html( short_description, 25)[:140] from_date = cleaned_data.get("from_date", None) to_date = cleaned_data.get("to_date", None) if not from_date and not to_date: return cleaned_data if from_date < timezone.now(): raise django_forms.ValidationError( _('Invalid start date, must be ' 'in the future')) if from_date and to_date and ( (to_date - from_date) < datetime.timedelta(hours=1)): raise django_forms.ValidationError( _('Voting time must be at least 1 hour')) return cleaned_data
def export_data(self, request, **kwargs): """ Dummy endpoint for kicking off data export tasks. NB: This endpoint is used for both exporting complete datasets (without a query arg) and exporting dataset search results (with a query arg). """ self.method_check(request, allowed=['get']) self.is_authenticated(request) self.throttle_check(request) if 'slug' in kwargs: slug = kwargs['slug'] else: slug = request.GET.get('slug') dataset = Dataset.objects.get(slug=slug) query = request.GET.get('q', '') since = request.GET.get('since', None) if since: query = 'last_modified:[' + since + 'Z TO *] AND (%s)' % query # Because users may have authenticated via headers the request.user may # not be a full User instance. To be sure, we fetch one. user = UserProxy.objects.get(id=request.user.id) try: dataset.export_data(user, query=query) except DatasetLockedError: raise ImmediateHttpResponse(response=http.HttpForbidden( 'Dataset is currently locked by another process.')) bundle = self.build_bundle(obj=dataset, request=request) bundle = self.full_dehydrate(bundle) self.log_throttled_access(request) return self.create_response(request, bundle)
def apply_filters(self, request, applicable_filters): """Implement advanced filters. - Implement 'groups' filter. - Implement 'languages' filter. - Implement 'skills' filter. """ if (request.GET.get('restricted', False) and 'email__text' not in applicable_filters and len(applicable_filters) != 1): raise ImmediateHttpResponse(response=http.HttpForbidden()) if request.GET.get('restricted', False): applicable_filters.append(F(allows_community_sites=True)) mega_filter = F() for filter in applicable_filters: mega_filter &= filter return S(UserProfile).filter(mega_filter)
def agoras(self, request, **kwargs): ''' Lists the agoras in which the authenticated user or the specified user is a member ''' from .agora import TinyAgoraResource class AgoraPermissionsResource(TinyAgoraResource): agora_permissions = fields.ApiField() def dehydrate_agora_permissions(self, bundle): return bundle.obj.get_perms(bundle.request.user) if kwargs.has_key('userid'): user = get_object_or_404(User, pk=kwargs['userid']) else: user = request.user if user.is_anonymous(): raise ImmediateHttpResponse(response=http.HttpForbidden()) return AgoraPermissionsResource().get_custom_list( request=request, queryset=user.agoras.all())