Beispiel #1
0
def user_account(auth, **kwargs):
    user = auth.user
    user_addons = addon_utils.get_addons_by_config_type('user', user)
    if 'password_reset' in request.args:
        push_status_message('Password updated successfully.',
                            kind='success',
                            trust=False)

    return {
        'user_id':
        user._id,
        'addons':
        user_addons,
        'addons_js':
        collect_user_config_js([
            addon for addon in settings.ADDONS_AVAILABLE
            if 'user' in addon.configs
        ]),
        'addons_css': [],
        'requested_deactivation':
        user.requested_deactivation,
        'external_identity':
        user.external_identity,
        'storage_flag_is_active':
        storage_i18n_flag_active(),
    }
Beispiel #2
0
def my_projects(auth):
    user = auth.user

    region_list = get_storage_region_list(user)

    bookmark_collection = find_bookmark_collection(user)
    my_projects_id = bookmark_collection._id
    return {'addons_enabled': user.get_addon_names(),
            'dashboard_id': my_projects_id,
            'storage_regions': region_list,
            'storage_flag_is_active': storage_i18n_flag_active(),
            }
Beispiel #3
0
def my_projects(auth):
    user = auth.user

    region_list = get_storage_region_list(user)

    bookmark_collection = find_bookmark_collection(user)
    my_projects_id = bookmark_collection._id
    return {'addons_enabled': user.get_addon_names(),
            'dashboard_id': my_projects_id,
            'storage_regions': region_list,
            'storage_flag_is_active': storage_i18n_flag_active(),
            }
Beispiel #4
0
def serialize_user(user,
                   node=None,
                   admin=False,
                   full=False,
                   is_profile=False,
                   include_node_counts=False):
    """
    Return a dictionary representation of a registered user.

    :param User user: A User object
    :param bool full: Include complete user properties
    """
    contrib = None
    if isinstance(user, Contributor):
        contrib = user
        user = contrib.user
    fullname = user.display_full_name(node=node)
    ret = {
        'id':
        str(user._id),
        'registered':
        user.is_registered,
        'surname':
        user.family_name,
        'fullname':
        fullname,
        'shortname':
        fullname if len(fullname) < 50 else fullname[:23] + '...' +
        fullname[-23:],
        'profile_image_url':
        user.profile_image_url(size=settings.PROFILE_IMAGE_MEDIUM),
        'active':
        user.is_active,
    }
    if node is not None:
        if admin:
            flags = {
                'visible': False,
                'permission': 'read',
            }
        else:
            is_contributor_obj = isinstance(contrib, Contributor)
            flags = {
                'visible':
                contrib.visible if is_contributor_obj else
                node.contributor_set.filter(user=user, visible=True).exists(),
                'permission':
                get_contributor_permissions(contrib, as_list=False)
                if is_contributor_obj else reduce_permissions(
                    node.get_permissions(user)),
            }
        ret.update(flags)
    if user.is_registered:
        ret.update({
            'url':
            user.url,
            'absolute_url':
            user.absolute_url,
            'display_absolute_url':
            user.display_absolute_url,
            'date_registered':
            user.date_registered.strftime('%Y-%m-%d'),
        })

    if full:
        # Add emails
        if is_profile:
            ret['emails'] = [
                {
                    'address':
                    each,
                    'primary':
                    each.strip().lower() == user.username.strip().lower(),
                    'confirmed':
                    True,
                } for each in user.emails.values_list('address', flat=True)
            ] + [{
                'address':
                each,
                'primary':
                each.strip().lower() == user.username.strip().lower(),
                'confirmed':
                False
            } for each in
                 user.get_unconfirmed_emails_exclude_external_identity()]

        if user.is_merged:
            merger = user.merged_by
            merged_by = {
                'id': str(merger._primary_key),
                'url': merger.url,
                'absolute_url': merger.absolute_url
            }
        else:
            merged_by = None

        default_region = user.get_addon('osfstorage').default_region
        available_regions = [
            region for region in Region.objects.all().values('_id', 'name')
        ]
        ret.update({
            'activity_points':
            user.get_activity_points(),
            'profile_image_url':
            user.profile_image_url(size=settings.PROFILE_IMAGE_LARGE),
            'is_merged':
            user.is_merged,
            'available_regions':
            available_regions,
            'storage_flag_is_active':
            storage_i18n_flag_active(),
            'default_region': {
                'name': default_region.name,
                '_id': default_region._id
            },
            'merged_by':
            merged_by,
        })
        if include_node_counts:
            projects = user.nodes.exclude(is_deleted=True).filter(
                type='osf.node').get_roots()
            ret.update({
                'number_projects':
                projects.count(),
                'number_public_projects':
                projects.filter(is_public=True).count(),
            })

    return ret
