Beispiel #1
0
def authorize(request, page=None, edit=False, add=False, delete=False, view=False, do_raise=True):
    if isinstance(page, basestring):
        page = Page.objects.get(slug=page).get_content_model()

    user = get_user(request)
    request.user = user
    auth = True

    if auth and page is not None:
        request.user = user
        if edit:
            auth = page.can_change(request)
        if add:
            auth = auth and page.can_add(request)
        if delete:
            auth = auth and page.can_delete(request)
        elif view:
            auth = auth and (not hasattr(page, 'can_view')) or \
                   (auth and hasattr(page, 'can_view') and page.can_view(request))

    if do_raise and not auth:
        raise PermissionDenied(json.dumps({
            "error": "Unauthorized",
            "user": user.email if user.is_authenticated() else None,
            "page": page.slug if page else None,
            "edit": edit,
            "add": add,
            "delete": delete,
            "view": view
        }))

    return user
def _check_webapp_in_user_open_with_list(tool_res_obj, request_obj):

    if request_obj.user.is_authenticated():
        user_obj = get_user(request_obj)
        return tool_res_obj.rlabels.is_open_with_app(user_obj)
    else:
        return False
Beispiel #3
0
    def can_view(self, request):
        user = get_user(request)

        if self.public or not self.owner:
            return True
        if user.is_authenticated():
            if not self.owner:
                return user.is_superuser
            elif user.pk == self.owner.pk:
                return True
            else:
                users = self.view_users
                groups = self.view_groups

                if len(users) > 0 and user.pk in users:
                    return True
                elif len(groups) > 0:
                    return user.groups.filter(pk__in=groups).exists()
                else:
                    return False
        else:
            return False
Beispiel #4
0
    def can_view(self, request):
        user = get_user(request)

        if self.public or not self.owner:
            return True
        if user.is_authenticated():
            if not self.owner:
                return user.is_superuser
            elif user.pk == self.owner.pk:
                return True
            else:
                users = self.view_users
                groups = self.view_groups

                if len(users) > 0 and user.pk in users:
                    return True
                elif len(groups) > 0:
                    return user.groups.filter(pk__in=groups).exists()
                else:
                    return False
        else:
            return False
Beispiel #5
0
    def can_change(self, request):
        user = get_user(request)

        ret = True

        if user.is_authenticated():
            if not self.owner:
                ret = user.is_superuser
            elif user.pk == self.owner.pk:
                ret = True
            else:
                users = self.edit_users
                groups = self.edit_groups

                if len(users) > 0 and user.pk in users:
                    ret = True
                elif len(groups) > 0:
                    ret = user.groups.filter(pk__in=groups).exists()
                else:
                    ret = False
        else:
            ret = False

        return ret
Beispiel #6
0
    def can_change(self, request):
        user = get_user(request)

        ret = True

        if user.is_authenticated():
            if not self.owner:
                ret = user.is_superuser
            elif user.pk == self.owner.pk:
                ret = True
            else:
                users = self.edit_users
                groups = self.edit_groups

                if len(users) > 0 and user.pk in users:
                    ret = True
                elif len(groups) > 0:
                    ret = user.groups.filter(pk__in=groups).exists()
                else:
                    ret = False
        else:
            ret = False

        return ret
