Esempio n. 1
0
File: api.py Progetto: sheep0x/ok
    def index(self):
        """
        Index HTTP method. Should be called from GET when no key is provided.

        Processes cursor and num_page URL arguments for pagination support.
        """
        query = self.model.query()
        need = Need('index')

        result = self.model.can(session['user'], need, query=query)
        if not result:
            return need.api_response()

        args = self.parse_args(True)
        query = filter_query(result, args, self.model)
        created_prop = getattr(self.model, 'created', None)
        if not query.orders and created_prop:
            logging.info("Adding default ordering by creation time.")
            query = query.order(-created_prop)

        page = int(request.args.get('page', 1))
        num_page = request.args.get('num_page', None)
        query_results = paginate(query, page, num_page)

        add_statistics = request.args.get('stats', False)
        if add_statistics:
            query_results['statistics'] = self.statistics()
        return create_api_response(200, "success", query_results)
Esempio n. 2
0
File: api.py Progetto: hpec/ok
    def remove_member(self, group, user, data):
        # can only remove a member if you are a member
        need = Need('member')
        if not group.can(user, need, group):
            raise need.exception()

        if data['member'] in group.members:
            group.members.remove(data['member'])
        elif data['member'] in group.invited_members:
            group.invited_members.remove(data['member'])

        if len(group.members) == 0:
            group.key.delete()
            description = "Deleted group"
        else:
            group.put()
            description = "Changed group"

        audit_log_message = models.AuditLog(
            event_type='Group.remove_member',
            user=user.key,
            obj=group.key,
            description=description
        )
        audit_log_message.put()
Esempio n. 3
0
    def access(self, value):
        user_id, model, obj_name, need = value.input
        self.login(user_id)  # sets self.user

        obj = None
        if model == "User":
            obj = self.accounts[obj_name]
        else:
            obj = getattr(self, model.lower() + 's')[obj_name]

        if not obj:
            self.assertTrue(False, "Invalid test arguments %s" % model)

        if need == "index":
            query = obj.__class__.query()  #pylint: disable=maybe-no-member
            query = obj.can(self.user, Need(need), obj, query=query)

            if not query:
                self.assertFalse(value.output, "|can| method returned false.")
                return

            queried_data = query.fetch()

            if value.output:
                self.assertIn(obj, queried_data)
            else:
                self.assertNotIn(obj, queried_data)
        else:
            self.assertEqual(value.output, obj.can(self.user, Need(need), obj))
Esempio n. 4
0
File: api.py Progetto: hpec/ok
 def reject_invitation(self, group, user, data):
     # can only reject an invitation if you are in the invited_members
     need = Need('invitation')
     if not group.can(user, need, group):
         raise need.exception()
     group.invited_members.remove(user.key)
     group.put()
Esempio n. 5
0
File: api.py Progetto: yuecong/ok
    def score(self, obj, user, data):
        """
        Sets composition score

        :param obj: (object) target
        :param user: (object) caller
        :param data: (dictionary) data
        :return: (int) score
        """
        need = Need('grade')
        if not obj.can(user, need, obj):
            raise need.exception()

        score = models.Score(
            score=data['score'],
            message=data['message'],
            grader=user.key)
        grade = score.put()

        submission = obj.submission.get()

        # Create or updated based on existing scores.
        if data['source'] == 'composition':
          # Only keep any autograded scores.
          submission.score = [autograde for autograde in submission.score \
            if score.autograder]
          submission.score.append(score)
        else:
          submission.score.append(score)

        submission.put()

        return score
Esempio n. 6
0
File: api.py Progetto: yuecong/ok
    def index(self, user, data):
        """
        Index HTTP method. Should be called from GET when no key is provided.

        Processes cursor and num_page URL arguments for pagination support.

        :param user: (object) caller
        :param data: (dictionary)
        :return: results for query
        """
        query = self.model.query()
        need = Need('index')

        result = self.model.can(user, need, query=query)
        if not result:
            raise need.exception()

        query = filter_query(result, data, self.model)
        created_prop = getattr(self.model, 'created', None)
        if not query.orders and created_prop:
            logging.info('Adding default ordering by creation time.')
            query = query.order(-created_prop, self.model.key)

        page = int(request.args.get('page', 1))
        # default page length is 100
        num_page = int(request.args.get('num_page', 100))
        query_results = paginate(query, page, num_page)

        add_statistics = request.args.get('stats', False)
        if add_statistics:
            query_results['statistics'] = self.statistics()
        return query_results