Beispiel #5
0
def _view_project(node, auth, primary=False,
                  embed_contributors=False, embed_descendants=False,
                  embed_registrations=False, embed_forks=False):
    """Build a JSON object containing everything needed to render
    project.view.mako.
    """
    node = AbstractNode.objects.filter(pk=node.pk).include('contributor__user__guids').get()
    user = auth.user

    try:
        contributor = node.contributor_set.get(user=user)
    except Contributor.DoesNotExist:
        contributor = None

    parent = node.find_readable_antecedent(auth)
    if user:
        bookmark_collection = find_bookmark_collection(user)
        bookmark_collection_id = bookmark_collection._id
        in_bookmark_collection = bookmark_collection.guid_links.filter(_id=node._id).exists()
    else:
        in_bookmark_collection = False
        bookmark_collection_id = ''

    view_only_link = auth.private_key or request.args.get('view_only', '').strip('/')
    anonymous = has_anonymous_link(node, auth)
    addons = list(node.get_addons())
    widgets, configs, js, css = _render_addons(addons)
    redirect_url = node.url + '?view_only=None'

    disapproval_link = ''
    if (node.is_pending_registration and node.has_permission(user, ADMIN)):
        disapproval_link = node.root.registration_approval.stashed_urls.get(user._id, {}).get('reject', '')

    if (node.is_pending_embargo and node.has_permission(user, ADMIN)):
        disapproval_link = node.root.embargo.stashed_urls.get(user._id, {}).get('reject', '')

    # Before page load callback; skip if not primary call
    if primary:
        for addon in addons:
            messages = addon.before_page_load(node, user) or []
            for message in messages:
                status.push_status_message(message, kind='info', dismissible=False, trust=True)
    NodeRelation = apps.get_model('osf.NodeRelation')

    is_registration = node.is_registration
    data = {
        'node': {
            'disapproval_link': disapproval_link,
            'id': node._primary_key,
            'title': node.title,
            'category': node.category_display,
            'category_short': node.category,
            'node_type': node.project_or_component,
            'description': node.description or '',
            'license': serialize_node_license_record(node.license),
            'url': node.url,
            'api_url': node.api_url,
            'absolute_url': node.absolute_url,
            'redirect_url': redirect_url,
            'display_absolute_url': node.display_absolute_url,
            'update_url': node.api_url_for('update_node'),
            'in_dashboard': in_bookmark_collection,
            'is_public': node.is_public,
            'is_archiving': node.archiving,
            'date_created': iso8601format(node.created),
            'date_modified': iso8601format(node.last_logged) if node.last_logged else '',
            'tags': list(node.tags.filter(system=False).values_list('name', flat=True)),
            'children': node.nodes_active.exists(),
            'child_exists': Node.objects.get_children(node, active=True).exists(),
            'is_supplemental_project': node.has_linked_published_preprints,
            'is_registration': is_registration,
            'is_pending_registration': node.is_pending_registration if is_registration else False,
            'is_retracted': node.is_retracted if is_registration else False,
            'is_pending_retraction': node.is_pending_retraction if is_registration else False,
            'retracted_justification': getattr(node.root.retraction, 'justification', None) if is_registration else None,
            'date_retracted': iso8601format(getattr(node.root.retraction, 'date_retracted', None)) if is_registration else '',
            'embargo_end_date': node.embargo_end_date.strftime('%A, %b %d, %Y') if is_registration and node.embargo_end_date else '',
            'is_pending_embargo': node.is_pending_embargo if is_registration else False,
            'is_embargoed': node.is_embargoed if is_registration else False,
            'is_pending_embargo_termination': is_registration and node.is_pending_embargo_termination,
            'registered_from_url': node.registered_from.url if is_registration else '',
            'registered_date': iso8601format(node.registered_date) if is_registration else '',
            'root_id': node.root._id if node.root else None,
            'registered_meta': node.registered_meta,
            'registered_schemas': serialize_meta_schemas(list(node.registered_schema.all())) if is_registration else False,
            'is_fork': node.is_fork,
            'is_collected': node.is_collected,
            'collections': serialize_collections(node.collecting_metadata_list, auth),
            'forked_from_id': node.forked_from._primary_key if node.is_fork else '',
            'forked_from_display_absolute_url': node.forked_from.display_absolute_url if node.is_fork else '',
            'forked_date': iso8601format(node.forked_date) if node.is_fork else '',
            'fork_count': node.forks.exclude(type='osf.registration').filter(is_deleted=False).count(),
            'private_links': [x.to_json() for x in node.private_links_active],
            'link': view_only_link,
            'templated_count': node.templated_list.count(),
            'linked_nodes_count': NodeRelation.objects.filter(child=node, is_node_link=True).exclude(parent__type='osf.collection').count(),
            'anonymous': anonymous,
            'comment_level': node.comment_level,
            'has_comments': node.comment_set.exists(),
            'identifiers': {
                'doi': node.get_identifier_value('doi'),
                'ark': node.get_identifier_value('ark'),
            },
            'visible_preprints': serialize_preprints(node, user),
            'institutions': get_affiliated_institutions(node) if node else [],
            'has_draft_registrations': node.has_active_draft_registrations,
            'access_requests_enabled': node.access_requests_enabled,
            'storage_location': node.osfstorage_region.name,
            'waterbutler_url': node.osfstorage_region.waterbutler_url,
            'mfr_url': node.osfstorage_region.mfr_url
        },
        'parent_node': {
            'exists': parent is not None,
            'id': parent._primary_key if parent else '',
            'title': parent.title if parent else '',
            'category': parent.category_display if parent else '',
            'url': parent.url if parent else '',
            'api_url': parent.api_url if parent else '',
            'absolute_url': parent.absolute_url if parent else '',
            'registrations_url': parent.web_url_for('node_registrations', _guid=True) if parent else '',
            'is_public': parent.is_public if parent else '',
            'is_contributor': parent.is_contributor(user) if parent else '',
            'can_view': parent.can_view(auth) if parent else False,
        },
        'user': {
            'is_contributor': bool(contributor),
            'is_admin': bool(contributor) and contributor.admin,
            'is_admin_parent': parent.is_admin_parent(user) if parent else False,
            'can_edit': bool(contributor) and contributor.write and not node.is_registration,
            'can_edit_tags': bool(contributor) and contributor.write,
            'has_read_permissions': node.has_permission(user, READ),
            'permissions': get_contributor_permissions(contributor, as_list=True) if contributor else [],
            'id': user._id if user else None,
            'username': user.username if user else None,
            'fullname': user.fullname if user else '',
            'can_comment': bool(contributor) or node.can_comment(auth),
            'show_wiki_widget': _should_show_wiki_widget(node, contributor),
            'dashboard_id': bookmark_collection_id,
            'institutions': get_affiliated_institutions(user) if user else [],
        },
        # TODO: Namespace with nested dicts
        'addons_enabled': [each.short_name for each in addons],
        'addons': configs,
        'addon_widgets': widgets,
        'addon_widget_js': js,
        'addon_widget_css': css,
        'node_categories': [
            {'value': key, 'display_name': value}
            for key, value in settings.NODE_CATEGORY_MAP.items()
        ]
    }

    # Default should be at top of list for UI and for the project overview page the default region
    # for a component is that of the it's parent node.
    region_list = get_storage_region_list(user, node=node)

    data.update({'storage_regions': region_list})
    data.update({'storage_flag_is_active': storage_i18n_flag_active()})
    if storage_usage_flag_active():
        storage_usage = node.storage_usage
        if storage_usage:
            data['node']['storage_usage'] = sizeof_fmt(storage_usage)

    if embed_contributors and not anonymous:
        data['node']['contributors'] = utils.serialize_visible_contributors(node)
    else:
        data['node']['contributors'] = list(node.contributors.values_list('guids___id', flat=True))
    if embed_descendants:
        descendants, all_readable = _get_readable_descendants(auth=auth, node=node)
        data['user']['can_sort'] = all_readable
        data['node']['descendants'] = [
            serialize_node_summary(node=each, auth=auth, primary=not node.has_node_link_to(each), show_path=False)
            for each in descendants
        ]
    if embed_registrations:
        data['node']['registrations'] = [
            serialize_node_summary(node=each, auth=auth, show_path=False)
            for each in node.registrations_all.order_by('-registered_date').exclude(is_deleted=True)
        ]
    if embed_forks:
        data['node']['forks'] = [
            serialize_node_summary(node=each, auth=auth, show_path=False)
            for each in node.forks.exclude(type='osf.registration').exclude(is_deleted=True).order_by('-forked_date')
        ]
    return data