Beispiel #7
0
def authorize(request, res_id, needed_permission=ACTION_TO_AUTHORIZE.VIEW_RESOURCE,
              raises_exception=True):
    """
    This function checks if a user has authorization for resource related actions as outlined
    below. This function doesn't check authorization for user sharing resource with another user.

    How this function should be called for different actions on a resource by a specific user?
    1. User wants to view a resource (both metadata and content files) which includes
       downloading resource bag or resource content files:
       authorize(request, res_id=id_of_resource,
       needed_permission=ACTION_TO_AUTHORIZE.VIEW_RESOURCE)
    2. User wants to view resource metadata only:
       authorize(request, res_id=id_of_resource,
       needed_permission=ACTION_TO_AUTHORIZE.VIEW_METADATA)
    3. User wants to edit a resource which includes:
       a. edit metadata
       b. add file to resource
       c. delete a file from the resource
       authorize(request, res_id=id_of_resource,
       needed_permission=ACTION_TO_AUTHORIZE.EDIT_RESOURCE)
    4. User wants to set resource flag (public, published, shareable etc):
       authorize(request, res_id=id_of_resource,
       needed_permission=ACTION_TO_AUTHORIZE.SET_RESOURCE_FLAG)
    5. User wants to delete a resource:
       authorize(request, res_id=id_of_resource,
       needed_permission=ACTION_TO_AUTHORIZE.DELETE_RESOURCE)
    6. User wants to create new version of a resource:
       authorize(request, res_id=id_of_resource,
       needed_permission=ACTION_TO_AUTHORIZE.CREATE_RESOURCE_VERSION)

    Note: resource 'shareable' status has no effect on authorization
    """
    authorized = False
    user = get_user(request)

    try:
        res = hydroshare.utils.get_resource_by_shortkey(res_id, or_404=False)
    except ObjectDoesNotExist:
        raise NotFound(detail="No resource was found for resource id:%s" % res_id)

    if needed_permission == ACTION_TO_AUTHORIZE.VIEW_METADATA:
        if res.raccess.discoverable or res.raccess.public:
            authorized = True
        elif user.is_authenticated() and user.is_active:
            authorized = user.uaccess.can_view_resource(res)
    elif user.is_authenticated() and user.is_active:
        if needed_permission == ACTION_TO_AUTHORIZE.VIEW_RESOURCE:
            authorized = user.uaccess.can_view_resource(res)
        elif needed_permission == ACTION_TO_AUTHORIZE.EDIT_RESOURCE:
            authorized = user.uaccess.can_change_resource(res)
        elif needed_permission == ACTION_TO_AUTHORIZE.DELETE_RESOURCE:
            authorized = user.uaccess.can_delete_resource(res)
        elif needed_permission == ACTION_TO_AUTHORIZE.SET_RESOURCE_FLAG:
            authorized = user.uaccess.can_change_resource_flags(res)
        elif needed_permission == ACTION_TO_AUTHORIZE.CREATE_RESOURCE_VERSION:
            authorized = user.uaccess.owns_resource(res)
        elif needed_permission == ACTION_TO_AUTHORIZE.VIEW_RESOURCE_ACCESS:
            authorized = user.uaccess.can_view_resource(res)
        elif needed_permission == ACTION_TO_AUTHORIZE.EDIT_RESOURCE_ACCESS:
            authorized = user.uaccess.can_share_resource(res, 2)
    elif needed_permission == ACTION_TO_AUTHORIZE.VIEW_RESOURCE:
        authorized = res.raccess.public

    if raises_exception and not authorized:
        raise PermissionDenied()
    else:
        return res, authorized, user
def _check_webapp_in_user_open_with_list(tool_res_obj, request_obj):
    if request_obj.user.is_authenticated():
        user_obj = get_user(request_obj)
        return tool_res_obj.rlabels.is_open_with_app(user_obj)
    else:
        return False
