Esempio n. 1
0
    def delete(self, program_id):
        '''
        Delete an existing program.
        '''
        if not program_id:
            raise errors.MethodError("Program ID 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_del')

            act = Activities(session)
            if not program.deleted:
                act.record(user_session.user, program, ['delete'])
            act.ensure_subscription(user_session.user, program, program,
                                    self.reason)

            program.deleted = True

        self.finish()
Esempio n. 2
0
    def post(self, query_id):
        if query_id:
            raise errors.MethodError("Can't use POST for existing query.")

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

            custom_query = model.CustomQuery()
            self.update(custom_query, self.request_son)
            self.update_auto(custom_query, user_session.user)
            session.add(custom_query)

            policy = user_session.policy.derive({
                'custom_query': custom_query,
            })
            policy.verify('custom_query_add')

            session.flush()
            act = Activities(session)
            act.record(user_session.user, custom_query, ['create'])
            act.ensure_subscription(user_session.user, custom_query,
                                    custom_query, self.reason)

            query_id = str(custom_query.id)

        self.get(query_id)
Esempio n. 3
0
    def delete(self, user_id):
        if not user_id:
            raise errors.MethodError("User ID required")

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

            user = session.query(model.AppUser).get(user_id)
            if not user:
                raise errors.MissingDocError("No such user")

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

            act = Activities(session)
            if not user.deleted:
                act.record(user_session.user, user, ['delete'])
            act.ensure_subscription(
                user_session.user, user, user.organisation, self.reason)

            user.deleted = True

        self.finish()
Esempio n. 4
0
    def delete(self, organisation_id):
        if not organisation_id:
            raise errors.MethodError("Organisation ID required")

        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('org_del')

            act = Activities(session)
            if not org.deleted:
                act.record(user_session.user, org, ['delete'])
            act.ensure_subscription(user_session.user, org, org, self.reason)

            org.deleted = True

        self.finish()
Esempio n. 5
0
    def delete(self, submission_id):
        if submission_id == '':
            raise errors.MethodError("Submission ID required")

        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_del')

            act = Activities(session)
            if not submission.deleted:
                act.record(user_session.user, submission, ['delete'])
            act.ensure_subscription(user_session.user, submission,
                                    submission.organisation, self.reason)

            submission.deleted = True

        self.finish()
Esempio n. 6
0
    def put(self, survey_id):
        '''Update existing.'''
        if not survey_id:
            raise errors.MethodError("Survey ID required")

        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')).options(
                    joinedload('program.surveygroups')).get(
                        (survey_id, program_id)))
            if not survey:
                raise errors.MissingDocError("No such survey")

            ## set only last level indexing_form 1 if no value, remove other level indexing_form
            levels = len(self.request_son.structure.levels)

            for i, l in enumerate(self.request_son.structure.levels):
                if i + 1 != levels and l.indexing_from:
                    del l.indexing_from
                if i + 1 == levels and (
                    (not l.indexing_from and l.indexing_from != 0) or
                    (not isinstance(l.indexing_from, Number))
                        or l.indexing_from < 0):
                    l.indexing_from = 1

            self._update(survey, self.request_son)

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

            verbs = []
            if session.is_modified(survey):
                verbs.append('update')

            if survey.deleted:
                survey.deleted = False
                verbs.append('undelete')

            act = Activities(session)
            act.record(user_session.user, survey, verbs)
            act.ensure_subscription(user_session.user, survey, survey.program,
                                    self.reason)

        self.get(survey_id)
