def test_branched_from_must_be_a_node_or_draft_node(self):
        with pytest.raises(DraftRegistrationStateError):
            DraftRegistration.create_from_node(
                user=user,
                node=factories.RegistrationFactory(),
                schema=factories.get_default_metaschema())

        with pytest.raises(DraftRegistrationStateError):
            DraftRegistration.create_from_node(
                user=user,
                node=factories.CollectionFactory(),
                schema=factories.get_default_metaschema())
 def make_draft_registration(node=None):
     draft_registration = DraftRegistration.create_from_node(
         user=user,
         schema=get_default_metaschema(),
         data={},
         node=node if node else None
     )
     user.affiliated_institutions.add(institution)
     draft_registration.set_title(title, Auth(user))
     draft_registration.set_description(description, Auth(user))
     draft_registration.category = category
     draft_registration.add_contributor(write_contrib, permissions=WRITE)
     draft_registration.set_node_license(
         {
             'id': license.license_id,
             'year': NEW_YEAR,
             'copyrightHolders': COPYLEFT_HOLDERS
         },
         auth=Auth(user),
         save=True
     )
     draft_registration.add_tag('savanna', Auth(user))
     draft_registration.add_tag('taxonomy', Auth(user))
     draft_registration.set_subjects([[subject._id]], auth=Auth(draft_registration.creator))
     draft_registration.affiliated_institutions.add(institution)
     draft_registration.save()
     return draft_registration
Esempio n. 3
0
    def test_can_view_property(self, user):
        project = factories.ProjectFactory(creator=user)

        write_contrib = factories.UserFactory()
        read_contrib = factories.UserFactory()
        non_contrib = factories.UserFactory()

        draft = DraftRegistration.create_from_node(
            user=user,
            node=project,
            schema=factories.get_default_metaschema()
        )
        project.add_contributor(non_contrib, ADMIN, save=True)
        draft.add_contributor(write_contrib, WRITE, save=True)
        draft.add_contributor(read_contrib, READ, save=True)

        assert draft.get_permissions(user) == [READ, WRITE, ADMIN]
        assert draft.get_permissions(write_contrib) == [READ, WRITE]
        assert draft.get_permissions(read_contrib) == [READ]

        assert draft.can_view(Auth(user)) is True
        assert draft.can_view(Auth(write_contrib)) is True
        assert draft.can_view(Auth(read_contrib)) is True

        assert draft.can_view(Auth(non_contrib)) is False
Esempio n. 4
0
    def create(self, validated_data):
        node = validated_data.pop('node')
        initiator = validated_data.pop('initiator')
        metadata = validated_data.pop('registration_metadata', None)

        schema_id = validated_data.pop('registration_schema').get('_id')
        schema = get_object_or_error(MetaSchema, schema_id,
                                     self.context['request'])
        if schema.schema_version != LATEST_SCHEMA_VERSION or not schema.active:
            raise exceptions.ValidationError(
                'Registration supplement must be an active schema.')

        draft = DraftRegistration.create_from_node(node=node,
                                                   user=initiator,
                                                   schema=schema)
        reviewer = is_prereg_admin_not_project_admin(self.context['request'],
                                                     draft)

        if metadata:
            try:
                # Required fields are only required when creating the actual registration, not updating the draft.
                draft.validate_metadata(metadata=metadata,
                                        reviewer=reviewer,
                                        required_fields=False)
            except ValidationError as e:
                raise exceptions.ValidationError(e.message)
            draft.update_metadata(metadata)
            draft.save()
        return draft
Esempio n. 5
0
def new_draft_registration(auth, node, *args, **kwargs):
    """Create a new draft registration for the node

    :return: Redirect to the new draft's edit page
    :rtype: flask.redirect
    :raises: HTTPError
    """
    if node.is_registration:
        raise HTTPError(http.FORBIDDEN, data={
            'message_short': "Can't create draft",
            'message_long': 'Creating draft registrations on registered projects is not allowed.'
        })
    data = request.values

    schema_name = data.get('schema_name')
    if not schema_name:
        raise HTTPError(
            http.BAD_REQUEST,
            data={
                'message_short': 'Must specify a schema_name',
                'message_long': 'Please specify a schema_name'
            }
        )

    schema_version = data.get('schema_version', 2)

    meta_schema = get_schema_or_fail(schema_name, int(schema_version))
    draft = DraftRegistration.create_from_node(
        node,
        user=auth.user,
        schema=meta_schema,
        data={}
    )
    return redirect(node.web_url_for('edit_draft_registration_page', draft_id=draft._id, _guid=True))
