Beispiel #1
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)
Beispiel #2
0
    def put(self, activity_id):
        with model.session_scope() as session:
            user_session = self.get_user_session(session)

            activity = (session.query(model.Activity).get(activity_id))
            if not activity:
                raise errors.MissingDocError("No such activity")

            if 'surveygroups' in self.request_son:
                try:
                    assign_surveygroups(user_session, activity,
                                        self.request_son)
                except ValueError as e:
                    raise errors.ModelError(str(e))

            if activity.ob_type == 'organisation':
                org = get_ob(activity.ob_type, activity.ob_ids)
                policy = user_session.policy.derive({
                    'activity':
                    activity,
                    'org':
                    org,
                    'surveygroups':
                    org.surveygroups,
                })
            elif not activity.ob_type:
                policy = user_session.policy.derive({
                    'activity':
                    activity,
                    'surveygroups':
                    activity.surveygroups,
                })
            else:
                raise errors.ModelError("That activity can't be modified")

            policy.verify('surveygroup_interact')

            if 'sticky' in self.request_son:
                if self.request_son.sticky != activity.sticky:
                    policy.verify('post_pin')
                    activity.sticky = self.request_son.sticky

            if 'message' in self.request_son:
                if self.request_son.message != activity.message:
                    policy.verify('post_edit')
                    activity.message = self.request_son.message

            son = ActivityHandler.TO_SON(activity)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Beispiel #3
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)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
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)
Beispiel #7
0
    def post(self, activity_id):
        if activity_id:
            raise errors.ModelError("Can't specify ID for new activity")

        if len(self.request_son.message) < 3:
            raise errors.ModelError("Message is too short")

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

            if self.request_son.to == 'org':
                org = user_session.org
                if not org:
                    raise errors.ModelError('No such organisation')
            elif self.request_son.to == 'all':
                org = None
            else:
                raise errors.ModelError('Unrecognised recipient')

            activity = model.Activity(
                subject=user_session.user,
                verbs=['broadcast'],
                message=self.request_son.message,
                sticky=self.request_son.sticky,
            )

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

            if org:
                desc = org.action_descriptor
                activity.ob_type = desc.ob_type
                activity.ob_ids = desc.ob_ids
                activity.ob_refs = desc.ob_refs
                policy = user_session.policy.derive({
                    'surveygroups':
                    org.surveygroups,
                })
                policy.verify('surveygroup_interact')
            else:
                activity.ob_type = None
                activity.ob_ids = []
                activity.ob_refs = []

            session.add(activity)
            session.flush()

            policy = user_session.policy.derive({
                'activity': activity,
                'org': org,
            })
            policy.verify('post_add')

            son = ActivityHandler.TO_SON(activity)

            act = Activities(session)
            if org:
                act.ensure_subscription(user_session.user, org, org,
                                        self.reason)

        self.set_header("Content-Type", "application/json")
        self.write(json_encode(son))
        self.finish()
Beispiel #8
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)