Exemplo n.º 1
0
    def modify_org(self, user_email, org_name, code, reason):
        with model.session_scope() as session:
            org = session.query(model.Organisation).\
                filter(func.lower(model.Organisation.name) ==
                       func.lower(org_name)).one()

            to_son = ToSon(
                r'/id$',
                r'/name$',
                r'/title$',
                r'/locations.*$',
                r'/meta.*$',
                r'/surveygroups$',
                r'/[0-9]+$',
            )
            to_son.exclude(
                r'/locations/[0-9]+/id$',
                r'/locations/[0-9]+/organisation.*$',
                r'/meta/id$',
                r'/meta/organisation.*$',
            )
            org_son = to_son(org)

        with base.mock_user(user_email):
            post_data = org_son.copy()
            response = self.fetch("/organisation/%s.json" % org_son['id'],
                                  method='PUT',
                                  body=json_encode(post_data),
                                  expected=code)
        self.assertIn(reason, response.reason,
                      "%s operating on %s" % (user_email, org_name))
Exemplo n.º 2
0
    def get(self, user_id):
        '''
        Get a single user.
        '''
        if not user_id:
            self.query()
            return

        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            if user_id == 'current':
                user = user_session.user
            else:
                user = (
                    session.query(model.AppUser)
                    .options(joinedload('organisation'))
                    .options(joinedload('surveygroups'))
                    .get(user_id))
                if not user:
                    raise errors.MissingDocError("No such user")

            policy = user_session.policy.derive({
                'user': user,
                'surveygroups': user.surveygroups,
            })
            policy.verify('user_view')

            # Check that user shares a common surveygroup with the requesting
            # user.
            # Allow admins to access users outside their surveygroups though.
            if not policy.check('admin'):
                policy.verify('surveygroup_interact')

            to_son = ToSon(
                r'/id$',
                r'/name$',
                r'/title$',
                r'/email$',
                r'/email_interval$',
                r'/role$',
                r'/deleted$',
                # Descend into nested objects
                r'/organisation$',
                r'/[0-9+]$',
                # Exclude password from response. Not really necessary because
                # 1. it's hashed and 2. it's not in the list above. But just to
                # be safe.
                r'!password',
            )
            if policy.check('surveygroup_browse'):
                to_son.add(r'^/surveygroups$')
            son = to_son(user)
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Exemplo n.º 3
0
    def test_son_node(self):

        input = TestNode(id_col=uuid.uuid4(),
                         int_col=1,
                         bool_col=True,
                         string_col="foo",
                         float_col=0.5,
                         date_col=datetime.date(2015, 1, 1))
        input.parent = TestNode(int_col=2, string_col="bar")

        output = {
            'idCol': str(input.id_col),
            'intCol': 1,
            'boolCol': True,
            'stringCol': "foo",
            'floatCol': 0.5,
            'parent': {
                'intCol': 2,
                'stringCol': "bar"
            },
            'dateCol': time.mktime(input.date_col.timetuple()),
        }
        to_son = ToSon(omit=True)
        self.assertEqual(output, to_son(input))

        output = {
            'idCol': str(input.id_col),
            'intCol': 1,
            'boolCol': True,
            'floatCol': 0.5,
            'parent': {
                'stringCol': "bar"
            },
            'dateCol': time.mktime(input.date_col.timetuple()),
        }
        to_son = ToSon(r'!^/string_col', r'!parent/int_col', omit=True)
        self.assertEqual(output, to_son(input))

        output = {'idCol': str(input.id_col), 'parent': {'stringCol': "bar"}}
        to_son = ToSon(r'^/id_col', r'^/parent$', r'parent/string_col')
        self.assertEqual(output, to_son(input))

        output = {
            'idCol': str(input.id_col),
            'parent': {
                'intCol': 2,
            }
        }
        to_son = ToSon(r'^/id_col', r'^/parent', r'!string_col', omit=True)
        self.assertEqual(output, to_son(input))

        input.parent.parent = input
        to_son = ToSon()
        with self.assertRaises(UtilException):
            to_son(input)