Esempio n. 6
0
def new_draft_registration(auth, node, *args, **kwargs):
    """Create a new draft registration for the node

    :return: Redirect to the new draft's edit page
    :rtype: flask.redirect
    :raises: HTTPError
    """
    if node.is_registration:
        raise HTTPError(http.FORBIDDEN, data={
            'message_short': "Can't create draft",
            'message_long': 'Creating draft registrations on registered projects is not allowed.'
        })
    data = request.values

    schema_name = data.get('schema_name')
    if not schema_name:
        raise HTTPError(
            http.BAD_REQUEST,
            data={
                'message_short': 'Must specify a schema_name',
                'message_long': 'Please specify a schema_name'
            }
        )

    schema_version = data.get('schema_version', 2)

    meta_schema = get_schema_or_fail(Q(name=schema_name, schema_version=int(schema_version)))
    draft = DraftRegistration.create_from_node(
        node,
        user=auth.user,
        schema=meta_schema,
        data={}
    )
    return redirect(node.web_url_for('edit_draft_registration_page', draft_id=draft._id))
 def test_create_draft_registration_without_node(self, user):
     data = {'some': 'data'}
     draft = DraftRegistration.create_from_node(
         user=user,
         schema=get_default_metaschema(),
         data=data,
     )
     assert draft.title == 'Untitled'
     assert draft.branched_from.title == 'Untitled'
     assert draft.branched_from.type == 'osf.draftnode'
     assert draft.branched_from.creator == user
     assert len(draft.logs.all()) == 0
Esempio n. 8
0
 def test_create_from_node(self):
     proj = NodeFactory()
     user = proj.creator
     schema = MetaSchema.objects.first()
     data = {'some': 'data'}
     draft = DraftRegistration.create_from_node(
         proj,
         user=user,
         schema=schema,
         data=data,
     )
     assert user == draft.initiator
     assert schema == draft.registration_schema
     assert data == draft.registration_metadata
     assert proj == draft.branched_from
Esempio n. 9
0
 def test_create_from_node(self):
     proj = NodeFactory()
     user = proj.creator
     schema = MetaSchema.objects.first()
     data = {'some': 'data'}
     draft = DraftRegistration.create_from_node(
         proj,
         user=user,
         schema=schema,
         data=data,
     )
     assert user == draft.initiator
     assert schema == draft.registration_schema
     assert data == draft.registration_metadata
     assert proj == draft.branched_from
Esempio n. 10
0
def bulk_upload_create_draft_registration(auth, initiator, schema, node, data,
                                          provider, row, title, external_id):
    """Create a draft registration from one registration row.
    """
    draft = None
    try:
        draft = DraftRegistration.create_from_node(
            initiator,
            schema,
            node=node,
            data=data,
            provider=provider,
        )
        # Remove all contributors except the initiator if created from an existing node
        if node:
            # Temporarily make initiator contributor visible so that removal of the others can succeed.
            initiator_contributor = draft.contributor_set.get(user=initiator)
            if not initiator_contributor.visible:
                initiator_contributor.visible = True
                initiator_contributor.save()
            contributor_set = draft.contributor_set.all()
            for contributor in contributor_set:
                if initiator != contributor.user:
                    is_removed = draft.remove_contributor(contributor, auth)
                    assert is_removed, 'Removal of an non-initiator contributor from the draft has failed'
            draft.save()
        assert len(draft.contributor_set.all(
        )) == 1, 'Draft should only have one contributor upon creation.'
        # Remove the initiator from the citation list
        initiator_contributor = draft.contributor_set.get(user=initiator)
        initiator_contributor.visible = False
        initiator_contributor.save()
        # Relate the draft to the row
        row.draft_registration = draft
        row.save()
    except Exception as e:
        # If the draft has been created already but failure happens before it is related to the registration row,
        # provide the draft id to the exception object for the caller to delete it after the exception is caught.
        draft_id = draft.id if draft else None
        raise RegistrationBulkCreationRowError(
            row.upload.id,
            row.id,
            title,
            external_id,
            draft_id=draft_id,
            error=repr(e),
        )
    return draft