Beispiel #6
0
def _view_project(node, auth, primary=False,
                  embed_contributors=False, embed_descendants=False,
                  embed_registrations=False, embed_forks=False):
    """Build a JSON object containing everything needed to render
    project.view.mako.
    """
    node = AbstractNode.objects.filter(pk=node.pk).include('contributor__user__guids').get()
    user = auth.user

    try:
        contributor = node.contributor_set.get(user=user)
    except Contributor.DoesNotExist:
        contributor = None

    parent = node.find_readable_antecedent(auth)
    if user:
        bookmark_collection = find_bookmark_collection(user)
        bookmark_collection_id = bookmark_collection._id
        in_bookmark_collection = bookmark_collection.guid_links.filter(_id=node._id).exists()
    else:
        in_bookmark_collection = False
        bookmark_collection_id = ''

    view_only_link = auth.private_key or request.args.get('view_only', '').strip('/')
    anonymous = has_anonymous_link(node, auth)
    addons = list(node.get_addons())
    widgets, configs, js, css = _render_addons(addons)
    redirect_url = node.url + '?view_only=None'

    disapproval_link = ''
    if (node.is_pending_registration and node.has_permission(user, ADMIN)):
        disapproval_link = node.root.registration_approval.stashed_urls.get(user._id, {}).get('reject', '')

    if (node.is_pending_embargo and node.has_permission(user, ADMIN)):
        disapproval_link = node.root.embargo.stashed_urls.get(user._id, {}).get('reject', '')

    # Before page load callback; skip if not primary call
    if primary:
        for addon in addons:
            messages = addon.before_page_load(node, user) or []
            for message in messages:
                status.push_status_message(message, kind='info', dismissible=False, trust=True)
    NodeRelation = apps.get_model('osf.NodeRelation')

    is_registration = node.is_registration
    data = {
        'node': {
            'disapproval_link': disapproval_link,
            'id': node._primary_key,
            'title': node.title,
            'category': node.category_display,
            'category_short': node.category,
            'node_type': node.project_or_component,
            'description': node.description or '',
            'license': serialize_node_license_record(node.license),
            'url': node.url,
            'api_url': node.api_url,
            'absolute_url': node.absolute_url,
            'redirect_url': redirect_url,
            'display_absolute_url': node.display_absolute_url,
            'update_url': node.api_url_for('update_node'),
            'in_dashboard': in_bookmark_collection,
            'is_public': node.is_public,
            'is_archiving': node.archiving,
            'date_created': iso8601format(node.created),
            'date_modified': iso8601format(node.last_logged) if node.last_logged else '',
            'tags': list(node.tags.filter(system=False).values_list('name', flat=True)),
            'children': node.nodes_active.exists(),
            'child_exists': Node.objects.get_children(node, active=True).exists(),
            'is_supplemental_project': node.has_linked_published_preprints,
            'is_registration': is_registration,
            'is_pending_registration': node.is_pending_registration if is_registration else False,
            'is_retracted': node.is_retracted if is_registration else False,
            'is_pending_retraction': node.is_pending_retraction if is_registration else False,
            'retracted_justification': getattr(node.retraction, 'justification', None) if is_registration else None,
            'date_retracted': iso8601format(getattr(node.retraction, 'date_retracted', None)) if is_registration else '',
            'embargo_end_date': node.embargo_end_date.strftime('%A, %b %d, %Y') if is_registration and node.embargo_end_date else '',
            'is_pending_embargo': node.is_pending_embargo if is_registration else False,
            'is_embargoed': node.is_embargoed if is_registration else False,
            'is_pending_embargo_termination': is_registration and node.is_embargoed and (
                node.embargo_termination_approval and
                node.embargo_termination_approval.is_pending_approval
            ),
            'registered_from_url': node.registered_from.url if is_registration else '',
            'registered_date': iso8601format(node.registered_date) if is_registration else '',
            'root_id': node.root._id if node.root else None,
            'registered_meta': node.registered_meta,
            'registered_schemas': serialize_meta_schemas(list(node.registered_schema.all())) if is_registration else False,
            'is_fork': node.is_fork,
            'is_collected': node.is_collected,
            'collections': serialize_collections(node.collecting_metadata_list, auth),
            'forked_from_id': node.forked_from._primary_key if node.is_fork else '',
            'forked_from_display_absolute_url': node.forked_from.display_absolute_url if node.is_fork else '',
            'forked_date': iso8601format(node.forked_date) if node.is_fork else '',
            'fork_count': node.forks.exclude(type='osf.registration').filter(is_deleted=False).count(),
            'private_links': [x.to_json() for x in node.private_links_active],
            'link': view_only_link,
            'templated_count': node.templated_list.count(),
            'linked_nodes_count': NodeRelation.objects.filter(child=node, is_node_link=True).exclude(parent__type='osf.collection').count(),
            'anonymous': anonymous,
            'comment_level': node.comment_level,
            'has_comments': node.comment_set.exists(),
            'identifiers': {
                'doi': node.get_identifier_value('doi'),
                'ark': node.get_identifier_value('ark'),
            },
            'visible_preprints': serialize_preprints(node, user),
            'institutions': get_affiliated_institutions(node) if node else [],
            'has_draft_registrations': node.has_active_draft_registrations,
            'access_requests_enabled': node.access_requests_enabled,
            'storage_location': node.osfstorage_region.name,
            'waterbutler_url': node.osfstorage_region.waterbutler_url,
            'mfr_url': node.osfstorage_region.mfr_url
        },
        'parent_node': {
            'exists': parent is not None,
            'id': parent._primary_key if parent else '',
            'title': parent.title if parent else '',
            'category': parent.category_display if parent else '',
            'url': parent.url if parent else '',
            'api_url': parent.api_url if parent else '',
            'absolute_url': parent.absolute_url if parent else '',
            'registrations_url': parent.web_url_for('node_registrations', _guid=True) if parent else '',
            'is_public': parent.is_public if parent else '',
            'is_contributor': parent.is_contributor(user) if parent else '',
            'can_view': parent.can_view(auth) if parent else False,
        },
        'user': {
            'is_contributor': bool(contributor),
            'is_admin': bool(contributor) and contributor.admin,
            'is_admin_parent': parent.is_admin_parent(user) if parent else False,
            'can_edit': bool(contributor) and contributor.write and not node.is_registration,
            'can_edit_tags': bool(contributor) and contributor.write,
            'has_read_permissions': node.has_permission(user, READ),
            'permissions': get_contributor_permissions(contributor, as_list=True) if contributor else [],
            'id': user._id if user else None,
            'username': user.username if user else None,
            'fullname': user.fullname if user else '',
            'can_comment': bool(contributor) or node.can_comment(auth),
            'show_wiki_widget': _should_show_wiki_widget(node, contributor),
            'dashboard_id': bookmark_collection_id,
            'institutions': get_affiliated_institutions(user) if user else [],
        },
        # TODO: Namespace with nested dicts
        'addons_enabled': [each.short_name for each in addons],
        'addons': configs,
        'addon_widgets': widgets,
        'addon_widget_js': js,
        'addon_widget_css': css,
        'node_categories': [
            {'value': key, 'display_name': value}
            for key, value in settings.NODE_CATEGORY_MAP.items()
        ]
    }

    # Default should be at top of list for UI and for the project overview page the default region
    # for a component is that of the it's parent node.
    region_list = get_storage_region_list(user, node=node)

    data.update({'storage_regions': region_list})
    data.update({'storage_flag_is_active': storage_i18n_flag_active()})

    if embed_contributors and not anonymous:
        data['node']['contributors'] = utils.serialize_visible_contributors(node)
    else:
        data['node']['contributors'] = list(node.contributors.values_list('guids___id', flat=True))
    if embed_descendants:
        descendants, all_readable = _get_readable_descendants(auth=auth, node=node)
        data['user']['can_sort'] = all_readable
        data['node']['descendants'] = [
            serialize_node_summary(node=each, auth=auth, primary=not node.has_node_link_to(each), show_path=False)
            for each in descendants
        ]
    if embed_registrations:
        data['node']['registrations'] = [
            serialize_node_summary(node=each, auth=auth, show_path=False)
            for each in node.registrations_all.order_by('-registered_date').exclude(is_deleted=True)
        ]
    if embed_forks:
        data['node']['forks'] = [
            serialize_node_summary(node=each, auth=auth, show_path=False)
            for each in node.forks.exclude(type='osf.registration').exclude(is_deleted=True).order_by('-forked_date')
        ]
    return data