Esempio n. 7
0
File: api.py Progetto: yuecong/ok
    def post(self, user, data):

        need = Need('create')

        if not self.model.can(user, need, None):
            raise need.exception()

        job_type, filters = data['job_type'], data['filters']

        if not isinstance(filters, list):
            raise BadValueError('filters must be a list of triples')
        for filter in filters:
            if len(filter) != 3:
                raise BadValueError('filters must be a list of triples')

        if job_type not in analytics.available_jobs:
            raise BadValueError('job must be of the following types: %s' %
                                ', '.join(list(analytics.available_jobs.keys())))

        job = analytics.get_job(job_type, user, filters)
        job.start()

        return (201, 'success', {
            'key': job.job_dump.key.id()
        })
    def test_participant_can(self):
        """Tests that all users can get, and that only staff can index"""
        get = Need('get')
        self.assertTrue(models.Participant._can(None, get, None, None))

        need = Need('index')
        student = models.User(email=['*****@*****.**']).put().get()
        admin = models.User(email=['*****@*****.**']).put().get()

        course = make_fake_course(student)

        models.Participant.add_role(student.key, course.key,
                                    constants.STUDENT_ROLE)
        models.Participant.add_role(admin.key, course.key,
                                    constants.STAFF_ROLE)

        query = models.Participant.query()

        results = models.Participant._can(student, need, course, query).fetch()
        self.assertNotEqual(None, results)
        self.assertEqual(1, len(results))

        results = models.Participant._can(admin, need, course, query).fetch()
        self.assertNotEqual(None, results)
        self.assertEqual(2, len(results))
Esempio n. 9
0
File: api.py Progetto: hpec/ok
 def remove_staff(self, course, user, data):
     need = Need("staff")
     if not course.can(user, need, course):
         raise need.exception()
     if data['staff_member'] in course.staff:
         course.staff.remove(data['staff_member'])
         course.put()
Esempio n. 10
0
File: api.py Progetto: sheep0x/ok
    def put(self, key):
        """
        The PUT HTTP method
        """
        obj = self.model.get_by_id(key)
        if not obj:
            return create_api_response(404, "{resource} {key} not found".format(
                resource=self.name, key=key))

        need = Need('get')
        if not obj.can(session['user'], need, obj):
            return need.api_response()

        need = Need('put')
        if not obj.can(session['user'], need, obj):
            return need.api_response()

        blank_val = object()
        changed = False
        for key, value in self.parse_args(False).iteritems():
            old_val = getattr(obj, key, blank_val)
            if old_val == blank_val:
                return create_api_response(
                    400, "{} is not a valid field.".format(key))

            setattr(obj, key, value)
            changed = True

        if changed:
            obj.put()

        return create_api_response(200, "", obj)
Esempio n. 11
0
File: api.py Progetto: yuecong/ok
 def get_students(self, course, user, data):
     query = models.Participant.query(
         models.Participant.course == course.key)
     need = Need('staff')
     if not models.Participant.can(user, need, course, query):
         raise need.exception()
     return list(query.fetch())
Esempio n. 12
0
File: api.py Progetto: yuecong/ok
 def get_staff(self, course, user, data):
     need = Need('staff')
     if not course.can(user, need, course):
         raise need.exception()
     query = models.Participant.query(
       models.Participant.course == course.key,
       models.Participant.role == 'staff')
     return list(query.fetch())
Esempio n. 13
0
File: api.py Progetto: yuecong/ok
    def remove_staff(self, course, user, data):
        need = Need('staff')
        if not course.can(user, need, course):
            raise need.exception()

        removed_user = models.User.lookup(data['email'])
        if removed_user:
          models.Participant.remove_role(removed_user, course, STAFF_ROLE)
Esempio n. 14
0
File: api.py Progetto: yuecong/ok
    def invite(self, group, user, data):
        need = Need('invite')
        if not group.can(user, need, group):
            return need.exception()

        error = group.invite(data['email'])
        if error:
            raise BadValueError(error)
Esempio n. 15
0
File: api.py Progetto: yuecong/ok
    def add_staff(self, course, user, data):
        need = Need('staff')
        if not course.can(user, need, course):
            raise need.exception()

        user = models.User.get_or_insert(data['email'])
        if user not in course.staff:
          models.Participant.add_role(user, course, STAFF_ROLE)
Esempio n. 16
0
File: api.py Progetto: yuecong/ok
 def current(self, obj, user, data):
     need = Need('get')
     if not obj.can(user, need, obj):
         raise need.exception()
     if not obj.current_version:
         raise BadValueError(
             'Invalid version resource. Contact an administrator.')
     return obj.current_version
