Beispiel #1
0
    def getContext(self):
        """
        Get a list of folders with given search parameters. Currently accepted
        search modes are:

        1. Searching by parentId and parentType, with optional additional
           filtering by the name field (exact match) or using full text search
           within a single parent folder. Pass a "name" parameter or "text"
           parameter to invoke these additional filters.
        2. Searching with full text search across all folders in the system.
           Simply pass a "text" parameter for this mode.
        """
        context = FolderModel().findOne({
            'name': 'JSON-LD',
            'parentCollection': 'collection',
            'parentId': CollectionModel().findOne({
                'name': 'Context'
            }).get('_id')
        })
        if context:
            return (context.get('meta', {}))
        user = self.getCurrentUser()
        context = FolderModel().setMetadata(
            folder=FolderModel().createFolder(
                parent=CollectionModel().createCollection(
                    name="Context",
                    creator=user,
                    public=True,
                    reuseExisting=True
                ),
                name="JSON-LD",
                parentType='collection',
                public=True,
                creator=user,
                reuseExisting=True
            ),
            metadata={
                "@context": {
                    "@language": "en-US",
                    "@base": rest.getApiUrl(),
                    "reprolib": REPROLIB_CANONICAL,
                    "http://schema.org/url": {
                        "@type": "@id"
                    }
                }
            }
        )
        return (context.get('meta', {}))
Beispiel #2
0
def getSkin(lang="en-US"):
    """
    Function to return the context for the current instance.

    :param language: ISO language string, optional
    :type language: None
    :returns: context dict
    """
    contextCollection = CollectionModel().findOne({'name': 'Context'})
    skinFolder = FolderModel().findOne({
        'name': 'Skin',
        'parentCollection': 'collection',
        'parentId': contextCollection.get('_id')
    }) if contextCollection else None
    defaultSkin = {
        'name': '',
        'colors': {
            'primary': '#000000',
            'secondary': '#FFFFFF'
        },
        'about': ''
    }
    skin = skinFolder.get(
        'meta', defaultSkin) if skinFolder is not None else defaultSkin
    for s in ['name', 'about']:
        lookup = jsonld_expander.getByLanguage(
            skin.get(s, ""),
            lang if lang and lang not in ["@context.@language", ""] else None)
        skin[s] = lookup if lookup and lookup not in [
            None,
            [{}],
        ] else jsonld_expander.getByLanguage(skin[s], None)
        skin[s] = jsonld_expander.fileObjectToStr(skin[s][0]) if isinstance(
            skin[s], list) and len(skin[s]) else skin[s]
    return (skin)
def getModelCollection(modelType):
    """
    Returns the Collection named for the given modelType, creating if not
    already extant.

    :param modelType: 'activity', 'screen', etc.
    :type modelType: str
    :returns: dict
    """
    from girderformindlogger.models import pluralize
    name = pluralize(modelType).title()
    collection = CollectionModel().findOne({'name': name})
    if not collection:
        collection = CollectionModel().createCollection(name=name,
                                                        public=True,
                                                        reuseExisting=True)
    return (collection)
Beispiel #4
0
def afterPostPutCollection(event):
    # This will only trigger if no exceptions (for access, invalid id, etc.) are thrown
    extraParams = event.info['params']
    if 'terms' in extraParams:
        collectionResponse = event.info['returnVal']
        collectionId = collectionResponse['_id']
        terms = extraParams['terms']

        CollectionModel().update({'_id': collectionId},
                                 {'$set': {
                                     'terms': terms
                                 }})

        collectionResponse['terms'] = terms
        event.addResponse(collectionResponse)
    def __init__(self):
        super(Collection, self).__init__()
        self.resourceName = 'collection'
        self._model = CollectionModel()

        self.route('DELETE', (':id',), self.deleteCollection)
        self.route('GET', (), self.find)
        self.route('GET', (':id',), self.getCollection)
        self.route('GET', (':id', 'details'), self.getCollectionDetails)
        self.route('GET', ('details',), self.getCollectionsDetails)
        self.route('GET', (':id', 'download'), self.downloadCollection)
        self.route('GET', (':id', 'access'), self.getCollectionAccess)
        self.route('POST', (), self.createCollection)
        self.route('PUT', (':id',), self.updateCollection)
        self.route('PUT', (':id', 'access'), self.updateCollectionAccess)
        self.route('PUT', (':id', 'metadata'), self.setMetadata)
        self.route('DELETE', (':id', 'metadata'), self.deleteMetadata)
