Beispiel #1
0
    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() not in self.allowed_methods:
            return err("Method {} not allowed.".format(request.method), 405)

        try:
            check_perms(request, getattr(self, '_perms', {}))
        except BaseAuthError as e:
            return err(e, e.status)
        #It makes sense why these are stored in the request, but i want them
        #in the view for convenience purposes
        self.accept = request.META.get('HTTP_ACCEPT', 'application/json')
        self.params = request.GET
        self.params._mutable = True #no reason for it to stay immutable
        self.fields = [f for f in self.params.get('_fields', "").split(',') 
                       if f in self.field_names]
        
        self.sdepth = (int(self.params['_depth']) 
                       if self.params.get('_depth', None) is not None and 
                       self.params.get('_depth', None).isdigit() else 0)
        if not self.sdepth:
            if hasattr(self, 'expand') or '_expand' in self.params:
                self.sdepth = 1
        if getattr(settings, 'HYPERLINK_VALUES', True):
            self.rootcall = request.scheme + '://' + request.get_host()
        else:
            self.rootcall = ''
        try:
            self.data = read(request)
        except ValueError as e:
            return err(e)
        return super(ViewWrapper, self).dispatch(request, *args, **kwargs)
Beispiel #2
0
def response(mview, qs, headers={}, extra=None):
    '''
    Returns a response according to the type of request made. This is done 
    by passing in the Accept header with the desired Content-Type. If a 
    recognizable content type is not found, defaults to json. This is a 
    utility for serializing objects.
    
    If the query param single=true is found, then will return a single 
    object if the queryset returns only one object. Otherwise all queries 
    are sent in a list by default. This option is only available for json.
    
    @param mview: the modelview that is sending the response
    @param request: the request object
    @param qs: an iterable of manager objects, if a string or None will
        return an error response
    @param headers: a dictionary of headers to add
    @param fields: a list of fields to include
    @param extra: any extra data that needs to be serialized
    @return the HttpResponse object
    '''
    if qs is None or isinstance(qs, str):
        if qs is None:
            return err("There was a problem in querying the database"
                       " with the query params provided.")
        else:
            return err(qs)
    resp = serialize_to_response(mview,
                                 qs,
                                 rootcall=getattr(mview, 'rootcall', ''),
                                 extra=extra)
    print(len(connection.queries))
    if headers:
        set_headers(resp, headers)
    return resp
Beispiel #3
0
 def _wrapped(request, *args, **kwargs):
     if not request.user.is_authenticated():
         return err("Unauthenticated", 401)
     if request.user.level >= get_level(level):
         return func(request, *args, **kwargs)
     return err(
         "Unauthorized. You are not of level {} or above.".format(
             level), 403)
Beispiel #4
0
 def _wrapped(request, *args, **kwargs):
     from db.models import User
     if not request.user.is_authenticated():
         return err("Unauthenticated", 401)
     if request.user.level >= User.get_level_by_name(level):
         return func(request, *args, **kwargs)
     return err(
         "Unauthorized. You are not of level {} or above.".format(
             level), 403)
Beispiel #5
0
 def put(self, request, *args, **kwargs):
     try:
         self._check_objs_for_perm(request, *args, **kwargs)
     except AuthorizationError as e:
         return err(e, e.status)
     except KeyError as e:
         return err(e)
     except FieldDoesNotExist as e:
         return err(e)
     return super(ModPerms, self).put(request, *args, **kwargs)
Beispiel #6
0
 def post(self, request, *args, **kwargs):
     assignment = self.data["data"].get("assignment_id", None)
     if assignment is None:
         return err("Must include an assignment_id to create a user assignment.")
     if 'owner_id' not in self.data["data"]:
         return err("Must include an owner_id to create a user assignment.")
     self.data["requirements"] = (Assignment
                                     .objects
                                     .filter(id=assignment)
                                     .values_list("requirements", flat=True)[0]
                                 )
     return super(UserAssignment, self).post(request, *args, **kwargs)
Beispiel #7
0
 def _wrapped(request, *args, **kwargs):
     from db.models import User
     if not request.user.is_authenticated():
         return err("Unauthenticated", 401)
     if request.user.level >= User.get_level_by_name(level):
         return func(request, *args, _authenticated=True, **kwargs)
     return func(request, *args, _authenticated=False, **kwargs)
Beispiel #8
0
 def _get_assignments_and_students_enrolled_and_not_enrolled(self, request, *args, **kwargs):
     """
     Retrieves the given assignment and returns a separate list of all of
     the students with their name and their id. If they are assigned to
     the assignment, they will be in the assigned_to attribute, and the
     to_assign will the others go.
     """
     try:
         assigned = Assignment.objects.prefetch_related().get(id=kwargs['id'])
     except ObjectDoesNotExist:
         return err("Assignment with id {} does not exist."
                         .format(kwargs['id'])
                    )
     students = User.objects.exclude(Q(id__in=assigned.users.all()) | Q(level__gt=0))
     
     respDict = {
                 "assignment" : {
                                 "description" : assigned.description,
                                 "due_date" : assigned.due_date
                                 },
                 "assigned_to" : objs_to_dict(User, 
                                              assigned.users.all(),
                                              ("id", "lname", "fname")
                                              ),
                 "to_assign" : objs_to_dict(User, 
                                              students,
                                              ("id", "lname", "fname")
                                              )
                 }
     return jr(respDict)