Esempio n. 7
0
    def post(self, user_id):
        '''
        Create a new user.
        '''
        if user_id:
            raise errors.MethodError("Can't use POST for existing users.")

        try:
            user_input_schema(self.request_son)
        except voluptuous.error.Invalid as e:
            raise errors.ModelError.from_voluptuous(e)

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

            org = (
                session.query(model.Organisation)
                .get(self.request_son['organisation']['id']))
            if not org:
                raise errors.ModelError("No such organisation")

            user = model.AppUser(organisation=org)

            try:
                assign_surveygroups(user_session, user, self.request_son)
            except ValueError as e:
                raise errors.ModelError(str(e))

            policy = user_session.policy.derive({
                'org': user.organisation,
                'user': user,
                'target': self.request_son,
                'surveygroups': user.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('user_add')
            policy.verify('user_change_role')
            self.check_password(self.request_son.password)

            self._update(user, self.request_son, session)
            session.add(user)

            # Need to flush so object has an ID to record action against.
            session.flush()

            act = Activities(session)
            act.record(user_session.user, user, ['create'])
            act.ensure_subscription(
                user_session.user, user, user.organisation, self.reason)
            act.subscribe(user, user.organisation)
            self.reason("New user subscribed to organisation")

            user_id = user.id
        self.get(user_id)
Esempio n. 8
0
    def post(self, survey_id):
        '''Create new.'''
        if survey_id:
            raise errors.MethodError("Can't use POST for existing object")

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

        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.ModelError("No such program")

            ## set only last level indexing_form 1 if no value, remove other level indexing_form
            levels = len(self.request_son.structure.levels)

            for i, l in enumerate(self.request_son.structure.levels):
                if i + 1 != levels and l.indexing_from:
                    del l.indexing_from
                if i + 1 == levels and (
                    (not l.indexing_from and l.indexing_from != 0) or
                    (not isinstance(l.indexing_from, Number))
                        or l.indexing_from < 0):
                    l.indexing_from = 1

            survey = model.Survey(program=program)
            self._update(survey, self.request_son)
            session.add(survey)

            # Need to flush so object has an ID to record action against.
            session.flush()

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

            act = Activities(session)
            act.record(user_session.user, survey, ['create'])
            act.ensure_subscription(user_session.user, survey, survey.program,
                                    self.reason)

            survey_id = str(survey.id)

        self.get(survey_id)
Esempio n. 9
0
    def put(self, organisation_id):
        '''
        Update an existing organisation.
        '''
        if not organisation_id:
            raise errors.MethodError(
                "Can't use PUT for new organisations (no ID).")

        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")

            try:
                groups_changed = assign_surveygroups(user_session, org,
                                                     self.request_son)
            except ValueError as e:
                raise errors.ModelError(str(e))

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

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

            old_locations = list(org.locations)
            self._update(org, self.request_son)

            verbs = []
            if (session.is_modified(org) or org.locations != old_locations
                    or groups_changed or session.is_modified(org.meta)):
                verbs.append('update')

            if org.deleted:
                org.deleted = False
                verbs.append('undelete')

            act = Activities(session)
            act.record(user_session.user, org, verbs)
            act.ensure_subscription(user_session.user, org, org, self.reason)

        self.get(organisation_id)
Esempio n. 10
0
    def filter(self, request, response):
        is_valid = self.options.methods_validator.is_valid(
            request.request_method)

        allow_methods = self.options.methods_value

        if not is_valid:
            response.allow_methods = allow_methods
            return errors.MethodError(request.request_method)

        if not allow_methods:
            allow_methods = [request.request_method]
        response.allow_methods = allow_methods
Esempio n. 11
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()
Esempio n. 12
0
    def delete(self, qnode_id):
        '''Delete existing.'''

        if not qnode_id:
            raise errors.MethodError("Question node ID required")

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

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

            qnode = (
                session.query(model.QuestionNode)
                .options(joinedload('program'))
                .options(joinedload('program.surveygroups'))
                .get((qnode_id, program_id)))
            if not qnode:
                raise errors.MissingDocError("No such question node")
            log.debug("deleting: %s", qnode)

            program = qnode.program
            survey = qnode.survey
            parent = qnode.parent

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

            act = Activities(session)
            if not qnode.deleted:
                act.record(user_session.user, qnode, ['delete'])
            act.ensure_subscription(
                user_session.user, qnode, qnode.program, self.reason)

            qnode.deleted = True

            calculator = Calculator.structural()
            if parent:
                parent.children.reorder()
                calculator.mark_qnode_dirty(parent)
            else:
                survey.qnodes.reorder()
                calculator.mark_survey_dirty(survey)
            calculator.execute()

        self.finish()
Esempio n. 13
0
def reorder(collection, son, id_attr='id'):
    '''
    Update the order of items in an `ordering_list` according to a serialised
    list.
    '''
    current = {str(getattr(m, id_attr)): m.seq for m in collection}
    proposed = {m['id']: m['seq'] for m in son}
    if current != proposed:
        raise errors.MethodError(
            "The proposed changes are not compatible with the "
            "current sequence: items have been added or removed, or another "
            "user has changed the order too. Try reloading the list.")

    order = {m['id']: i for i, m in enumerate(son)}
    collection.sort(key=lambda m: order[str(getattr(m, id_attr))])
    collection.reorder()
Esempio n. 14
0
    def put(self, query_id):
        if not query_id:
            raise errors.MethodError("Can't use PUT for new query.")

        with model.session_scope(version=True) 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_edit')

            self.check_concurrent_write(custom_query)
            if not self.should_save_new_version(custom_query,
                                                user_session.user):
                custom_query.version_on_update = False

            self.update(custom_query, self.request_son)

            verbs = []
            if session.is_modified(custom_query):
                verbs.append('update')
                self.update_auto(custom_query, user_session.user)
            else:
                custom_query.version_on_update = False

            if custom_query.deleted:
                custom_query.deleted = False
                verbs.append('undelete')

            session.flush()
            act = Activities(session)
            act.record(user_session.user, custom_query, verbs)
            act.ensure_subscription(user_session.user, custom_query,
                                    custom_query, self.reason)

            query_id = str(custom_query.id)

        self.get(query_id)
Esempio n. 15
0
    def post(self, organisation_id):
        '''
        Create a new organisation.
        '''
        if organisation_id:
            raise errors.MethodError(
                "Can't use POST for existing organisation.")

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

            org = model.Organisation()

            try:
                assign_surveygroups(user_session, org, self.request_son)
            except ValueError as e:
                raise errors.ModelError(str(e))

            self._update(org, self.request_son)
            session.add(org)

            # Need to flush so object has an ID to record action against.
            session.flush()

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

            act = Activities(session)
            act.record(user_session.user, org, ['create'])
            act.ensure_subscription(user_session.user, org, org, self.reason)

            organisation_id = str(org.id)
        self.get(organisation_id)
Esempio n. 16
0
    def delete(self, survey_id):
        if not survey_id:
            raise errors.MethodError("Survey ID required")

        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')).options(
                    joinedload('program.surveygroups')).get(
                        (survey_id, program_id)))
            if not survey:
                raise errors.MissingDocError("No such survey")

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

            act = Activities(session)
            if not survey.deleted:
                act.record(user_session.user, survey, ['delete'])
            act.ensure_subscription(user_session.user, survey, survey.program,
                                    self.reason)

            survey.deleted = True

        self.finish()
