class ContentViewModel(BaseModel): endpoint_name = 'content_view' schema = { 'name': { 'type': 'string', 'required': True, 'minlength': 1 }, 'location': { 'type': 'string', 'allowed': ['ingest', 'archive'], 'default': 'archive' }, 'description': { 'type': 'string', 'minlength': 1 }, 'desk': BaseModel.rel('desks', True), 'user': BaseModel.rel('users', True), 'filter': { 'type': 'dict' }, 'hateoas': { 'self': '/{location}/{_id}' } } def check_filter(self, filter, location): parsed_request = init_parsed_request(filter) payload = None try: superdesk.apps[location].get(req=parsed_request, lookup={}) except Exception as e: logger.exception(e) payload = 'Fail to validate the filter against %s.' % location if payload: raise superdesk.SuperdeskError(payload=payload) def process_and_validate(self, doc): if 'desks' in doc and not doc['desks']: del doc['desks'] if 'filter' in doc and doc['filter']: self.check_filter(doc['filter'], doc['location']) def on_create(self, docs): for doc in docs: doc.setdefault('user', get_user(required=True)['_id']) self.process_and_validate(doc) def on_update(self, updates, original): self.process_and_validate(updates)
class AuthModel(BaseModel): endpoint_name = 'auth' schema = { 'username': { 'type': 'string', 'required': True }, 'password': { 'type': 'string', 'required': True }, 'token': { 'type': 'string' }, 'user': BaseModel.rel('users', True) } resource_methods = ['POST'] item_methods = ['GET'] public_methods = ['POST'] extra_response_fields = ['user', 'token', 'username'] def on_create(self, docs): for doc in docs: user = authenticate(doc, app.data) doc['user'] = user['_id'] doc['token'] = utils.get_random_string(40) del doc['password']
class ActivityModel(BaseModel): endpoint_name = 'activity' resource_methods = ['GET'] item_methods = ['GET', 'PATCH'] schema = { 'message': { 'type': 'string' }, 'data': { 'type': 'dict' }, 'read': { 'type': 'dict' }, 'item': BaseModel.rel('archive', type='string'), 'user': BaseModel.rel('users'), } exclude = {endpoint_name, 'notification'} datasource = {'default_sort': [('_created', -1)]}
class SesssionsModel(BaseModel): endpoint_name = 'sessions' schema = {'user': BaseModel.rel('users', True)} datasource = { 'source': 'auth', 'default_sort': [('_created', -1)], 'filter': { '$where': '(ISODate() - this._created) / 3600000 <= 12' } # last 12h } resource_methods = ['GET'] item_methods = [] embedded_fields = ['user']
class PlanningModel(BaseModel): endpoint_name = 'planning' schema = { 'guid': { 'type': 'string', 'unique': True }, 'language': { 'type': 'string' }, 'headline': { 'type': 'string' }, 'slugline': { 'type': 'string' }, 'description_text': { 'type': 'string', 'nullable': True }, 'firstcreated': { 'type': 'datetime' }, 'urgency': { 'type': 'integer' }, 'desk': BaseModel.rel('desks', True) } item_url = 'regex("[\w,.:-]+")' datasource = {'search_backend': 'elastic'} resource_methods = ['GET', 'POST'] def on_create(self, docs): on_create_item(docs) def on_created(self, docs): push_notification('planning', created=1) def on_updated(self, updates, original): push_notification('planning', updated=1) def on_deleted(self, doc): push_notification('planning', deleted=1)
from flask import current_app as app from superdesk.models import BaseModel from superdesk.utils import get_random_string from superdesk.emails import send_email from settings import RESET_PASSWORD_TOKEN_TIME_TO_LIVE as token_ttl import logging from .users import hash_password from superdesk.utc import utcnow logger = logging.getLogger(__name__) reset_schema = { 'email': {'type': 'email'}, 'token': {'type': 'string'}, 'password': {'type': 'string'}, 'user': BaseModel.rel('users', True) } def send_reset_password_email(doc): from settings import ADMINS from flask import render_template send_email.delay(subject='Reset password', sender=ADMINS[0], recipients=[doc['email']], text_body=render_template("reset_password.txt", user=doc, expires=token_ttl), html_body=render_template("reset_password.html", user=doc, expires=token_ttl)) class ActiveTokensModel(BaseModel): endpoint_name = 'active_tokens'
class UsersModel(BaseModel): endpoint_name = 'users' additional_lookup = { 'url': 'regex("[\w]+")', 'field': 'username' } schema = { 'username': { 'type': 'string', 'unique': True, 'required': True, 'minlength': 1 }, 'password': { 'type': 'string', 'minlength': 5 }, 'first_name': { 'type': 'string', }, 'last_name': { 'type': 'string', }, 'display_name': { 'type': 'string', }, 'email': { 'unique': True, 'type': 'email', 'required': True }, 'phone': { 'type': 'phone_number', }, 'user_info': { 'type': 'dict' }, 'picture_url': { 'type': 'string', }, 'avatar': BaseModel.rel('upload', True), 'role': BaseModel.rel('roles', True), 'workspace': { 'type': 'dict' }, 'preferences': { 'type': 'dict' } } extra_response_fields = [ 'display_name', 'username', 'email', 'user_info', 'picture_url', 'avatar', ] datasource = { 'projection': { 'password': 0, 'preferences': 0 } } def on_create(self, docs): for doc in docs: ensure_hashed_password(doc) def on_created(self, docs): for doc in docs: add_activity('created user {{user}}', user=doc.get('display_name', doc.get('username'))) def on_deleted(self, doc): add_activity('removed user {{user}}', user=doc.get('display_name', doc.get('username')))
class AuditModel(BaseModel): endpoint_name = 'audit' resource_methods = ['GET'] item_methods = ['GET'] schema = { 'resource': { 'type': 'string' }, 'action': { 'type': 'string' }, 'extra': { 'type': 'dict' }, 'user': BaseModel.rel('users', False) } exclude = {endpoint_name, 'activity'} def on_generic_inserted(self, resource, docs): if resource in self.exclude: return user = getattr(flask.g, 'user', None) if not user: return if not len(docs): return audit = { 'user': user.get('_id'), 'resource': resource, 'action': 'created', 'extra': docs[0] } post_internal(self.endpoint_name, audit) def on_generic_updated(self, resource, doc, original): if resource in self.exclude: return user = getattr(flask.g, 'user', None) if not user: return audit = { 'user': user.get('_id'), 'resource': resource, 'action': 'updated', 'extra': doc } post_internal(self.endpoint_name, audit) def on_generic_deleted(self, resource, doc): if resource in self.exclude: return user = getattr(flask.g, 'user', None) if not user: return audit = { 'user': user.get('_id'), 'resource': resource, 'action': 'deleted', 'extra': doc } post_internal(self.endpoint_name, audit)
import flask import superdesk from superdesk.models import BaseModel from superdesk.notification import push_notification from apps.activity import add_activity comments_schema = { 'text': { 'type': 'string', 'minlength': 1, 'maxlength': 500, 'required': True, }, 'item': BaseModel.rel('archive', True, True, type='string'), 'user': BaseModel.rel('users', True), 'mentioned_users': { 'type': 'dict' } } def check_item_valid(item_id): item = app.data.find_one('archive', req=None, _id=item_id) if not item: msg = 'Invalid content item ID provided: %s' % item_id raise superdesk.SuperdeskError(payload=msg) def get_users_mentions(text):
class TaskModel(BaseModel): endpoint_name = 'tasks' datasource = { 'source': 'archive', 'default_sort': [('_updated', -1)], 'filter': { 'task': { '$exists': True } }, 'elastic_filter': { 'exists': { 'field': 'task' } } # eve-elastic specific filter } schema = { 'slugline': base_schema['slugline'], 'description_text': base_schema['description_text'], 'type': base_schema['type'], 'planning_item': BaseModel.rel('planning', True, type='string'), 'task': { 'type': 'dict', 'schema': { 'status': { 'type': 'string', 'allowed': ['todo', 'in-progress', 'done'], 'default': 'todo', 'required': True }, 'due_date': { 'type': 'datetime' }, 'started_at': { 'type': 'datetime' }, 'finished_at': { 'type': 'datetime' }, 'user': BaseModel.rel('users', True), 'desk': BaseModel.rel('desks', True) } } } def update_times(self, doc): task = doc.get('task', {}) status = task.get('status', None) if status == 'in-progress': task.setdefault('started_at', utcnow()) if status == 'done': task.setdefault('finished_at', utcnow()) def on_create(self, docs): for doc in docs: self.update_times(doc) def on_update(self, updates, original): self.update_times(updates) def on_created(self, docs): push_notification(self.endpoint_name, created=1) def on_updated(self, updates, original): push_notification(self.endpoint_name, updated=1) def on_deleted(self, doc): push_notification(self.endpoint_name, deleted=1)