Beispiel #7
0
def confirm_email_get(token, auth=None, **kwargs):
    """
    View for email confirmation links. Authenticates and redirects to user settings page if confirmation is successful,
    otherwise shows an "Expired Link" error.
    HTTP Method: GET
    """

    is_merge = 'confirm_merge' in request.args

    try:
        if not is_merge or not check_select_for_update():
            user = OSFUser.objects.get(guids___id=kwargs['uid'], guids___id__isnull=False)
        else:
            user = OSFUser.objects.filter(guids___id=kwargs['uid'], guids___id__isnull=False).select_for_update().get()
    except OSFUser.DoesNotExist:
        raise HTTPError(http.NOT_FOUND)

    is_initial_confirmation = not user.date_confirmed
    log_out = request.args.get('logout', None)

    # if the user is merging or adding an email (they already are an osf user)
    if log_out:
        return auth_email_logout(token, user)

    if auth and auth.user and (auth.user._id == user._id or auth.user._id == user.merged_by._id):
        if not is_merge:
            # determine if the user registered through a campaign
            campaign = campaigns.campaign_for_user(user)
            if campaign:
                return redirect(campaigns.campaign_url_for(campaign))

            # go to home page with push notification
            if auth.user.emails.count() == 1 and len(auth.user.email_verifications) == 0:
                status.push_status_message(language.WELCOME_MESSAGE, kind='default', jumbotron=True, trust=True, id='welcome_message')
            if token in auth.user.email_verifications:
                status.push_status_message(language.CONFIRM_ALTERNATE_EMAIL_ERROR, kind='danger', trust=True, id='alternate_email_error')
            return redirect(web_url_for('index'))

        status.push_status_message(language.MERGE_COMPLETE, kind='success', trust=False)
        return redirect(web_url_for('user_account'))

    try:
        user.confirm_email(token, merge=is_merge)
    except exceptions.EmailConfirmTokenError as e:
        raise HTTPError(http.BAD_REQUEST, data={
            'message_short': e.message_short,
            'message_long': e.message_long
        })

    if is_initial_confirmation:
        user.update_date_last_login()
        user.save()

        # send out our welcome message
        mails.send_mail(
            to_addr=user.username,
            mail=mails.WELCOME,
            mimetype='html',
            user=user,
            domain=settings.DOMAIN,
            osf_support_email=settings.OSF_SUPPORT_EMAIL,
            storage_flag_is_active=storage_i18n_flag_active(),
        )

    # new random verification key, allows CAS to authenticate the user w/o password one-time only.
    user.verification_key = generate_verification_key()
    user.save()
    # redirect to CAS and authenticate the user with a verification key.
    return redirect(cas.get_login_url(
        request.url,
        username=user.username,
        verification_key=user.verification_key
    ))