def getByLanguage(object, tag=None):
    """
    Function to get a value or IRI by a language tag following
    https://tools.ietf.org/html/bcp47.

    :param object: The JSON-LD Object to language-parse
    :type object: dict or list
    :param tag: The language tag to use.
    :type tag: str
    :returns: str, either a literal or an IRI.
    """
    if not tag:
        from girderformindlogger.api.v1.context import Context
        tag = FolderModel().findOne({
            'name':
            'JSON-LD',
            'parentCollection':
            'collection',
            'parentId':
            CollectionModel().findOne({
                'name': 'Context'
            }).get('_id')
        })
        tag = tag.get('meta', {}).get('@context',
                                      {}).get('@language') if tag else None
    if isinstance(tag, str):
        tags = getMoreGeneric(tag)
        tags = tags + ["@{}".format(t) for t in tags]
        tags.sort(key=len, reverse=True)
        if isinstance(object, dict):
            return (getFromLongestMatchingKey(object,
                                              tags,
                                              caseInsensitive=True))
        if isinstance(object, list):
            return ([
                getFromLongestMatchingValue(objectList=object,
                                            listOfValues=tags,
                                            keyToMatch='@language',
                                            caseInsensitive=True)
            ])
    if isinstance(object, str):
        return (object)
Beispiel #7
0
    def load(self, info):
        # Augment the collection creation and edit routes to accept a terms field
        events.bind('rest.post.collection.after', 'terms',
                    afterPostPutCollection)
        events.bind('rest.put.collection/:id.after', 'terms',
                    afterPostPutCollection)
        for handler in [
                Collection.createCollection, Collection.updateCollection
        ]:
            handler.description.param('terms',
                                      'The Terms of Use for the collection.',
                                      required=False)

        # Expose the terms field on all collections
        CollectionModel().exposeFields(level=AccessType.READ, fields={'terms'})

        # Add endpoint for registered users to accept terms
        info['apiRoot'].collection.route('POST', (':id', 'acceptTerms'),
                                         acceptCollectionTerms)

        # Expose the terms field on all users
        User().exposeFields(level=AccessType.ADMIN, fields={'terms'})
Beispiel #8
0
    def createApplet(self,
                     name,
                     protocol={},
                     user=None,
                     roles=None,
                     constraints=None):
        """
        Method to create an Applet.

        :param name: Name for the Applet
        :type name: str
        :param protocol: Protocol to link to this Applet, with one or both
            keys: {`_id`, `url`}
        :type protocol: dict
        :param user: User creating Applet
        :type user: dict
        :param roles: Roles to set to this Applet
        :type roles: dict or None
        :param constraints: Constraints to set to this Applet
        :type constraints: dict or None
        """
        from girderformindlogger.utility import jsonld_expander

        if user == None:
            raise AccessException("You must be logged in to create an applet.")
        appletsCollection = CollectionModel().findOne({"name": "Applets"})

        # create the Applets collection if it isn't there!
        if not appletsCollection:
            CollectionModel().createCollection('Applets')
            appletsCollection = CollectionModel().findOne({"name": "Applets"})

        # create new applet
        applet = self.setMetadata(
            folder=self.createFolder(parent=appletsCollection,
                                     name=name,
                                     parentType='collection',
                                     public=True,
                                     creator=user,
                                     allowRename=True),
            metadata={
                'protocol': protocol,
                'applet': constraints if constraints is not None
                and isinstance(constraints, dict) else {}
            })

        appletGroupName = "Default {} ({})".format(name,
                                                   str(applet.get('_id', '')))

        print("Name: {}".format(appletGroupName))
        # Create user groups
        for role in USER_ROLES.keys():
            try:
                group = GroupModel().createGroup(
                    name="{} {}s".format(appletGroupName, role.title()),
                    creator=user,
                    public=False if role == 'user' else True)
            except ValidationException:
                numero = 0
                numberedName = appletGroupName
                while GroupModel().findOne(query={'name': numberedName}):
                    numero += 1
                    numberedName = "{} {} {}s".format(appletGroupName,
                                                      str(numero),
                                                      role.title())
                group = GroupModel().createGroup(
                    name=numberedName,
                    creator=user,
                    public=False if role == 'user' else True)
            self.setGroupRole(doc=applet,
                              group=group,
                              role=role,
                              currentUser=user,
                              force=False)
        return (jsonld_expander.formatLdObject(applet, 'applet', user))