Exemplo n.º 4
0
    def query(self, submission_id):
        '''Get a list.'''
        qnode_id = self.get_argument('qnodeId', '')
        if not qnode_id:
            raise errors.ModelError("qnode ID required")

        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            submission = (session.query(model.Submission).options(
                joinedload('organisation')).filter_by(
                    id=submission_id).first())

            if not submission:
                raise errors.MissingDocError("No such submission")

            policy = user_session.policy.derive({
                'org':
                submission.organisation,
                'submission':
                submission,
                'surveygroups':
                submission.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('response_view')

            rnode = (session.query(model.ResponseNode).get(
                (submission_id, qnode_id)))
            if not rnode:
                responses = []
            else:
                responses = rnode.responses

            to_son = ToSon(
                # Fields to match from any visited object
                r'/id$',
                r'/score$',
                r'/approval$',
                r'/modified$',
                r'/not_relevant$',
                r'^/[0-9]+/error$',
                # Descend into nested objects
                r'/[0-9]+$',
                r'/measure$',
            )
            if user_session.user.role == 'clerk':
                to_son.exclude(r'/score$')
            sons = to_son(responses)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 5
0
    def get(self, ob_type, ids):
        if ob_type:
            self.query(ob_type, ids.split(','))
            return

        subscription_id = ids
        with model.session_scope() as session:
            subscription = (session.query(
                model.Subscription).get(subscription_id))
            if not subscription:
                raise errors.MissingDocError("No such subscription")

            user_session = self.get_user_session(session)
            policy = user_session.policy.derive({
                'user': subscription.user,
            })
            policy.verify('subscription_view')

            to_son = ToSon(
                r'/created$',
                r'/user_id$',
                r'/subscribed$',
                r'/ob_type$',
                r'/ob_refs/?.*$',
            )
            son = to_son(subscription)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Exemplo n.º 6
0
 def test_son(self):
     date = datetime.date(2015, 1, 1)
     id_ = uuid.uuid4()
     input = {
         'a_string': "foo",
         'a_date': date,
         'a_uuid': id_,
         'a_list': [1, id_, {
             '3': date
         }],
         'a_dict': {
             'a_nested_item': "bar"
         }
     }
     output = {
         'aString': "foo",
         'aDate': time.mktime(date.timetuple()),
         'aUuid': str(id_),
         'aList': [1, str(id_), {
             '3': time.mktime(date.timetuple())
         }],
         'aDict': {
             'aNestedItem': "bar"
         }
     }
     to_son = ToSon()
     self.assertEqual(output, to_son(input))
Exemplo n.º 7
0
 def test_son_sanitise(self):
     input = {
         'safe_html': '<script>foo</script> '
         '<a href="http://bar">bar</a> '
         '<a href="javascript:fn()">baz</a>',
         'strip_script': '<script>foo</script>',
         'strip_protocol': '<a href="http://bar">bar</a> '
         '<a href="javascript:fn()">baz</a>',
         'strip_click': '<span onclick="fn()">bar</span> '
         '<a onclick="fn()">baz</a>',
         'a_dict': {
             'strip_script': '<script>foo</script>',
         }
     }
     output = {
         'safeHtml': '<script>foo</script> '
         '<a href="http://bar">bar</a> '
         '<a href="javascript:fn()">baz</a>',
         'stripScript': 'foo',
         'stripProtocol': '<a href="http://bar">bar</a> <a>baz</a>',
         'stripClick': 'bar <a>baz</a>',
         'aDict': {
             'stripScript': 'foo',
         }
     }
     to_son = ToSon(r'/safe_html$', r'</strip.*$', r'^/a_dict$')
     self.assertEqual(output, to_son(input))
Exemplo n.º 8
0
    def modify_org_in_user(self, user_email, old_org_name, new_org_name, code,
                           reason):
        with model.session_scope() as session:
            org = (session.query(model.Organisation).filter(
                func.lower(model.Organisation.name) == func.lower(
                    new_org_name)).one())

            to_son = ToSon(
                r'/id$',
                r'/name$',
                r'/surveygroups$',
                r'/[0-9]+$',
            )
            org_son = to_son(org)

            user = (session.query(model.AppUser).filter(
                func.lower(model.AppUser.email) == func.lower(
                    user_email)).one())

            user_son = to_son(user)
            user_son['organisation'] = org_son

            with base.mock_user(user_email):
                response = self.fetch("/user/%s.json" % user_son['id'],
                                      method='PUT',
                                      body=json_encode(user_son),
                                      expected=code)
                self.assertIn(reason, response.reason, msg=user_email)
Exemplo n.º 9
0
    def get(self, path):
        if path == '':
            path = 'index.html'
        template = os.path.join(self.path, path)

        with model.session_scope() as session:
            if self.uses_old_url(session):
                self.redirect_to_canonical(session)
                return

            user_session = self.get_user_session(session)
            params = TemplateParams(session)
            theme_params = theme.ThemeParams(session)

            to_son = ToSon(
                r'/id$',
                r'/name$',
                r'/title$',
                r'/email$',
                r'/role$',
                r'/deleted$',
                r'/organisation$',
                r'!password',
                r'^/surveygroups$',
                r'/[0-9+]$',
            )
            user_son = json_encode(to_son(user_session.user))

            self.render(
                template, params=params, theme=theme_params,
                user=user_session.user, organisation=user_session.org,
                user_son=user_son)
Exemplo n.º 10
0
    def get(self, submission_id, measure_id, submeasure_id):
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            response = (
                session.query(model.Response)
                .get((submission_id, measure_id)))

            if response is None:
                raise errors.MissingDocError("No such response")

            org = response.submission.organisation
            policy = user_session.policy.derive({
                'org': org,
                'surveygroups': org.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('attachment_view')

            query = (
                session.query(model.Attachment)
                .filter(model.Attachment.response == response))

            to_son = ToSon(
                r'/id$',
                r'/file_name$',
                r'/url$'
            )
            # Don't send internal URLs to client
            to_son_internal = ToSon(
                r'/id$',
                r'/file_name$'
            )

            sons = []
            for attachment in query.all():
                if  measure_id==submeasure_id or str(attachment.submeasure_id) == submeasure_id:
                    assert (attachment.organisation_id == org.id)
                    if attachment.storage == 'external':
                       sons.append(to_son(attachment))
                    else:
                       sons.append(to_son_internal(attachment))


        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 11
0
    def write(self, session, resultset, path, query):
        with open(path, 'w', encoding='utf-8') as f:
            log.debug("Writing result as JSON")

            to_son = ToSon(
                r'/[0-9]+$',
                r'/[0-9]+/[^/]+$',
            )
            f.write('{"cols": %s, "rows": [' %
                    json_encode(to_son(resultset.cols)))

            to_son = ToSon(r'/[0-9]+$', )
            for i, row in enumerate(resultset.rows):
                if i > 0:
                    f.write(', ')
                f.write(json_encode(to_son(row)))
            f.write(']}')
Exemplo n.º 12
0
    def get(self, submission_id, measure_id):
        '''Get a list of versions of a response.'''
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            submission = session.query(model.Submission).get(submission_id)
            if not submission:
                raise errors.MissingDocError("No such submission")

            policy = user_session.policy.derive({
                'org':
                submission.organisation,
                'submission':
                submission,
                'surveygroups':
                submission.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('response_view')

            # Current version
            versions = (session.query(model.Response).filter_by(
                submission_id=submission_id, measure_id=measure_id).all())

            # Other versions
            query = (session.query(model.ResponseHistory).filter_by(
                submission_id=submission_id, measure_id=measure_id).order_by(
                    model.ResponseHistory.version.desc()))
            query = self.paginate(query)

            versions += query.all()

            # Important! If you're going to include the comment field here,
            # make sure it is cleaned first to prevent XSS attacks.
            to_son = ToSon(
                r'/id$',
                r'/name$',
                r'/approval$',
                r'/version$',
                r'/modified$',
                # Descend
                r'/[0-9]+$',
                r'/user$',
                r'/organisation$',
                # The IDs of rnodes and responses are not part of the API
                r'!^/[0-9]+/id$',
            )
            sons = to_son(versions)

            for son, version in zip(sons, versions):
                user = session.query(model.AppUser).get(version.user_id)
                if user is not None:
                    son['user'] = to_son(user)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 13
0
 def get_groups_son(self, session, *group_names):
     surveygroups = (session.query(model.SurveyGroup).filter(
         model.SurveyGroup.title.in_(group_names)).all())
     to_son = ToSon(
         r'/id$',
         r'/title$',
         r'/[0-9]+$',
     )
     return to_son(surveygroups)
Exemplo n.º 14
0
    def get(self, submission_id):
        if submission_id == '':
            self.query()
            return

        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            submission = session.query(model.Submission).get(submission_id)

            if not submission:
                raise errors.MissingDocError("No such submission")

            policy = user_session.policy.derive({
                'org':
                submission.organisation,
                'surveygroups':
                submission.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('submission_view')

            to_son = ToSon(
                # Any
                r'/ob_type$',
                r'/id$',
                r'/title$',
                r'/name$',
                r'</description$',
                r'/approval$',
                r'/created$',
                r'/deleted$',
                r'/n_measures$',
                r'^/error$',
                r'^/survey/error$',
                r'/program/tracking_id$',
                # Nested
                r'/program$',
                r'/program/tracking_id$',
                r'/organisation$',
                r'/survey$',
                r'/survey/structure.*$',
                r'/survey/min_stats_approval$',
                r'/program/hide_aggregate$',
            )
            son = to_son(submission)
            # menu for export asset management show if asset management template exist  src/app/client/report
            # local path "src/app/client/report/" + submission.survey.title + ' Template.xlsx"
            # templateFile = "src/app/client/report/" + submission.survey.title + ' Template.xlsx'
            # local path "app/client/report/" + submission.survey.title + ' Template.xlsx" for develop
            # production path "client/report/" + submission.survey.title + ' Template.xlsx' for deploy
            templateFile = "client/report/" + submission.survey.title + ' Template.xlsx'
            if os.path.isfile(templateFile):
                son["showCreateAssetReport"] = True
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Exemplo n.º 15
0
    def query(self, organisation_id):
        deleted = self.get_argument('deleted', '')
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            org = session.query(model.Organisation).get(organisation_id)
            if not org:
                raise errors.MissingDocError("No such organisation")

            policy = user_session.policy.derive({
                'org':
                org,
                'surveygroups':
                org.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('submission_browse')

            query = (session.query(model.Survey).join(
                model.PurchasedSurvey).filter(
                    model.PurchasedSurvey.organisation_id == organisation_id))

            if deleted:
                deleted = truthy(deleted)
                if deleted:
                    del_filter = ((model.Survey.deleted == True) |
                                  (model.Program.deleted == True))
                else:
                    del_filter = ((model.Survey.deleted == False) &
                                  (model.Program.deleted == False))
                query = query.join(model.Program).filter(del_filter)

            if not policy.check('surveygroup_interact_all'):
                query = filter_surveygroups(session, query,
                                            user_session.user.id,
                                            [model.Program],
                                            [model.program_surveygroup])

            surveys = query.all()

            to_son = ToSon(
                r'/id$',
                r'/title$',
                r'/deleted$',
                r'/n_measures$',
                r'/program/tracking_id$',
                # Descend into list
                r'/[0-9]+$',
                r'/program$')

            sons = to_son(surveys)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 16
0
    def query(self):
        sons = []
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            policy = user_session.policy.derive({})
            policy.verify('org_browse')

            query = session.query(model.Organisation)

            # Filter out orgs that don't share a surveygroup with this user.
            # Admins need access to orgs outside their surveygroups though.
            if not policy.check('admin'):
                query = filter_surveygroups(session, query,
                                            user_session.user.id, [],
                                            [model.organisation_surveygroup])

            # Filter down to just organisations in a particular survey group
            surveygroup_id = self.get_argument("surveyGroupId", None)
            if surveygroup_id:
                query = (query.join(
                    model.SurveyGroup, model.Organisation.surveygroups).filter(
                        model.SurveyGroup.id == surveygroup_id))

            term = self.get_argument('term', None)
            if term is not None:
                query = query.filter(
                    model.Organisation.name.ilike(r'%{}%'.format(term)))

            deleted = self.get_argument('deleted', '')
            if deleted != '':
                deleted = truthy(deleted)
                query = query.filter(model.Organisation.deleted == deleted)

            query = query.order_by(model.Organisation.name)
            query = self.paginate(query)

            to_son = ToSon(
                r'^/[0-9]+/id$',
                r'/name$',
                r'/deleted$',
                r'/locations$',
                r'/locations/0/description$',
                r'/meta$',
                r'/meta/asset_types.*$',
                # Descend into list
                r'/[0-9]+$')
            sons = to_son(query.all())
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 17
0
    def get(self, query_id):
        if not query_id:
            self.query()
            return

        version = self.get_argument('version', '')

        with model.session_scope() as session:
            custom_query = session.query(model.CustomQuery).get(query_id)
            if custom_query is None:
                raise errors.MissingDocError("No such query")

            user_session = self.get_user_session(session)
            policy = user_session.policy.derive({
                'custom_query': custom_query,
            })
            policy.verify('custom_query_view')

            old_version = self.get_version(session, custom_query, version)

            to_son = ToSon(
                r'/id$',
                r'/deleted$',
                r'/modified$',
                r'/latest_modified$',
                r'/user$',
                r'/title$',
                r'</description$',
                r'/name$',
                r'/text$',
                r'/version$',
            )

            if not old_version:
                son = to_son(custom_query)
            else:
                son = to_son(old_version)
                user = session.query(model.AppUser).get(old_version.user_id)
                if user:
                    son.user = to_son(user)

            # Always include the mtime of the most recent version. This is used
            # to avoid edit conflicts.
            dummy_relations = {
                'latest_modified': custom_query.modified,
            }
            son.update(to_son(dummy_relations))

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Exemplo n.º 18
0
    def get(self, program_id):
        '''
        Get a list of programs that share the same lineage.
        '''
        if program_id == '':
            raise errors.MethodError("Program ID is required")

        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            program = session.query(model.Program).get(program_id)
            if not program:
                raise errors.MissingDocError("No such program")

            policy = user_session.policy.derive({
                'program':
                program,
                'surveygroups':
                program.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('program_view')

            query = (session.query(model.Program).filter(
                model.Program.tracking_id == program.tracking_id).order_by(
                    model.Program.created))

            if not policy.check('surveygroup_interact_all'):
                query = filter_surveygroups(session, query,
                                            user_session.user.id, [],
                                            [model.program_surveygroup])

            deleted = self.get_argument('deleted', '')
            if deleted != '':
                deleted = truthy(deleted)
                query = query.filter(model.Program.deleted == deleted)

            to_son = ToSon(
                r'/id$',
                r'/title$',
                r'/is_editable$',
                r'/deleted$',
                # Descend
                r'/[0-9]+$',
            )
            sons = to_son(query.all())

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 19
0
    def query(self):
        '''
        Get a list of programs.
        '''

        term = self.get_argument('term', '')
        is_editable = truthy(self.get_argument('editable', ''))

        sons = []
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            query = session.query(model.Program)

            policy = user_session.policy.derive({})
            if not policy.check('surveygroup_interact_all'):
                query = filter_surveygroups(session, query,
                                            user_session.user.id, [],
                                            [model.program_surveygroup])

            # Get all programs for a survey group
            surveygroup_id = self.get_argument("surveyGroupId", None)
            if surveygroup_id:
                query = (query.join(
                    model.SurveyGroup, model.Program.surveygroups).filter(
                        model.SurveyGroup.id == surveygroup_id))

            if term != '':
                query = query.filter(
                    model.Program.title.ilike(r'%{}%'.format(term)))

            if is_editable:
                query = query.filter(model.Program.finalised_date == None)

            deleted = self.get_argument('deleted', '')
            if deleted != '':
                deleted = truthy(deleted)
                query = query.filter(model.Program.deleted == deleted)

            query = query.order_by(model.Program.created.desc())
            query = self.paginate(query)

            to_son = ToSon(r'/id$', r'/title$', r'</description$',
                           r'/deleted$', r'^/[0-9]+/error$', r'/[0-9]+$')
            sons = to_son(query.all())

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 20
0
    def get(self):
        with model.session_scope() as session:
            user_session = self.get_user_session(session)
            policy = user_session.policy.derive({})
            policy.verify('custom_query_view')

            to_son = ToSon(r'.*')
            self.set_header("Content-Type", "application/json")

            wall_time = config.get_setting(session, 'custom_timeout') * 1000
            max_limit = config.get_setting(session, 'custom_max_limit')
            conf = {'wall_time': wall_time, 'max_limit': max_limit}

        self.write(json_encode(to_son(conf)))
        self.finish()
Exemplo n.º 21
0
    def get(self, survey_id):

        if not survey_id:
            self.query()
            return

        program_id = self.get_argument('programId', '')

        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            survey = (session.query(model.Survey).options(
                joinedload('program.surveygroups')).get(
                    (survey_id, program_id)))
            if not survey:
                raise errors.MissingDocError("No such survey")

            policy = user_session.policy.derive({
                'survey':
                survey,
                'surveygroups':
                survey.program.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('survey_view')

            to_son = ToSon(
                # Any
                r'/ob_type$',
                r'/id$',
                r'/title$',
                r'/seq$',
                r'/created$',
                r'/deleted$',
                r'/is_editable$',
                r'/n_measures$',
                r'^/error$',
                r'/program/tracking_id$',
                # Root-only
                r'<^/description$',
                r'^/structure.*',
                # Nested
                r'/program$',
            )
            son = to_son(survey)
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Exemplo n.º 22
0
    def test_modify_user(self):
        with model.session_scope() as session:
            # TODO: Refactor this to make it reusable.
            user = (session.query(
                model.AppUser).filter(model.AppUser.email == 'clerk').one())

            to_son = ToSon(
                r'/id$',
                r'/title$',
                r'/name$',
                r'/surveygroups$',
                r'/organisation$',
                r'/[0-9]+$',
                # Exclude password
                r'!/password$',
            )
            user_son = to_son(user)

        users = [('consultant', 403, "are not the owner"),
                 ('authority', 403, "are not the owner"),
                 ('author', 403, "are not the owner"), ('clerk', 200, 'OK'),
                 ('org_admin', 200, 'OK'), ('admin', 200, 'OK')]

        for user_email, code, reason in users:
            post_data = user_son.copy()
            post_data['organisation'] = post_data['organisation'].copy()
            with base.mock_user(user_email):
                response = self.fetch("/user/%s.json" % user_son['id'],
                                      method='PUT',
                                      body=json_encode(post_data))
                self.assertIn(reason, response.reason, msg=user_email)
                self.assertEqual(code, response.code, msg=user_email)

        users = [
            ('clerk', 403, "can't add that user"),
            ('org_admin', 200, 'OK'),
        ]

        for user_email, code, reason in users:
            post_data = user_son.copy()
            post_data['organisation'] = post_data['organisation'].copy()
            post_data['deleted'] = True
            with base.mock_user(user_email):
                response = self.fetch("/user/%s.json" % user_son['id'],
                                      method='PUT',
                                      body=json_encode(post_data))
                self.assertIn(reason, response.reason, msg=user_email)
                self.assertEqual(code, response.code, msg=user_email)
Exemplo n.º 23
0
    def query(self):
        with model.session_scope() as session:
            user_session = self.get_user_session(session)
            policy = user_session.policy.derive({})
            policy.verify('custom_query_browse')

            query = session.query(model.CustomQuery)

            term = self.get_argument('term', None)
            if term is not None:
                query = query.filter(
                    model.CustomQuery.title.ilike(r'%{}%'.format(term)))

            deleted = self.get_argument('deleted', '')
            if deleted != '':
                deleted = truthy(deleted)
                query = query.filter(model.CustomQuery.deleted == deleted)

            order_by = self.get_argument('order', 'title')
            if order_by == 'title':
                order_field = model.CustomQuery.title
            elif order_by == 'modified':
                order_field = model.CustomQuery.modified
            else:
                order_field = None

            if order_field:
                if self.get_argument('desc', ''):
                    order_field = order_field.desc()
                query = query.order_by(order_field)

            query = self.paginate(query)

            to_son = ToSon(
                r'^/[0-9]+/id$',
                r'/deleted$',
                r'/title$',
                r'/description$',
                r'/modified$',
                # Descend into list
                r'/[0-9]+$',
            )
            sons = to_son(query.all())
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 24
0
    def query(self, ob_type, object_ids):
        with model.session_scope() as session:
            ob = get_ob(session, ob_type, object_ids)
            if not ob:
                raise errors.MissingDocError("No such object")

            user_session = self.get_user_session(session)
            act = Activities(session)
            subscription_map = {
                tuple(sub.ob_refs): sub.subscribed
                for sub in act.subscriptions(user_session.user, ob)
            }
            subscription_id_map = {
                tuple(sub.ob_refs): sub.id
                for sub in act.subscriptions(user_session.user, ob)
            }

            lineage = [{
                'id':
                subscription_id_map.get(tuple(item.ob_ids), None),
                'title':
                item.ob_title,
                'ob_type':
                item.ob_type,
                'ob_ids':
                item.ob_ids,
                'subscribed':
                subscription_map.get(tuple(item.ob_ids), None)
            } for item in ob.action_lineage]

            to_son = ToSon(
                r'/id$',
                r'/title$',
                r'/subscribed$',
                r'/ob_type$',
                r'/ob_ids/?.*$',
                r'/[0-9]+$',
            )
            sons = to_son(lineage)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 25
0
    def get(self, entity_id):
        '''
        Get a list of programs that some entity belongs to. For example,
        a single survey may be present in multiple programs.
        '''
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            query = (session.query(model.Program).join(self.mapper).filter(
                self.mapper.id == entity_id).order_by(model.Program.created))

            policy = user_session.policy.derive({})
            if not policy.check('surveygroup_interact_all'):
                query = filter_surveygroups(session, query,
                                            user_session.user.id, [],
                                            [model.program_surveygroup])

            deleted = self.get_argument('deleted', '')
            if deleted != '':
                deleted = truthy(deleted)
                query = query.filter(model.Program.deleted == deleted)

            programs = [
                program for program in query.all()
                if user_session.policy.derive({
                    'program': program,
                }).check('program_view')
            ]

            to_son = ToSon(
                r'/id$',
                r'/title$',
                r'/is_editable$',
                r'/created$',
                r'/deleted$',
                # Descend
                r'/[0-9]+$',
            )
            sons = to_son(programs)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()
Exemplo n.º 26
0
    def get(self, program_id):
        '''
        Get a single program.
        '''
        if program_id == "":
            self.query()
            return

        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            program = (session.query(model.Program).options(
                joinedload('surveygroups')).get(program_id))
            if not program:
                raise errors.MissingDocError("No such program")

            policy = user_session.policy.derive({
                'program':
                program,
                'surveygroups':
                program.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('program_view')

            to_son = ToSon(
                r'/ob_type$',
                r'/id$',
                r'/tracking_id$',
                r'/title$',
                r'</description$',
                r'/created$',
                r'/deleted$',
                r'/is_editable$',
                r'^/error$',
                r'/has_quality$',
                r'/hide_aggregate$',
                r'/[0-9+]$',
            )
            if policy.check('surveygroup_browse'):
                to_son.add(r'^/surveygroups$')
            if not policy.check('author'):
                to_son.exclude(
                    r'/response_types.*score$',
                    r'/response_types.*formula$',
                )
            son = to_son(program)
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Exemplo n.º 27
0
    def get(self):
        with model.session_scope() as session:
            user_session = self.get_user_session(session)
            user_session.policy.verify('conf_view')

            settings = {}
            for name, schema in config.SCHEMA.items():
                if config.is_private(name, schema):
                    continue

                s = schema.copy()
                s['name'] = to_camel_case(name)
                if 'default_file_path' in s:
                    del s['default_file_path']

                s['value'] = config.get_setting(session, name)
                settings[name] = s
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(ToSon()(settings)))
        self.finish()
Exemplo n.º 28
0
    def test_son_iter(self):

        input = TestNode(id_col=uuid.uuid4(),
                         int_col=1,
                         bool_col=True,
                         string_col="foo",
                         float_col=0.5,
                         date_col=datetime.date(2015, 1, 1))
        input.parent = TestNode(int_col=2, string_col="bar")
        input.parent.parent = TestNode(int_col=3, string_col="baz")

        output = {
            'intCol': 1,
            'stringCol': "foo",
            'parent': {
                'intCol': 2,
                'stringCol': "bar",
                'parent': {
                    'intCol': 3,
                    'stringCol': "baz"
                }
            }
        }
        outputs = [item for item in itertools.repeat(output, 3)]

        to_son = ToSon(
            # Fields to match in any visisted object
            r'/int_col$',
            r'/string_col$',
            # Descend into nested objects
            r'/[0-9]+$',
            r'/parent$',
            omit=True)

        # List iteration
        inputs = [item for item in itertools.repeat(input, 3)]
        self.assertEqual(outputs, to_son(inputs))

        # Generator iteration
        inputs = (item for item in itertools.repeat(input, 3))
        self.assertEqual(outputs, to_son(inputs))
Exemplo n.º 29
0
    def get(self, organisation_id):
        if organisation_id == "":
            self.query()
            return

        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            org = (session.query(model.Organisation).options(
                joinedload('surveygroups')).get(organisation_id))
            if not org:
                raise errors.MissingDocError("No such organisation")

            policy = user_session.policy.derive({
                'org':
                org,
                'surveygroups':
                org.surveygroups,
            })
            policy.verify('org_view')

            # Check that user shares a common surveygroup with this org.
            # Admins need access to orgs outside their surveygroups though.
            if not policy.check('admin'):
                policy.verify('surveygroup_interact')

            to_son = ToSon(
                r'/id$',
                r'/name$',
                r'/title$',
                r'/deleted$',
                r'/url$',
                r'/locations.*$',
                r'/meta.*$',
                r'/[0-9+]$',
            )
            to_son.exclude(
                r'/locations/.*/organisation(_id)?$',
                r'/locations/.*/id$',
                r'/meta/organisation(_id)?$',
                r'/meta/id$',
            )
            if policy.check('surveygroup_browse'):
                to_son.add(r'^/surveygroups$')
            son = to_son(org)
        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Exemplo n.º 30
0
    def get(self):
        sons = []
        to_son = ToSon(r'.*')
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            org = user_session.org
            sons.append(
                to_son({
                    'title': org.name,
                    'created': org.created,
                    'ob_type': 'organisation',
                    'ob_ids': [org.id],
                }))

            if user_session.policy.check('author', 'consultant'):
                programs = (session.query(model.Program).filter(
                    model.Program.finalised_date == None).order_by(
                        model.Program.created.desc()).limit(2).all())
                sons += to_son([{
                    'title': s.title,
                    'created': s.created,
                    'ob_type': 'program',
                    'ob_ids': [s.id],
                } for s in programs])

            if user_session.policy.check('clerk'):
                submissions = (session.query(model.Submission).filter(
                    model.Submission.organisation_id == org.id).order_by(
                        model.Submission.created.desc()).limit(2).all())
                sons += to_son([{
                    'title': a.title,
                    'created': a.created,
                    'ob_type': 'submission',
                    'ob_ids': [a.id],
                } for a in submissions])

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(sons))
        self.finish()