Esempio n. 17
0
    def delete(self, query_id):
        if not query_id:
            raise errors.MethodError("Query ID required")

        with model.session_scope(version=False) 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_del')

            act = Activities(session)
            if not custom_query.deleted:
                act.record(user_session.user, custom_query, ['delete'])
            act.ensure_subscription(user_session.user, custom_query,
                                    custom_query, self.reason)

            custom_query.deleted = True

        self.get(query_id)
Esempio n. 18
0
    def put(self, submission_id):
        '''Update existing.'''
        if submission_id == '':
            raise errors.MethodError("Submission ID required")

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

        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,
                'approval':
                approval,
                'surveygroups':
                submission.surveygroups,
            })
            policy.verify('surveygroup_interact')
            policy.verify('submission_edit')

            current_level = 0
            verbs = []
            if approval:
                self.check_approval_down_one(session, submission, approval)
                current_level = APPROVAL_STATES.index(submission.approval)
                if approval != submission.approval:
                    verbs.append('state')
                submission.approval = approval
            self._update(submission, self.request_son)
            if session.is_modified(submission):
                verbs.append('update')

            # update measures approval state, when save edited submission no approval, so here should not
            if approval != '':
                approval_level = APPROVAL_STATES.index(approval)
                if 'state' in verbs and approval_level > current_level:
                    approval_level = approval_level - 1
                    responses = (session.query(model.Response).filter(
                        model.Response.submission_id == submission.id,
                        model.Response.approval ==
                        APPROVAL_STATES[approval_level]))
                    for response in responses:
                        # update = updater(response, error_factory=errors.ModelError)
                        # update('title', son)
                        response.approval = approval
                        try:
                            calculator = Calculator.scoring(submission)
                            calculator.mark_measure_dirty(
                                response.qnode_measure)
                            calculator.execute()
                        except ResponseTypeError as e:
                            raise errors.ModelError(str(e))

                        act = Activities(session)
                        act.record(user_session.user, response, verbs)
                        act.ensure_subscription(user_session.user, response,
                                                response.submission,
                                                self.reason)

            if submission.deleted:
                submission.deleted = False
                verbs.append('undelete')

            act = Activities(session)
            act.record(user_session.user, submission, verbs)
            act.ensure_subscription(user_session.user, submission,
                                    submission.organisation, self.reason)

        self.get(submission_id)