Esempio n. 11
0
 def _create(cls, *args, **kwargs):
     branched_from = kwargs.get('branched_from')
     initiator = kwargs.get('initiator')
     registration_schema = kwargs.get('registration_schema')
     registration_metadata = kwargs.get('registration_metadata')
     if not branched_from:
         project_params = {}
         if initiator:
             project_params['creator'] = initiator
         branched_from = ProjectFactory(**project_params)
     initiator = branched_from.creator
     registration_schema = registration_schema or MetaSchema.find()[0]
     registration_metadata = registration_metadata or {}
     draft = DraftRegistration.create_from_node(
         branched_from,
         user=initiator,
         schema=registration_schema,
         data=registration_metadata,
     )
     return draft
Esempio n. 12
0
    def test_create_from_node_draft_node(self, user):
        draft = DraftRegistration.create_from_node(
            user=user,
            schema=factories.get_default_metaschema(),
        )

        assert draft.title == 'Untitled'
        assert draft.description == ''
        assert draft.category == ''
        assert user in draft.contributors.all()
        assert len(draft.contributors.all()) == 1

        assert draft.get_permissions(user) == [READ, WRITE, ADMIN]

        assert draft.node_license is None

        draft_tags = draft.tags.values_list('name', flat=True)
        assert len(draft_tags) == 0
        assert draft.subjects.count() == 0
        assert draft.affiliated_institutions.count() == 0
Esempio n. 13
0
 def _create(cls, *args, **kwargs):
     branched_from = kwargs.get('branched_from')
     initiator = kwargs.get('initiator')
     registration_schema = kwargs.get('registration_schema')
     registration_metadata = kwargs.get('registration_metadata')
     if not branched_from:
         project_params = {}
         if initiator:
             project_params['creator'] = initiator
         branched_from = ProjectFactory(**project_params)
     initiator = branched_from.creator
     registration_schema = registration_schema or MetaSchema.find()[0]
     registration_metadata = registration_metadata or {}
     draft = DraftRegistration.create_from_node(
         branched_from,
         user=initiator,
         schema=registration_schema,
         data=registration_metadata,
     )
     return draft
Esempio n. 14
0
    def create(self, validated_data):
        node = validated_data.pop('node')
        initiator = validated_data.pop('initiator')
        metadata = validated_data.pop('registration_metadata', None)

        schema_id = validated_data.pop('registration_schema').get('_id')
        schema = get_object_or_error(MetaSchema, schema_id)
        if schema.schema_version != LATEST_SCHEMA_VERSION or not schema.active:
            raise exceptions.ValidationError('Registration supplement must be an active schema.')

        draft = DraftRegistration.create_from_node(node=node, user=initiator, schema=schema)
        reviewer = is_prereg_admin_not_project_admin(self.context['request'], draft)

        if metadata:
            try:
                # Required fields are only required when creating the actual registration, not updating the draft.
                draft.validate_metadata(metadata=metadata, reviewer=reviewer, required_fields=False)
            except ValidationError as e:
                raise exceptions.ValidationError(e.message)
            draft.update_metadata(metadata)
            draft.save()
        return draft