Beispiel #9
0
def _invite(applet, user, role, rsvp, subject):
    """
    Helper function to invite a user to an applet.

    :param applet: Applet to invite user to
    :type applet: AppletModel
    :param user: ID (canonical or applet-specific) or email address of user to
                 invite
    :type user: string
    :param role: Role to invite user to
    :type role: string
    :param rsvp: Require user acceptance?
    :type rsvp: boolean
    :param subject: Subject about 'user' role can inform or about which
                    'reviewer' role can review
    :type subject: string or literal
    :returns: New assignment (dictionary)
    """
    if role not in USER_ROLE_KEYS:
        raise ValidationException('Invalid role.', 'role')
    thisUser = Applet().getCurrentUser()
    user = user if user else str(thisUser['_id'])

    if mail_utils.validateEmailAddress(user):
        user = UserModel().hash(user)

    if bool(rsvp):
        groupName = {'title': '{} {}s'.format(str(applet.get('_id')), role)}
        groupName['lower'] = groupName.get('title', '').lower()
        group = GroupModel().findOne(query={'lowerName': groupName['lower']})
        if not group or group is None:
            group = GroupModel().createGroup(
                name=groupName['title'],
                creator=thisUser,
                public=bool(role in ['manager', 'reviewer']))
    try:
        assignments = CollectionModel().createCollection(name="Assignments",
                                                         public=True,
                                                         reuseExisting=True)
        assignmentType = 'collection'
    except AccessException:
        assignments, assignmentType = selfAssignment()
    appletAssignment = list(FolderModel().childFolders(
        parent=assignments,
        parentType=assignmentType,
        user=thisUser,
        filters={
            'meta.applet.@id': str(applet['_id']) if '_id' in applet else None
        }))
    appletAssignment = appletAssignment[0] if len(
        appletAssignment) else FolderModel().setMetadata(
            FolderModel().createFolder(
                parent=assignments,
                name=FolderModel().preferredName(applet),
                parentType=assignmentType,
                public=False,
                creator=thisUser,
                allowRename=True,
                reuseExisting=False), {
                    'applet': {
                        '@id': str(applet['_id']) if '_id' in applet else None
                    }
                })
    meta = appletAssignment.get('meta', {})
    members = meta.get('members',
                       []) if meta.get('members') is not None else []
    cUser = getUserCipher(appletAssignment, user)
    subject = subject.upper() if subject is not None and subject.upper(
    ) in SPECIAL_SUBJECTS else getUserCipher(
        appletAssignment,
        str(thisUser['_id']) if subject is None else subject)
    thisAppletAssignment = {
        '@id': str(cUser),
        'roles': {
            role: True if role not in ['reviewer', 'user'] else [subject]
        }
    }
    for i, u in enumerate(members):
        if '@id' in u and u["@id"] == str(cUser):
            thisAppletAssignment = members.pop(i)
            if 'roles' not in thisAppletAssignment:
                thisAppletAssignment['roles'] = {}
            thisAppletAssignment['roles'][role] = True if role not in [
                'reviewer', 'user'
            ] else [subject] if (subject in SPECIAL_SUBJECTS) or (
                'reviewer' not in thisAppletAssignment['roles']) else list(
                    set(thisAppletAssignment['roles']['reviewer'] +
                        [subject]).difference(set(SPECIAL_SUBJECTS))
                ) if "ALL" not in thisAppletAssignment['roles'][
                    'reviewer'] else ["ALL"]
    members.append(thisAppletAssignment)
    meta['members'] = members
    appletAssignment = FolderModel().setMetadata(appletAssignment, meta)
    authorizeReviewers(appletAssignment)
    return (appletAssignment)