Esempio n. 19
0
    def post(self, submission_id):
        '''Create new.'''
        if submission_id:
            raise errors.MethodError("Can't use POST for existing object")

        program_id = self.get_argument('programId', '')
        if not program_id:
            raise errors.ModelError("Program ID is required")

        survey_id = self.get_argument('surveyId', '')
        if not survey_id:
            raise errors.ModelError("Survey ID is required")

        organisation_id = self.get_argument('organisationId', '')
        if not organisation_id:
            raise errors.ModelError("Organisation ID is required")

        # Source submission ID
        duplicate_id = self.get_argument('duplicateId', '')

        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.ModelError("No such organisation")

            survey = session.query(model.Survey).get((survey_id, program_id))
            if not survey:
                raise errors.ModelError("No such survey")

            if duplicate_id:
                source_submission = (session.query(
                    model.Submission).get(duplicate_id))
                if not source_submission:
                    raise errors.MissingDocError(
                        "Source submission (for duplication) not found")
                if source_submission.organisation != org:
                    raise errors.ModelError(
                        "Can't duplicate a submission across two "
                        "organisations: '%s' and '%s'" %
                        (source_submission.organisation.name, org.name))
            else:
                source_submission = None

            submission = model.Submission(program=survey.program,
                                          survey=survey,
                                          organisation=org,
                                          approval='draft')
            self._update(submission, self.request_son)
            session.add(submission)

            surveygroups = submission.surveygroups
            if source_submission:
                surveygroups &= source_submission.surveygroups

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

            session.flush()
            submission_id = str(submission.id)

            if source_submission:
                yield SubmissionHandler.executor.submit(
                    self.duplicate, submission, source_submission, session)

            act = Activities(session)
            act.record(user_session.user, submission, ['create'])
            act.ensure_subscription(user_session.user, submission,
                                    submission.organisation, self.reason)

        self.get(submission_id)
Esempio n. 20
0
    def put(self, user_id):
        '''
        Update an existing user.
        '''
        if not user_id:
            raise errors.MethodError("Can't use PUT for new users (no ID).")

        try:
            user_input_schema(self.request_son)
        except voluptuous.error.Invalid as e:
            raise errors.ModelError.from_voluptuous(e)

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

            user = session.query(model.AppUser).get(user_id)
            if not user:
                raise errors.MissingDocError("No such user")

            try:
                groups_changed = assign_surveygroups(
                    user_session, user, self.request_son)
            except ValueError as e:
                raise errors.ModelError(str(e))

            policy = user_session.policy.derive({
                'org': user.organisation,
                'user': user,
                'target': self.request_son,
                'surveygroups': user.surveygroups,
            })
            policy.verify('user_edit')

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

            if self.request_son.role and self.request_son.role != user.role:
                policy.verify('user_change_role')

            if ('deleted' in self.request_son and
                    self.request_son['deleted'] != user.deleted):
                policy.verify('user_enable')

            if self.request_son.get('password'):
                self.check_password(self.request_son.password)

            verbs = []
            oid = self.request_son.organisation.id
            if oid != str(user.organisation_id):
                policy.verify('user_change_org')
                verbs.append('relation')

            self._update(user, self.request_son, session)

            act = Activities(session)
            if session.is_modified(user) or groups_changed:
                verbs.append('update')

            if user.deleted:
                user.deleted = False
                verbs.append('undelete')

            session.flush()
            if len(verbs) > 0:
                act.record(user_session.user, user, verbs)
                act.ensure_subscription(
                    user_session.user, user, user.organisation, self.reason)
                if not act.has_subscription(user, user):
                    act.subscribe(user, user.organisation)
                    self.reason("User subscribed to organisation")

        self.get(user_id)
Esempio n. 21
0
    def get(self, activity_id):
        if not activity_id:
            yield self.query()

        raise errors.MethodError("GET for single activity is not implemented")