Esempio n. 15
0
def main(guid, creator_username):
    egap_schema = ensure_egap_schema()
    creator, creator_auth = get_creator_auth_header(creator_username)

    egap_assets_path = get_egap_assets(guid, creator_auth)

    # __MACOSX is a hidden file created by the os when zipping
    directory_list = [
        directory for directory in os.listdir(egap_assets_path)
        if directory not in ('egap_assets.zip',
                             '__MACOSX') and not directory.startswith('.')
    ]

    for egap_project_dir in directory_list:
        logger.info('Attempting to import the follow directory: {}'.format(
            egap_project_dir))
        # Node Creation
        try:
            node = create_node_from_project_json(egap_assets_path,
                                                 egap_project_dir,
                                                 creator=creator)
        except Exception as err:
            logger.error(
                'There was an error attempting to create a node from the '
                '{} directory. Attempting to rollback node and contributor creation'
                .format(egap_project_dir))
            logger.error(str(err))
            try:
                rollback_node_from_project_json(egap_assets_path,
                                                egap_project_dir,
                                                creator=creator)
            except Exception as err:
                logger.error(str(err))
            continue

        # Node File Upload
        non_anon_files = os.path.join(egap_assets_path, egap_project_dir,
                                      'data', 'nonanonymous')
        non_anon_metadata = recursive_upload(creator_auth, node,
                                             non_anon_files)

        anon_files = os.path.join(egap_assets_path, egap_project_dir, 'data',
                                  'anonymous')
        if os.path.isdir(anon_files):
            anon_metadata = recursive_upload(creator_auth, node, anon_files)
        else:
            anon_metadata = {}

        # DraftRegistration Metadata Handling
        with open(
                os.path.join(egap_assets_path, egap_project_dir,
                             'registration-schema.json'), 'r') as fp:
            registration_metadata = json.load(fp)

        # add selectedFileName Just so filenames are listed in the UI
        for data in non_anon_metadata:
            data['selectedFileName'] = data['data']['attributes']['name']

        for data in anon_metadata:
            data['selectedFileName'] = data['data']['attributes']['name']

        non_anon_titles = ', '.join(
            [data['data']['attributes']['name'] for data in non_anon_metadata])
        registration_metadata['q37'] = {
            'comments': [],
            'extra': non_anon_metadata,
            'value': non_anon_titles
        }

        anon_titles = ', '.join(
            [data['data']['attributes']['name'] for data in anon_metadata])
        registration_metadata['q38'] = {
            'comments': [],
            'extra': anon_metadata,
            'value': anon_titles
        }

        # DraftRegistration Creation
        draft_registration = DraftRegistration.create_from_node(
            node,
            user=creator,
            schema=egap_schema,
            data=registration_metadata,
        )

        # Registration Creation
        logger.info(
            'Attempting to create a Registration for Project {}'.format(
                node._id))

        # Retrieve EGAP registration date and potential embargo go-public date
        if registration_metadata.get('q4'):
            egap_registration_date_string = registration_metadata['q4'][
                'value']
            egap_registration_date = dt.strptime(
                egap_registration_date_string,
                '%m/%d/%Y - %H:%M').replace(tzinfo=pytz.UTC)
        else:
            logger.error(
                'DraftRegistration associated with Project {} '
                'does not have a valid registration date in registration_metadata'
                .format(node._id))
            continue

        if registration_metadata.get('q12'):
            if bool(registration_metadata['q12'].get('value')):
                egap_embargo_public_date_string = registration_metadata['q12'][
                    'value']
                egap_embargo_public_date = dt.strptime(
                    egap_embargo_public_date_string,
                    '%m/%d/%y').replace(tzinfo=pytz.UTC)
            else:
                egap_embargo_public_date = None
        else:
            egap_embargo_public_date = None

        sanction_type = 'RegistrationApproval'
        if egap_embargo_public_date and (egap_embargo_public_date >
                                         dt.today().replace(tzinfo=pytz.UTC)):
            sanction_type = 'Embargo'

        logger.info('Attempting to register {} silently'.format(node._id))
        try:
            register_silently(draft_registration, Auth(creator), sanction_type,
                              egap_registration_date, egap_embargo_public_date)
        except Exception as err:
            logger.error(
                'Unexpected error raised when attempting to silently register '
                'project {}. Continuing...'.format(node._id))
            logger.info(str(err))
            continue

        # Update contributors on project to Admin
        contributors = node.contributor_set.all()
        for contributor in contributors:
            if contributor.user == creator:
                pass
            else:
                node.update_contributor(contributor.user,
                                        permission=ADMIN,
                                        visible=True,
                                        auth=Auth(creator),
                                        save=True)

    shutil.rmtree(egap_assets_path)