Beispiel #10
0
    def createApplet(self,
                     name,
                     protocol={},
                     user=None,
                     roles=None,
                     constraints=None,
                     appletName=None):
        """
        Method to create an Applet.

        :param name: Name for the Applet
        :type name: str
        :param protocol: Protocol to link to this Applet, with one or both
            keys: {`_id`, `url`}
        :type protocol: dict
        :param user: User creating Applet
        :type user: dict
        :param roles: Roles to set to this Applet
        :type roles: dict or None
        :param constraints: Constraints to set to this Applet
        :type constraints: dict or None
        """
        from girderformindlogger.utility import jsonld_expander

        if user == None:
            raise AccessException("You must be logged in to create an applet.")
        appletsCollection = CollectionModel().findOne({"name": "Applets"})

        # create the Applets collection if it isn't there!
        if not appletsCollection:
            CollectionModel().createCollection('Applets')
            appletsCollection = CollectionModel().findOne({"name": "Applets"})

        appletName = self.validateAppletName(appletName, appletsCollection,
                                             user)

        # create new applet
        applet = self.setMetadata(
            folder=self.createFolder(parent=appletsCollection,
                                     name=name,
                                     parentType='collection',
                                     public=True,
                                     creator=user,
                                     allowRename=True,
                                     appletName=appletName),
            metadata={
                'protocol': protocol,
                'applet': constraints if constraints is not None
                and isinstance(constraints, dict) else {}
            })

        appletGroupName = "Default {} ({})".format(name,
                                                   str(applet.get('_id', '')))

        print("Name: {}".format(appletGroupName))
        # Create user groups
        role2AccessLevel = {
            'user': AccessType.READ,
            'coordinator': AccessType.ADMIN,
            'manager': AccessType.ADMIN,
            'editor': AccessType.WRITE,
            'reviewer': AccessType.READ
        }
        accessList = applet.get('access', {})
        accessList['groups'] = []

        for role in USER_ROLES.keys():
            try:
                group = GroupModel().createGroup(
                    name="{} {}s".format(appletGroupName, role.title()),
                    creator=user,
                    public=False if role == 'user' else True)
                accessList['groups'].append({
                    'id': ObjectId(group['_id']),
                    'level': role2AccessLevel[role]
                })

            except ValidationException:
                numero = 0
                numberedName = appletGroupName
                while GroupModel().findOne(query={'name': numberedName}):
                    numero += 1
                    numberedName = "{} {} {}s".format(appletGroupName,
                                                      str(numero),
                                                      role.title())
                group = GroupModel().createGroup(
                    name=numberedName,
                    creator=user,
                    public=False if role == 'user' else True)
            self.setGroupRole(doc=applet,
                              group=group,
                              role=role,
                              currentUser=user,
                              force=False)

        self.setAccessList(applet, accessList)
        self.update({'_id': ObjectId(applet['_id'])},
                    {'$set': {
                        'access': applet.get('access', {})
                    }})

        from girderformindlogger.models.profile import Profile

        # give all roles to creator of an applet
        profile = Profile().createProfile(applet, user, 'manager')
        profile = Profile().load(profile['_id'], force=True)

        profile['roles'] = list(USER_ROLES.keys())
        Profile().save(profile, False)

        UserModel().appendApplet(UserModel().load(user['_id'], force=True),
                                 applet['_id'], USER_ROLES.keys())

        return (jsonld_expander.formatLdObject(applet,
                                               'applet',
                                               user,
                                               refreshCache=False))