コード例 #1
0
def _via_hydroshare(request, resource, callback, errback):
    """
    Tries to match a HydroShare resource to a project_id, and if found, calls
    the success callback with it, else calls the error callback. The callback
    is returned to the caller.

    :param request: The Django Request object
    :param resource: String of HydroShare Resource ID
    :param callback: Function that takes project_id and does something
    :param errback: Function that takes nothing and does something
    :return: Output of the called callback
    """

    # Try to match resource to a project
    try:
        hsresource = HydroShareResource.objects.get(resource=resource)
        project_id = hsresource.project_id
    except HydroShareResource.DoesNotExist:
        project_id = None

    if project_id:
        return callback(project_id)

    # If no matching project found, try and fetch project snapshot directly
    snapshot_url = '{base_url}resource/{resource}/{snapshot_path}'.format(
        base_url=settings.HYDROSHARE['base_url'],
        resource=resource,
        snapshot_path='data/contents/mmw_project_snapshot.json')

    response = requests.get(snapshot_url)

    if response.status_code == 200:
        snapshot_json = response.json()
        if snapshot_json:
            project_id = snapshot_json['id'] if 'id' in snapshot_json else None
            if project_id:
                return callback(project_id)

    # If project snapshot couldn't be fetched directly, try fetching it as
    # a HydroShare user. This is useful for cases when an existing resource
    # is copied, since the copy isn't public by default.
    if request.user.is_authenticated:
        # Make sure the user has linked their account to HydroShare
        try:
            HydroShareToken.objects.get(user_id=request.user.id)
        except HydroShareToken.DoesNotExist:
            return errback()

        hss = HydroShareService()
        hs = hss.get_client(request.user.id)

        snapshot_json = hs.get_project_snapshot(resource)
        if snapshot_json:
            project_id = snapshot_json['id'] if 'id' in snapshot_json else None
            if project_id:
                return callback(project_id)

    return errback()
コード例 #2
0
@decorators.permission_classes((IsAuthenticated, ))
def change_password(request):
    form = PasswordChangeForm(user=request.user, data=request.POST)
    if form.is_valid():
        form.save()
        update_session_auth_hash(request, form.user)
        response_data = {'result': 'success'}
        status_code = status.HTTP_200_OK
    else:
        response_data = {'errors': form.errors.values()}
        status_code = status.HTTP_400_BAD_REQUEST

    return Response(data=response_data, status=status_code)


hss = HydroShareService()


@decorators.permission_classes((IsAuthenticated, ))
def hydroshare_login(request):
    redirect_uri = request.build_absolute_uri(reverse('user:hydroshare_auth'))
    params = {'redirect_uri': redirect_uri, 'response_type': 'code'}
    auth_url = hss.get_authorize_url(**params)
    return redirect(auth_url)


@decorators.permission_classes((IsAuthenticated, ))
def hydroshare_auth(request):
    context = get_context(request)

    code = request.GET.get('code')
コード例 #3
0
    def callback(project_id):
        project = get_object_or_404(Project, id=project_id)

        # Check to see if we should associate with given resource
        try:
            hsresource = HydroShareResource.objects.get(project_id=project_id)
        except HydroShareResource.DoesNotExist:
            hsresource = None

        if hsresource and hsresource.resource == resource:
            # Use case (1). The user owns this exact project, so we show it.
            if request.user == project.user:
                return redirect(f'/project/{project_id}/')

            # Use case (2). This is a different user trying to edit a project
            # they don't own, so we clone it to their account.
            return redirect(f'/project/{project_id}/clone')

        # Use cases (3) and (4). This is a copy in HydroShare that needs a
        # corresponding new copy in MMW. Fetch that resource's details.

        # Make sure the user has linked their account to HydroShare
        try:
            HydroShareToken.objects.get(user_id=request.user.id)
        except HydroShareToken.DoesNotExist:
            return redirect('/error/hydroshare-not-found')

        hss = HydroShareService()
        hs = hss.get_client(request.user.id)

        # Get specified resource info
        hstitle = hs.getSystemMetadata(resource)['resource_title']
        snapshot = hs.get_project_snapshot(resource)

        try:
            with transaction.atomic():
                # Copy the project
                project.pk = None
                project.user = request.user
                project.save()

                # Copy each scenario
                for scenario in Scenario.objects \
                        .filter(project_id=project_id) \
                        .order_by('created_at'):
                    scenario.pk = None
                    scenario.project = project
                    scenario.save()

                # If the current user owns that resource on HydroShare,
                # update it to point to new project and map project to it
                try:
                    # Update project snapshot to refer to new project
                    snapshot['id'] = project.id
                    hs.add_files(resource, [{
                        'name': 'mmw_project_snapshot.json',
                        'contents': json.dumps(snapshot),
                    }],
                                 overwrite=True)

                    # Create a HydroShareResource mapping
                    hsr = HydroShareResource.objects.create(
                        project=project,
                        resource=resource,
                        title=hstitle,
                        autosync=False,
                        exported_at=now(),
                    )
                    hsr.save()
                except HydroShareNotAuthorized:
                    # If the current user cannot update the resource
                    # from which this project was created, don't associate it
                    pass

                return redirect(f'/project/{project.id}')

        except IntegrityError:
            return redirect('/error/hydroshare-not-found')