Esempio n. 1
0
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)
Esempio n. 2
0
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']
Esempio n. 3
0
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)]}
Esempio n. 4
0
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']
Esempio n. 5
0
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)
Esempio n. 6
0
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'
Esempio n. 7
0
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')))
Esempio n. 8
0
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):
Esempio n. 10
0
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)