Beispiel #8
0
def external_login_confirm_email_get(auth, uid, token):
    """
    View for email confirmation links when user first login through external identity provider.
    HTTP Method: GET

    When users click the confirm link, they are expected not to be logged in. If not, they will be logged out first and
    redirected back to this view. After OSF verifies the link and performs all actions, they will be automatically
    logged in through CAS and redirected back to this view again being authenticated.

    :param auth: the auth context
    :param uid: the user's primary key
    :param token: the verification token
    """

    user = OSFUser.load(uid)
    if not user:
        raise HTTPError(http.BAD_REQUEST)

    destination = request.args.get('destination')
    if not destination:
        raise HTTPError(http.BAD_REQUEST)

    # if user is already logged in
    if auth and auth.user:
        # if it is a wrong user
        if auth.user._id != user._id:
            return auth_logout(redirect_url=request.url)
        # if it is the expected user
        new = request.args.get('new', None)
        if destination in campaigns.get_campaigns():
            # external domain takes priority
            campaign_url = campaigns.external_campaign_url_for(destination)
            if not campaign_url:
                campaign_url = campaigns.campaign_url_for(destination)
            return redirect(campaign_url)
        if new:
            status.push_status_message(language.WELCOME_MESSAGE, kind='default', jumbotron=True, trust=True, id='welcome_message')
        return redirect(web_url_for('dashboard'))

    # token is invalid
    if token not in user.email_verifications:
        raise HTTPError(http.BAD_REQUEST)
    verification = user.email_verifications[token]
    email = verification['email']
    provider = verification['external_identity'].keys()[0]
    provider_id = verification['external_identity'][provider].keys()[0]
    # wrong provider
    if provider not in user.external_identity:
        raise HTTPError(http.BAD_REQUEST)
    external_status = user.external_identity[provider][provider_id]

    try:
        ensure_external_identity_uniqueness(provider, provider_id, user)
    except ValidationError as e:
        raise HTTPError(http.FORBIDDEN, e.message)

    if not user.is_registered:
        user.register(email)

    if not user.emails.filter(address=email.lower()):
        user.emails.create(address=email.lower())

    user.date_last_logged_in = timezone.now()
    user.external_identity[provider][provider_id] = 'VERIFIED'
    user.social[provider.lower()] = provider_id
    del user.email_verifications[token]
    user.verification_key = generate_verification_key()
    user.save()

    service_url = request.url

    if external_status == 'CREATE':
        mails.send_mail(
            to_addr=user.username,
            mail=mails.WELCOME,
            mimetype='html',
            user=user,
            domain=settings.DOMAIN,
            osf_support_email=settings.OSF_SUPPORT_EMAIL,
            storage_flag_is_active=storage_i18n_flag_active(),
        )
        service_url += '&{}'.format(urllib.urlencode({'new': 'true'}))
    elif external_status == 'LINK':
        mails.send_mail(
            user=user,
            to_addr=user.username,
            mail=mails.EXTERNAL_LOGIN_LINK_SUCCESS,
            external_id_provider=provider,
            can_change_preferences=False,
        )

    # redirect to CAS and authenticate the user with the verification key
    return redirect(cas.get_login_url(
        service_url,
        username=user.username,
        verification_key=user.verification_key
    ))