def create_scidas_virtual_app(request, res_id, cluster):
    user = get_user(request)
    if not user.is_authenticated() or not user.is_active:
        messages.error(
            request,
            "Only authorized user can make appliance provision request.")
        return HttpResponseRedirect(request.META['HTTP_REFERER'])

    res, _, _ = authorize(request,
                          res_id,
                          needed_permission=ACTION_TO_AUTHORIZE.VIEW_RESOURCE)
    cluster_name = cluster
    if cluster_name != 'chameleon' and cluster_name != 'aws' and cluster_name != 'azure':
        cluster_name = ''
    file_data_list = []
    p_data = {}
    file_path = '/' + ds.IRODS_ZONE + '/home/' + ds.IRODS_USERNAME
    for rf in ResourceFile.objects.filter(object_id=res.id):
        fname = ''
        if rf.resource_file.name:
            fname = os.path.join(file_path, rf.resource_file.name)
        elif rf.fed_resource_file.name:
            fname = rf.fed_resource_file.name
        if fname:
            file_data_list.append(fname)
            if fname.endswith('.json') and not p_data:
                temp_json_file = get_file_from_irods(rf)
                with open(temp_json_file, 'r') as fp:
                    jdata = load(fp)
                    if 'id' in jdata and 'containers' in jdata:
                        p_data = jdata

    url = settings.PIVOT_URL
    app_id = user.username + '_cs_app_id'
    preset_url = ''
    if not p_data:
        p_data = {
            "id":
            app_id,
            "containers": [{
                "id":
                app_id,
                "image":
                "scidas/irods-jupyter-hydroshare",
                "resources": {
                    "cpus": 2,
                    "mem": 2048
                },
                "port_mappings": [{
                    "container_port": 8888,
                    "host_port": 0,
                    "protocol": "tcp"
                }],
                "args": ["--ip=0.0.0.0", "--NotebookApp.token=\"\""],
                "data":
                file_data_list
            }]
        }
    else:
        app_id = p_data['id']
        p_data['containers'][0]['data'] = file_data_list

    if cluster_name:
        p_data['containers'][0]['cluster'] = cluster_name

    if 'endpoints' in p_data['containers'][0]:
        if p_data['containers'][0]['endpoints']:
            preset_ep_data = p_data['containers'][0]['endpoints'][0]
            preset_url = 'http://' + preset_ep_data['host'] + ':' + str(
                preset_ep_data['host_port'])

    # delete the appliance before posting to create a new one in case it already exists
    app_url = url + '/' + app_id
    response = requests.delete(app_url)
    is_deleted = False
    if response.status_code != status.HTTP_404_NOT_FOUND and \
           response.status_code != status.HTTP_200_OK:
        idx = 0
        while idx < 2:
            get_response = requests.get(app_url)
            idx += 1
            if get_response.status_code == status.HTTP_404_NOT_FOUND:
                is_deleted = True
                break
            else:
                # appliance is not deleted successfully yet, wait and poll
                # again one more time
                time.sleep(2)
    else:
        is_deleted = True
    if not is_deleted:
        errmsg = 'The old appliance ' + app_id + ' cannot be deleted successfully'
        messages.error(request, errmsg)
        return HttpResponseRedirect(request.META['HTTP_REFERER'])

    response = requests.post(url, data=dumps(p_data))
    if response.status_code != status.HTTP_200_OK and \
            response.status_code != status.HTTP_201_CREATED:
        return HttpResponseBadRequest(content=response.text)
    while True:
        response = requests.get(app_url)
        if not response.status_code == status.HTTP_200_OK:
            return HttpResponseBadRequest(content=response.text)
        return_data = loads(response.content)
        con_ret_data_list = return_data['containers']
        con_ret_data = con_ret_data_list[0]
        con_state = con_ret_data['state']
        ep_data_list = con_ret_data['endpoints']
        if con_state == 'running' and (ep_data_list or preset_url):
            break
        else:
            # the jupyter appliance is not ready yet, need to wait and poll again
            time.sleep(2)

    if preset_url:
        app_url = preset_url
    else:
        ep_data = ep_data_list[0]
        app_url = 'http://' + ep_data['host'] + ':' + str(ep_data['host_port'])

    # make sure the new directed url is loaded and working before redirecting.
    # Since scidas will install dependencies included in requirements.txt, it will take some time
    # before the app_url is ready to go after the appliance is provisioned, hence wait for up to 30 seconds
    # before erroring out if connection to the url keeps being refused.
    idx = 0
    while True:
        try:
            ret = urlopen(app_url, timeout=10)
            break
        except URLError as ex:
            errmsg = ex.reason if hasattr(ex, 'reason') else 'URLError'
            idx += 1
            time.sleep(5)

        if idx > 6:
            messages.error(request, errmsg)
            return HttpResponseRedirect(request.META['HTTP_REFERER'])

    if ret.code == 200:
        return HttpResponseRedirect(app_url)
    else:
        messages.error(request, 'time out error')
        return HttpResponseRedirect(request.META['HTTP_REFERER'])