Esempio n. 22
0
    def post(self, qnode_id):
        '''Create new.'''

        if qnode_id:
            raise errors.MethodError("Can't use POST for existing object")

        program_id = self.get_argument('programId', '')
        survey_id = self.get_argument('surveyId', '')
        parent_id = self.get_argument('parentId', '')

        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.ModelError("No such program")

            qnode = model.QuestionNode(program=program)
            self._update(session, qnode, self.request_son)
            log.debug("new: %s", qnode)

            if survey_id:
                survey = (
                    session.query(model.Survey)
                    .get((survey_id, program_id)))
                if not survey:
                    raise errors.ModelError("No such survey")
            else:
                survey = None
            log.debug("survey: %s", survey)

            if parent_id:
                parent = (
                    session.query(model.QuestionNode)
                    .get((parent_id, program_id)))
                if not parent:
                    raise errors.ModelError("Parent does not exist")
                if not survey:
                    survey = parent.survey
                elif parent.survey != survey:
                    raise errors.ModelError(
                        "Parent does not belong to that survey")
            else:
                parent = None

            qnode.survey = survey

            if parent:
                log.debug("Appending to parent")
                parent.children.append(qnode)
                parent.children.reorder()
                log.debug("committing: %s", parent.children)
            elif survey:
                log.debug("Appending to survey")
                survey.qnodes.append(qnode)
                survey.qnodes.reorder()
                log.debug("committing: %s", survey.qnodes)
            else:
                raise errors.ModelError("Parent or survey ID required")

            # Need to flush so object has an ID to record action against.
            session.flush()

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

            calculator = Calculator.structural()
            calculator.mark_qnode_dirty(qnode)
            calculator.execute()

            qnode_id = str(qnode.id)

            act = Activities(session)
            act.record(user_session.user, qnode, ['create'])
            act.ensure_subscription(
                user_session.user, qnode, qnode.program, self.reason)

        self.get(qnode_id)
Esempio n. 23
0
    def put(self, program_id):
        '''
        Update an existing program.
        '''
        if program_id == '':
            raise errors.MethodError("Can't use PUT for new program (no ID).")

        editable = self.get_argument('editable', '')
        if editable != '':
            self._update_state(program_id, truthy(editable))
            return

        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")

            try:
                groups_changed = assign_surveygroups(user_session, program,
                                                     self.request_son)
            except ValueError as e:
                raise errors.ModelError(str(e))

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

            if not program.is_editable:
                raise errors.MethodError("This program is closed for editing")

            calculator = Calculator.structural()
            if self.request_son['has_quality'] != program.has_quality:
                # Recalculate stats for surveys. This will trigger the
                # recalculation of the submissions in the recalculation
                # daemon.
                for survey in program.surveys:
                    calculator.mark_survey_dirty(survey)

            self._update(program, self.request_son)

            calculator.execute()

            verbs = []
            if session.is_modified(program) or groups_changed:
                verbs.append('update')

            if program.deleted:
                program.deleted = False
                verbs.append('undelete')

            act = Activities(session)
            act.record(user_session.user, program, verbs)
            act.ensure_subscription(user_session.user, program, program,
                                    self.reason)
        self.get(program_id)
Esempio n. 24
0
    def post(self, program_id):
        '''
        Create a new program.
        '''
        if program_id:
            raise errors.MethodError("Can't use POST for existing program.")

        duplicate_id = self.get_argument('duplicateId', '')

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

            program = model.Program()
            self._update(program, self.request_son)
            session.add(program)

            try:
                assign_surveygroups(user_session, program, self.request_son)
            except ValueError as e:
                raise errors.ModelError(str(e))

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

            # Need to flush so object has an ID to record action against.
            session.flush()

            act = Activities(session)

            if duplicate_id:
                source_program = (session.query(
                    model.Program).get(duplicate_id))
                if not source_program:
                    raise errors.MissingDocError(
                        "Source program does not exist")

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

                yield self.duplicate_structure(source_program, program,
                                               session)
                source_program.finalised_date = datetime.datetime.utcnow()
                act.record(user_session.user, source_program, ['state'])

            act.record(user_session.user, program, ['create'])
            act.ensure_subscription(user_session.user, program, program,
                                    self.reason)

            program_id = program.id

        self.get(program_id)