Esempio n. 17
0
File: api.py Progetto: hpec/ok
    def get_instance(self, key, user):
        obj = self.model.get_by_id(key)
        if not obj:
            raise BadKeyError(key)

        need = Need('get')
        if not obj.can(user, need, obj):
            raise need.exception()
        return obj
Esempio n. 18
0
File: api.py Progetto: yuecong/ok
 def download(self, obj, user, data):
     need = Need('get')
     if not obj.can(user, need, obj):
         raise need.exception()
     if 'version' not in data:
         download_link = obj.download_link()
     else:
         download_link = obj.download_link(data['version'])
     return redirect(download_link)
Esempio n. 19
0
File: api.py Progetto: hpec/ok
    def delete(self, obj, user, data):
        """
        The DELETE HTTP method
        """
        need = Need('delete')
        if not self.model.can(user, need, obj=obj):
            raise need.exception()

        obj.key.delete()
Esempio n. 20
0
File: api.py Progetto: hpec/ok
    def add_staff(self, course, user, data):
        need = Need("staff")
        if not course.can(user, need, course):
            raise need.exception()

        if data['staff_member'] not in course.staff:
            user = models.User.get_or_insert(data['staff_member'].id())
            course.staff.append(user.key)
            course.put()
Esempio n. 21
0
File: api.py Progetto: hpec/ok
    def create_staff(self, obj, user, data):
        # Must be a staff to create a staff user
        need = Need("staff")
        if not obj.can(user, need, obj):
            raise need.exception()

        user = models.User.get_or_insert(data['email'].id())
        user.role = data['role']
        user.put()
Esempio n. 22
0
File: api.py Progetto: yuecong/ok
 def set_current(self, obj, user, data):
     need = Need('update')
     if not obj.can(user, need, obj):
         raise need.exception()
     current_version = data['version']
     if current_version not in obj.versions:
         raise BadValueError(
             'Invalid version. Cannot update to current.')
     obj.current_version = current_version
     obj.put()
Esempio n. 23
0
File: api.py Progetto: sheep0x/ok
    def delete(self, user_id):
        """
        The DELETE HTTP method
        """
        ent = self.model.query.get(user_id)

        need = Need('delete')
        if not self.model.can_static(session['user'], need):
            return need.api_response()

        ent.key.delete()
        return create_api_response(200, "success", {})
Esempio n. 24
0
File: api.py Progetto: yuecong/ok
    def delete_email(self, obj, user, data):
        """
        Deletes an email for the user - modified in place.

        :param obj: (object) target
        :param user: (object) caller
        :param data: (dictionary) key "email" deleted
        :return: None
        """
        need = Need('get')
        if not obj.can(user, need, obj):
            raise need.exception()
        obj.delete_email(data['email'])
Esempio n. 25
0
File: api.py Progetto: yuecong/ok
    def add_email(self, obj, user, data):
        """
        Adds an email for the user - modified in place.

        :param obj: (object) target
        :param user: (object) caller
        :param data: -- unused --
        :return: None
        """
        need = Need('get') # Anyone who can get the User object can add an email
        if not obj.can(user, need, obj):
            raise need.exception()
        obj.append_email(data['email'])
Esempio n. 26
0
File: api.py Progetto: yuecong/ok
    def get_instance(self, key, user):
        """
        Convert key from email to UserKey
        """
        obj = self.model.lookup(key)
        if not obj:
            raise BadKeyError(key)

        need = Need('get')
        if not obj.can(user, need, obj):
            raise need.exception()

        return obj
Esempio n. 27
0
File: api.py Progetto: hpec/ok
    def accept_invitation(self, group, user, data):
        # can only accept an invitation if you are in the invited_members
        need = Need('invitation')
        if not group.can(user, need, group):
            raise need.exception()

        assignment = group.assignment.get()
        if len(group.members) < assignment.max_group_size:
            group.invited_members.remove(user.key)
            group.members.append(user.key)
            group.put()
        else:
            raise BadValueError("too many people in group")
Esempio n. 28
0
File: api.py Progetto: sheep0x/ok
    def get(self, key):
        """
        The GET HTTP method
        """
        obj = self.model.get_by_id(key)
        if not obj:
            return create_api_response(404, "{resource} {key} not found".format(
                resource=self.name, key=key))

        need = Need('get')
        if not obj.can(session['user'], need, obj):
            return need.api_response()

        return create_api_response(200, "", obj)
