Exemplo n.º 1
0
    def update(self, **kwargs):
        '''Updates metadata values.

        This function should be used when updating or adding
        values to the metadata objects.

        :param dict kwargs: key = value of attributes to add/update in the object.
        :returns: itself for chainability
        :rtype: :class:`Project`

        ..note::
            When updating PIs, CO-PIs, team members or collaborators.
            Remember to use :func:`add_collaborator` or :func:`remove_collaborator` respectively.
        '''
        logger.debug('updating project metadata: {"id": "%s", "updates": %s}', self.uuid, kwargs)
        for key, value in six.iteritems(kwargs):
            camel_key = to_camel_case(key)
            self.value[camel_key] = value
Exemplo n.º 2
0
    def post(self, request, project_id):
        """
        Update a Project. Projects and the root File directory for a Project should
        be owned by the portal, with roles/permissions granted to the creating user.

        1. Get the metadata record for the project
        2. Get the metadata permissions for the project
        3. Update the metadata record with changes from the post data and initilize the
           appropriate project class.
        4. Use the metadata permissions and the metadata record to determine which users
           to add and/or remove from the project
        5. Update file metadata permissions
        6. Set ACLs on the project
        7. Email users who have been added to the project

        :param request: 
        :return:
        """
        if request.is_ajax():
            post_data = json.loads(request.body)
        else:
            post_data = request.POST.copy()

        client = request.user.agave_oauth.client
        sa_client = get_service_account_client(
        )  # service account for updating user permissions

        meta_obj = client.meta.getMetadata(uuid=project_id)
        meta_perms = client.meta.listMetadataPermissions(uuid=project_id)

        # update the meta_obj
        for key, value in post_data.items():
            camel_key = to_camel_case(key)
            meta_obj.value[camel_key] = value

        # get users to add/remove
        admins = ['ds_admin', 'prjadmin']
        users_with_access = [x['username'] for x in meta_perms]
        updated_users = list(
            set(meta_obj['value']['teamMembers'] + meta_obj['value']['coPis'] +
                [meta_obj['value']['pi']]))
        add_perm_usrs = [
            u for u in updated_users + admins if u not in users_with_access
        ]
        rm_perm_usrs = [
            u for u in users_with_access if u not in updated_users + admins
        ]

        prj_class = project_lookup_model(meta_obj)
        project = prj_class(value=meta_obj.value, uuid=project_id)
        project.manager().set_client(sa_client)

        try:
            ds_user = get_user_model().objects.get(username=project.pi)
        except:
            return HttpResponseBadRequest('Project update requires a valid PI')

        # remove permissions for users not on project and add permissions for new members
        if rm_perm_usrs:
            project._remove_team_members_pems(rm_perm_usrs)
        if add_perm_usrs:
            project._add_team_members_pems(add_perm_usrs)

        tasks.check_project_files_meta_pems.apply_async(args=[project.uuid],
                                                        queue='api')
        tasks.set_facl_project.apply_async(args=[project.uuid, add_perm_usrs],
                                           queue='api')
        tasks.email_collaborator_added_to_project.apply_async(args=[
            project.project_id, project.uuid, project.title,
            request.build_absolute_uri('{}/projects/{}/'.format(
                reverse('designsafe_data:data_depot'), project.uuid)),
            add_perm_usrs, []
        ])
        project.save(client)
        return JsonResponse(project.to_body_dict())