Esempio n. 16
0
def main(guid, creator_username):
    egap_schema = ensure_egap_schema()
    creator, creator_auth = get_creator_auth_header(creator_username)

    egap_assets_path = get_egap_assets(guid, creator_auth)

    # __MACOSX is a hidden file created by the os when zipping
    directory_list = [
        directory for directory in os.listdir(egap_assets_path)
        if directory not in ('egap_assets.zip', '__MACOSX')
    ]

    for epag_project_dir in directory_list:
        node = create_node_from_project_json(egap_assets_path,
                                             epag_project_dir,
                                             creator=creator)

        non_anon_files = os.path.join(egap_assets_path, epag_project_dir,
                                      'data', 'nonanonymous')
        non_anon_metadata = recursive_upload(creator_auth, node,
                                             non_anon_files)

        anon_files = os.path.join(egap_assets_path, epag_project_dir, 'data',
                                  'anonymous')
        if os.path.isdir(anon_files):
            anon_metadata = recursive_upload(creator_auth, node, anon_files)
        else:
            anon_metadata = {}

        with open(
                os.path.join(egap_assets_path, epag_project_dir,
                             'registration-schema.json'), 'r') as fp:
            registration_metadata = json.load(fp)

        # add selectedFileName Just so filenames are listed in the UI
        for data in non_anon_metadata:
            data['selectedFileName'] = data['data']['attributes']['name']

        for data in anon_metadata:
            data['selectedFileName'] = data['data']['attributes']['name']

        non_anon_titles = ', '.join(
            [data['data']['attributes']['name'] for data in non_anon_metadata])
        registration_metadata['q37'] = {
            'comments': [],
            'extra': non_anon_metadata,
            'value': non_anon_titles
        }

        anon_titles = ', '.join(
            [data['data']['attributes']['name'] for data in anon_metadata])
        registration_metadata['q38'] = {
            'comments': [],
            'extra': anon_metadata,
            'value': anon_titles
        }

        DraftRegistration.create_from_node(
            node,
            user=creator,
            schema=egap_schema,
            data=registration_metadata,
        )

    shutil.rmtree(egap_assets_path)
Esempio n. 17
0
    def test_create_from_node_existing(self, user):
        node = factories.ProjectFactory(creator=user)

        member = factories.AuthUserFactory()
        osf_group = factories.OSFGroupFactory(creator=user)
        osf_group.make_member(member, auth=Auth(user))
        node.add_osf_group(osf_group, ADMIN)

        write_contrib = factories.AuthUserFactory()
        subject = factories.SubjectFactory()
        institution = factories.InstitutionFactory()
        user.affiliated_institutions.add(institution)

        title = 'A Study of Elephants'
        description = 'Loxodonta africana'
        category = 'Methods and Materials'

        node.set_title(title, Auth(user))
        node.set_description(description, Auth(user))
        node.category = category
        node.add_contributor(write_contrib, permissions=WRITE)

        GPL3 = NodeLicense.objects.get(license_id='GPL3')
        NEW_YEAR = '2014'
        COPYLEFT_HOLDERS = ['Richard Stallman']
        node.set_node_license(
            {
                'id': GPL3.license_id,
                'year': NEW_YEAR,
                'copyrightHolders': COPYLEFT_HOLDERS
            },
            auth=Auth(user),
            save=True
        )
        node.add_tag('savanna', Auth(user))
        node.add_tag('taxonomy', Auth(user))
        node.set_subjects([[subject._id]], auth=Auth(node.creator))
        node.affiliated_institutions.add(institution)
        node.save()

        draft = DraftRegistration.create_from_node(
            node=node,
            user=user,
            schema=factories.get_default_metaschema(),
        )

        # Assert existing metadata-like node attributes are copied to the draft
        assert draft.title == title
        assert draft.description == description
        assert draft.category == category
        assert user in draft.contributors.all()
        assert write_contrib in draft.contributors.all()
        assert member not in draft.contributors.all()
        assert not draft.has_permission(member, 'read')

        assert draft.get_permissions(user) == [READ, WRITE, ADMIN]
        assert draft.get_permissions(write_contrib) == [READ, WRITE]

        assert draft.node_license.license_id == GPL3.license_id
        assert draft.node_license.name == GPL3.name
        assert draft.node_license.copyright_holders == COPYLEFT_HOLDERS

        draft_tags = draft.tags.values_list('name', flat=True)
        assert 'savanna' in draft_tags
        assert 'taxonomy' in draft_tags
        assert subject in draft.subjects.all()
        assert institution in draft.affiliated_institutions.all()
        assert draft.branched_from == node