Beispiel #9
0
def serialize_user(user, node=None, admin=False, full=False, is_profile=False, include_node_counts=False):
    """
    Return a dictionary representation of a registered user.

    :param User user: A User object
    :param bool full: Include complete user properties
    """
    contrib = None
    if isinstance(user, Contributor):
        contrib = user
        user = contrib.user
    fullname = user.display_full_name(node=node)
    ret = {
        'id': str(user._id),
        'registered': user.is_registered,
        'surname': user.family_name,
        'fullname': fullname,
        'shortname': fullname if len(fullname) < 50 else fullname[:23] + '...' + fullname[-23:],
        'profile_image_url': user.profile_image_url(size=settings.PROFILE_IMAGE_MEDIUM),
        'active': user.is_active,
    }
    if node is not None:
        if admin:
            flags = {
                'visible': False,
                'permission': 'read',
            }
        else:
            is_contributor_obj = isinstance(contrib, Contributor)
            flags = {
                'visible': contrib.visible if is_contributor_obj else node.contributor_set.filter(user=user, visible=True).exists(),
                'permission': get_contributor_permissions(contrib, as_list=False) if is_contributor_obj else reduce_permissions(node.get_permissions(user)),
            }
        ret.update(flags)
    if user.is_registered:
        ret.update({
            'url': user.url,
            'absolute_url': user.absolute_url,
            'display_absolute_url': user.display_absolute_url,
            'date_registered': user.date_registered.strftime('%Y-%m-%d'),
        })

    if full:
        # Add emails
        if is_profile:
            ret['emails'] = [
                {
                    'address': each,
                    'primary': each.strip().lower() == user.username.strip().lower(),
                    'confirmed': True,
                } for each in user.emails.values_list('address', flat=True)
            ] + [
                {
                    'address': each,
                    'primary': each.strip().lower() == user.username.strip().lower(),
                    'confirmed': False
                }
                for each in user.get_unconfirmed_emails_exclude_external_identity()
            ]

        if user.is_merged:
            merger = user.merged_by
            merged_by = {
                'id': str(merger._primary_key),
                'url': merger.url,
                'absolute_url': merger.absolute_url
            }
        else:
            merged_by = None

        default_region = user.get_addon('osfstorage').default_region
        available_regions = [region for region in Region.objects.all().values('_id', 'name')]
        ret.update({
            'activity_points': user.get_activity_points(),
            'profile_image_url': user.profile_image_url(size=settings.PROFILE_IMAGE_LARGE),
            'is_merged': user.is_merged,
            'available_regions': available_regions,
            'storage_flag_is_active': storage_i18n_flag_active(),
            'default_region': {'name': default_region.name, '_id': default_region._id},
            'merged_by': merged_by,
        })
        if include_node_counts:
            projects = user.nodes.exclude(is_deleted=True).filter(type='osf.node').get_roots()
            ret.update({
                'number_projects': projects.count(),
                'number_public_projects': projects.filter(is_public=True).count(),
            })

    return ret