Beispiel #9
0
 def post(self, request, *args, **kwargs):
     '''
     Log the person in. Login requires the following json to work:
     
         {
             "email" : "<email>",
             "password" : "<password>"
         }
     '''
     try:
         session_id = authenticate(request)
         resp = HttpResponse(request, status=204)
         resp.set_cookie("sessionid", session_id, max_age=30)
         return resp
     except (KeyError, ValueError) as e:
         return err(e)
     except AuthenticationError as ae:
         return err(ae, 401)
Beispiel #10
0
 def delete(self, request, *args, **kwargs):
     '''
     Delete an entity. This is a no payload endpoint where you can delete 
     either in bulk or singly.
     
     Filtering is done in the same way as GET.
     
     Will return status 204 if successful.
     '''
     args = self._get_ids_from_args(*args)
     if not args:
         if "ids" not in self.params:
             return err("Did not contain any valid ids to delete.")
     try:
         deletes = self._get_qs(*args, **kwargs)   
     except TypeError as e:
         return err(e)
     deletes.delete()
     return other_response()
Beispiel #11
0
 def put(self, request, *args, **kwargs):
     '''
     The put currently only accepts json. Json generically looks like:
     
     {  
         "data" : {
             "<data_field_name>" : "<data>" | <data>, ...
         },
         "<m2m>" : {
             "add" : [ .... ],
             "delete" : [ .... ]
         }
     }
     
     Note that you can update from a queryset relative to the rules of a get. 
     Meaning you can search for a set of entities to update at once.
     
     Filtering is done in the same way as GET.
     
     To perform a multi update, pass in an array for data and all query
     params from the url query will be ignored in favor of the data provided
     in the individual objects. You can only update on the given entity, 
     and you must provide the lookup value to help determine what entity
     or entities need to be updated with the given data.
     
     The json object should then look as follows:
     
     {
         "lookup" : "<field_lookup>",
         "data" : [
             {
                 "data" : {
                     "<data_field_name>" : "<data>" | <data>, ...
                 },
                 "<m2m>" : {
                     "add" : [ .... ],
                     "delete" : [ .... ]
                 }
             }
         ]
     }
     
     Be careful, it does not validate that this is a unique lookup and will
     update all values returned in the qs. If you do not provide a lookup, it
     will assume the pk and will search for the pk in the body of the data.
     If the pk is not found, then an error is thrown and none are updated.
     '''
     try:
         self.do_put(request, *args, **kwargs)
     except (KeyError, FieldDoesNotExist, TypeError) as e:
         return err(e)
     return other_response()
Beispiel #12
0
 def post(self, request, *args, **kwargs):
     '''
     Creates a new poster. The poster object should be of the following json 
     type:
     
         {
             "email" : "<email>",
             "password" : "<password>"
         }
     '''
     j = read(request)
     try:
         p = USER().objects.create_user(**j)
         resp = convert_to_dicts([p], p.field_names, p)[0]
         return jr(resp)
     except IntegrityError as ie:
         return err(ie)
Beispiel #13
0
 def put(self, request, *args, **kwargs):
     def remove_prohibited(d):
         removed = ""
         if "assignment" in d:
             del d['assignment_id']
             removed += "assignment_id"
         if "owner" in d:
             del d['owner_id']
             removed += "owner_id"
         if "reviewed" in d:
             del d['reviewed']
             removed += "reviewed"
         if "score" in d:
             del d['score']
             removed += "score"
         return removed
             
     if request.user.level > 0:
         return super(UserAssignment, self).put(request, *args, **kwargs)
     else:
         expand = self.expand #ensure that it returns dictionaries
         self.expand = False
         qs = self.do_get(request, *args, **kwargs)
         self.expand = expand 
         print(qs, request.user.pk)
         if any([request.user.pk != x['owner_id'] for x in qs]):
             return err("Unauthorized. Cannot make change for someone other"
                        " than yourself.", 403)
         if isinstance(self.data, list):
             removed = []
             for d in self.data:
                 removed.append(remove_prohibited(d['data']))
             if removed:
                 removed = '|'.join(["{} : {}".format(i, r) 
                                      for i, r in enumerate(removed)])
         else:
             removed = remove_prohibited(self.data['data'])
         
         resp = super(UserAssignment, self).put(request, *args, **kwargs)
         if removed:
             setattr(resp, "X-Removed", removed)
             print(removed)
         return resp
Beispiel #14
0
 def do_get(self, request, *args, **kwargs):
     '''
     Will do a get without returning a response, but instead returns the
     list of objects that can be serialized by the serializer. Useful if
     you want the GET functionality but need to do some transforms on the
     output before sending. This is a method to override GET without
     rewriting everything.
     
     Look at get for more info on how this is to be used.
     
     @return an iterable of values from the database, not necessarily of 
     model objects
     '''
     try:
         qs = self._expand(self._get_qs(*args, **kwargs))
     except ValueError as e:
         return err(e, 500)
     qs = self._get_aggs(qs)
     if 'latest' in self.params:
         qs = [qs[0]]
     return qs
Beispiel #15
0
 def _wrapped(request, *args, **kwargs):
     if not request.user.is_authenticated():
         return err("Unauthenticated", 401)
     if request.user.level >= get_level(level):
         return func(request, *args, _authenticated=True, **kwargs)
     return func(request, *args, _authenticated=False, **kwargs)
Beispiel #16
0
 def delete(self, request, *args, **kwargs):
     try:
         self._check_objs_for_perm(request, *args, **kwargs)
     except AuthorizationError as e:
         return err(e, e.status)
     return super(ModPerms, self).delete(request, *args, **kwargs)
Beispiel #17
0
 def wrapper(request, *args, **kwargs):
     if request.user.is_authenticated():
         return func(request, *args, **kwargs)
     return err("Unauthenticated.", 401)