Esempio n. 29
0
File: api.py Progetto: yuecong/ok
    def merge_user(self, obj, user, data):
        """
        Merges this user with another user.
        This user is the user that is "merged" -- no longer can login.
        """
        need = Need('merge')
        if not obj.can(user, need, obj):
            raise need.exception()

        other_user = models.User.lookup(data['other_email'])
        if not other_user:
            raise BadValueError("Invalid user to merge to")

        merge_user(obj, other_user)
Esempio n. 30
0
File: api.py Progetto: yuecong/ok
    def delete(self, obj, user, data):
        """
        DELETE HTTP method

        :param obj: (object) target
        :param user: (object) caller
        :param data: -- unused --
        :return: None
        """
        need = Need('delete')
        if not self.model.can(user, need, obj=obj):
            raise need.exception()

        obj.key.delete()
Esempio n. 31
0
File: api.py Progetto: hpec/ok
    def post(self, user, data):
        """
        The POST HTTP method
        """
        entity = self.new_entity(data)

        need = Need('create')
        if not self.model.can(user, need, obj=entity):
            raise need.exception()

        entity.put()

        return (201, "success", {
            'key': entity.key.id()
        })
Esempio n. 32
0
File: api.py Progetto: yuecong/ok
    def new(self, obj, user, data):
        need = Need('update')
        if not obj.can(user, need, obj):
            raise need.exception()

        new_version = data['version']

        if new_version in obj.versions:
            raise BadValueError('Duplicate version: {}'.format(new_version))

        obj.versions.append(new_version)
        if 'current' in data and data['current']:
            obj.current_version = data['version']
        obj.put()
        return obj
Esempio n. 33
0
 def get_query(self):
     """Returns a query over the specified kind, with any appropriate filters applied."""
     q = self.kind.can(self.user, Need('index'), query=self.kind.query())
     for filter in self.filters:
         q = q.filter(ndb.query.FilterNode(*filter))
     for order in self.orders:
         q = q.order(order)
     return q
Esempio n. 34
0
    def test_backup_index(self):
        """Tests permissions for backup"""
        admin = models.User(email=['*****@*****.**']).put().get()
        course = make_fake_course(admin)
        models.Participant.add_role(admin.key, course.key,
                                    constants.STAFF_ROLE)

        index = Need('index')
        assignment = make_fake_assignment(course, admin)
        backup = models.Backup(submitter=admin.key,
                               assignment=assignment.key).put().get()
        query = models.Backup.query()
        self.assertNotEqual(False,
                            models.Backup._can(admin, index, backup, query))
Esempio n. 35
0
 def test_assignment_can(self):
     """Tests that index always returns"""
     index = Need('index')
     self.assertTrue(models.Assignment._can(None, index, None, True))
Esempio n. 36
0
 def test_message_can(self):
     """Tests that messgea can always false"""
     index = Need('index')
     self.assertFalse(models.Message._can(None, index, None, None))
Esempio n. 37
0
 def test_backup_can_get(self):
     """Tests that backup required"""
     with self.assertRaises(ValueError):
         get = Need('get')
         models.Backup._can(None, get, None, None)
Esempio n. 38
0
 def test_submission_can(self):
     """Tests that mission submission raises valueerror"""
     grade = Need('grade')
     with self.assertRaises(ValueError):
         models.Submission._can(None, grade, None, None)
Esempio n. 39
0
 def test_comment_can(self):
     """test commentp ermissions"""
     admin = models.User(email=['*****@*****.**'], is_admin=True).put().get()
     self.assertTrue(models.Comment._can(admin, None))
     weird = Need('weird')
     self.assertFalse(models.Comment._can(MagicMock(is_admin=False), weird))
Esempio n. 40
0
 def test_version_can(self):
     """Tests that delete always forbidden"""
     need = Need('delete')
     self.assertFalse(models.Version._can(None, need))
Esempio n. 41
0
 def test_can_lookup(self):
     """Tests that anyone can lookup"""
     user = models.User(email=['*****@*****.**']).put().get()
     need = Need('lookup')
     self.assertTrue(user._can(user, need, None, None))
Esempio n. 42
0
 def test_can_get_not_user(self):
     """Tests can get with invalid user"""
     user = models.User(email=['*****@*****.**']).put().get()
     need = Need('get')
     self.assertFalse(user._can(user, need, None, None))
Esempio n. 43
0
 def test_can_index(self):
     """Tests that index only works for user"""
     user = models.User(email=['*****@*****.**']).put().get()
     need = Need('index')
     self.assertTrue(
         user._can(user, need, None, MagicMock(filter=lambda *args: True)))