def put(self, organisation_id, survey_id): program_id = self.get_argument('programId', '') with model.session_scope() as session: org = session.query(model.Organisation).get(organisation_id) if not org: raise errors.MissingDocError("No such organisation") survey = (session.query(model.Survey).get((survey_id, program_id))) if not survey: raise errors.MissingDocError('No such survey') user_session = self.get_user_session(session) policy = user_session.policy.derive({ 'org': org, 'survey': survey, 'surveygroups': survey.surveygroups & org.surveygroups, }) policy.verify('surveygroup_interact') policy.verify('survey_purchase') purchased_survey = (session.query(model.PurchasedSurvey).get( (program_id, survey_id, org.id))) if not purchased_survey: org.surveys.append(survey)
def head(self, organisation_id, survey_id): program_id = self.get_argument('programId', '') with model.session_scope() as session: org = session.query(model.Organisation).get(organisation_id) if not org: raise errors.MissingDocError("No such organisation") survey = (session.query(model.Survey).get((survey_id, program_id))) if not survey: raise errors.MissingDocError("No such survey") user_session = self.get_user_session(session) policy = user_session.policy.derive({ 'org': org, 'surveygroups': survey.surveygroups & org.surveygroups, }) policy.verify('surveygroup_interact') policy.verify('submission_browse') purchased_survey = (session.query(model.PurchasedSurvey).get( (program_id, survey_id, organisation_id))) if not purchased_survey: raise errors.MissingDocError( "This survey has not been purchased yet") self.finish()
def get_schema(self, name): schema = config.SCHEMA.get(name) if not schema or config.is_private(name, schema): raise errors.MissingDocError("No such setting") if config.is_primitive(schema): raise errors.MissingDocError( "This service can only be used to get blob data, not " "text or numerical values.") return schema
def get(self, submission_id, fmt, extension): if extension != 'xlsx': raise errors.MissingDocError("File type not supported: %s" % extension) if fmt not in {'tabular', 'nested'}: raise errors.MissingDocError("Unrecognised format: %s" % fmt) 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") elif submission.deleted: raise errors.MissingDocError( "That submission has been deleted") policy = user_session.policy.derive({ 'org': submission.organisation, 'survey': submission.survey, 'surveygroups': submission.surveygroups, }) policy.verify('surveygroup_interact') policy.verify('report_sub_export') survey_id = submission.survey_id program_id = submission.program_id role = user_session.user.role output_file = 'submission_{0}_{1}.xlsx'.format(submission_id, fmt) base_url = ("%s://%s" % (self.request.protocol, self.request.host)) with tempfile.TemporaryDirectory() as tmpdirname: output_path = os.path.join(tmpdirname, output_file) if fmt == 'tabular': yield self.export_tabular(output_path, program_id, survey_id, submission_id, role, base_url) else: yield self.export_nested(output_path, program_id, survey_id, submission_id, role, base_url) self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment') with open(output_path, 'rb') as f: while True: data = f.read(BUF_SIZE) if not data: break self.write(data) self.finish()
def post(self, query_id, file_type): parameters = self.request_son.copy() with model.session_scope() as session: custom_query = session.query(model.CustomQuery).get(query_id) if not custom_query: 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_execute') if not custom_query.text: raise errors.ModelError("Query is empty") conf = self.get_config(session) session.expunge(custom_query) # Overwrite stored query text if query is parameterised if parameters.text: custom_query.text = parameters.text yield self.export(custom_query, conf, file_type) self.finish()
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()
def delete(self, response_type_id): '''Delete''' program_id = self.get_argument('programId', '') with model.session_scope() as session: user_session = self.get_user_session(session) response_type = (session.query(model.ResponseType).get( (response_type_id, program_id))) if not response_type: raise errors.MissingDocError("No such response type") policy = user_session.policy.derive({ 'program': response_type.program, 'surveygroups': response_type.program.surveygroups, }) policy.verify('surveygroup_interact') policy.verify('response_type_del') session.delete(response_type) # No need for survey update: delete will fail if any measures are # using this RT act = Activities(session) act.record(user_session.user, response_type, ['delete']) act.ensure_subscription(user_session.user, response_type, response_type.program, self.reason) self.set_header("Content-Type", "text/plain") self.finish()
def _update_state(self, program_id, editable): ''' Just update the state of the program (not title etc.) ''' 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, }) if editable: program.finalised_date = None policy.verify('program_edit') else: policy.verify('program_edit') program.finalised_date = datetime.datetime.utcnow() act = Activities(session) if session.is_modified(program): act.record(user_session.user, program, ['state']) act.ensure_subscription(user_session.user, program, program, self.reason) self.get(program_id)
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()
def put(self, ob_type, subscription_id): if ob_type: raise errors.ModelError( "Can't provide object type when updating a subscription") with model.session_scope() as session: user_session = self.get_user_session(session) subscription = (session.query( model.Subscription).get(subscription_id)) if not subscription: raise errors.MissingDocError("No such subscription") subscription.subscribed = self.request_son.get('subscribed', False) ob = get_ob(session, subscription.ob_type, subscription.ob_refs) policy = user_session.policy.derive({ 'user': subscription.user, 'survey': self.get_survey(ob), 'submission': self.get_submission(ob), }) policy.verify('subscription_edit') subscription_id = str(subscription.id) self.get('', subscription_id)
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()
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()
def post(self, ob_type, object_ids): object_ids = object_ids.split(',') if not ob_type: raise errors.ModelError( "Object type required when creating a subscription") with model.session_scope() as session: user_session = self.get_user_session(session) ob = get_ob(session, ob_type, object_ids) if not ob: raise errors.MissingDocError("No such object") act = Activities(session) subscription = act.subscribe(user_session.user, ob) subscription.subscribed = self.request_son.get('subscribed', False) policy = user_session.policy.derive({ 'user': subscription.user, 'survey': self.get_survey(ob), 'submission': self.get_submission(ob), }) policy.verify('subscription_add') session.flush() subscription_id = str(subscription.id) self.get('', subscription_id)
def get(self, attachment_id, file_name): with model.session_scope() as session: user_session = self.get_user_session(session) attachment = session.query(model.Attachment).get(attachment_id) if not attachment: raise errors.MissingDocError("No such attachment") policy = user_session.policy.derive({ 'org': attachment.organisation, 'surveygroups': attachment.organisation.surveygroups, }) policy.verify('surveygroup_interact') policy.verify('attachment_view') if attachment.storage == "aws": s3 = aws.session.client('s3', verify=False) object_loc = aws.S3_PATTERN.match(attachment.url) with tempfile.NamedTemporaryFile() as temp: s3.download_file( object_loc.group('bucket'), object_loc.group('path'), temp.name) with open(temp.name, "rb") as file: blob = file.read() else: blob = attachment.blob self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment') self.write(bytes(blob)) self.finish()
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()
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()
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()
def put(self, response_type_id): '''Update existing''' program_id = self.get_argument('programId', '') with model.session_scope() as session: user_session = self.get_user_session(session) response_type = (session.query(model.ResponseType).get( (response_type_id, program_id))) if not response_type: raise errors.MissingDocError("No such response type") policy = user_session.policy.derive({ 'program': response_type.program, 'surveygroups': response_type.program.surveygroups, }) policy.verify('surveygroup_interact') policy.verify('response_type_edit') if 'name' in self.request_son: rt_by_name = (session.query(model.ResponseType).filter( model.ResponseType.program_id == program_id).filter( model.ResponseType.name == self.request_son.name).first()) if rt_by_name and rt_by_name != response_type: raise errors.ModelError( "'" + self.request_son.name + "' as a response type of that name already exists") try: self._update(response_type, self.request_son) except ResponseTypeError as e: raise errors.ModelError(str(e)) except voluptuous.error.Error as e: raise errors.ModelError(str(e)) except Exception as e: raise errors.ModelError(str(e)) verbs = [] # Check if modified now to avoid problems with autoflush later if session.is_modified(response_type): verbs.append('update') calculator = Calculator.structural() for measure in response_type.measures: for qnode_measure in measure.qnode_measures: calculator.mark_measure_dirty(qnode_measure) calculator.execute() act = Activities(session) act.record(user_session.user, response_type, verbs) act.ensure_subscription(user_session.user, response_type, response_type.program, self.reason) self.get(response_type_id)
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)
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()
def get(self, size): size = int(size) if size < 8: raise errors.MissingDocError("Size is too small") if size > 256: raise errors.MissingDocError("Size is too big") if size <= 64: name = 'theme_icon_sm' else: name = 'theme_icon_lg' with model.session_scope() as session: data = yield self.get_icon(session, name, size) self.set_header('Content-Type', 'image/png') self.write(data) self.finish()
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()
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()
def post(self, response_type_id): '''Create new''' if response_type_id: raise errors.ModelError("Can't specify ID when creating") program_id = self.get_argument('programId', '') 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('response_type_add') rt_by_name = (session.query(model.ResponseType).filter( model.ResponseType.program_id == program_id).filter( model.ResponseType.name == self.request_son.name).first()) if rt_by_name: raise errors.ModelError( "'" + self.request_son.name + "' as a response type of that name already exists") response_type = model.ResponseType(program=program) session.add(response_type) try: self._update(response_type, self.request_son) except ResponseTypeError as e: raise errors.ModelError(str(e)) except voluptuous.error.Error as e: raise errors.ModelError(str(e)) try: session.flush() except sqlalchemy.exc.IntegrityError as e: raise errors.ModelError.from_sa(e) response_type_id = str(response_type.id) # No need for survey update: RT is not being used yet act = Activities(session) act.record(user_session.user, response_type, ['create']) act.ensure_subscription(user_session.user, response_type, response_type.program, self.reason) self.get(response_type_id)
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()
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)
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()
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()
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()
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()