def complement_resources(configuration, job, vgrid, resources): """Returns a set of allowed resources where those specified-and-allowed have been subtracted. A job submitted to a VGrid must be executed by a resource from that VGrid. """ allowed_resources = set() if vgrid == default_vgrid: allowed_resources = set(default_vgrid_resources(configuration)) else: (status, vgrid_res) = vgrid_resources(vgrid, configuration) if not status: vgrid_res = [] allowed_resources = set(vgrid_res) return allowed_resources.difference(resources)
def validate_resource(configuration, job, vgrid, errors): """Returns a list of user specified resources that are allowed. A job submitted to a VGrid must be executed by a resource from that VGrid. """ allowed_resources = set() if vgrid == default_vgrid: allowed_resources = set(default_vgrid_resources(configuration)) else: (status, vgrid_res) = vgrid_resources(vgrid, configuration) if not status: vgrid_res = [] allowed_resources = set(vgrid_res) if skip_validation(configuration, job, 'RESOURCE'): # all allowed, possibly empty return list(allowed_resources) specified_resources = anon_to_real_resources(configuration, job['RESOURCE']) not_allowed = specified_resources.difference(allowed_resources) if not_allowed: anon_not_allowed = real_to_anon_resources(configuration, not_allowed) errors['RESOURCE'] = \ 'The following resources are illegal for VGrid %s:, %s' \ % (vgrid, list(anon_not_allowed)) if not allowed_resources.intersection(specified_resources): # all allowed, possibly [] return list(allowed_resources) else: #validated specifed and allowed return list(allowed_resources.intersection(specified_resources))
def validate_resource(configuration, job, vgrid, errors): """Returns a list of user specified resources that are allowed. A job submitted to a VGrid must be executed by a resource from that VGrid. """ allowed_resources = set() if vgrid == default_vgrid: allowed_resources = set(default_vgrid_resources(configuration)) else: (status, vgrid_res) = vgrid_resources(vgrid, configuration) if not status: vgrid_res = [] allowed_resources = set(vgrid_res) if skip_validation(configuration, job, 'RESOURCE'): # all allowed, possibly empty return list(allowed_resources) specified_resources = anon_to_real_resources(configuration, job['RESOURCE']) not_allowed = specified_resources.difference(allowed_resources) if not_allowed: anon_not_allowed = real_to_anon_resources(configuration, not_allowed) errors['RESOURCE'] = \ 'The following resources are illegal for VGrid %s:, %s' \ % (vgrid, list(anon_not_allowed)) if not allowed_resources.intersection(specified_resources): # all allowed, possibly [] return list(allowed_resources) else: # validated specifed and allowed return list(allowed_resources.intersection(specified_resources))
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] title_entry = find_entry(output_objects, 'title') label = "%s" % configuration.site_vgrid_label title_entry['text'] = "Remove %s Owner" % label output_objects.append({'object_type': 'header', 'text': 'Remove %s Owner' % label}) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) vgrid_name = accepted['vgrid_name'][-1] flags = ''.join(accepted['flags']) cert_id = accepted['cert_id'][-1] cert_dir = client_id_dir(cert_id) # inherited vgrid membership inherit_vgrid_member = False if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append( {'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) # always allow owner to remove self if client_id != cert_id: user_map = get_full_user_map(configuration) user_dict = user_map.get(client_id, None) # Optional site-wide limitation of manage vgrid permission if not user_dict or \ not vgrid_manage_allowed(configuration, user_dict): logger.warning("user %s is not allowed to manage vgrids!" % client_id) output_objects.append( {'object_type': 'error_text', 'text': 'Only privileged users can manage %ss' % label}) return (output_objects, returnvalues.CLIENT_ERROR) # make sure vgrid settings allow this owner to edit other owners (allow_status, allow_msg) = allow_owners_adm(configuration, vgrid_name, client_id) if not allow_status: output_objects.append({'object_type': 'error_text', 'text': allow_msg}) return (output_objects, returnvalues.CLIENT_ERROR) # Validity of user and vgrid names is checked in this init function so # no need to worry about illegal directory traversal through variables (ret_val, msg, _) = \ init_vgrid_script_add_rem(vgrid_name, client_id, cert_id, 'owner', configuration) if not ret_val: output_objects.append({'object_type': 'error_text', 'text': msg}) return (output_objects, returnvalues.CLIENT_ERROR) # don't remove if not already an owner if not vgrid_is_owner(vgrid_name, cert_id, configuration): logger.warning('%s is not allowed to remove owner %s from %s' % (client_id, cert_id, vgrid_name)) output_objects.append({'object_type': 'error_text', 'text': '%s is not an owner of %s or a parent %s.' % (cert_id, vgrid_name, label)}) return (output_objects, returnvalues.CLIENT_ERROR) # we need the local owners file to detect inherited ownerships (owners_status, owners_direct) = vgrid_owners(vgrid_name, configuration, False) (all_status, owners) = vgrid_owners(vgrid_name, configuration, True) if not owners_status or not all_status: logger.error('Error loading owners for %s: %s / %s' % (vgrid_name, owners_direct, owners)) output_objects.append( {'object_type': 'error_text', 'text': 'An internal error occurred, error conditions have been logged.'}) output_objects.append({'object_type': 'text', 'text': ''' You can help us fix the problem by notifying the administrators via mail about what you wanted to do when the error happened.'''}) return (output_objects, returnvalues.CLIENT_ERROR) logger.info('%s removing owner %s from %s' % (client_id, cert_id, vgrid_name)) # find out whether to just remove an owner or delete the whole thing. # ask about delete if last or no direct owners. if len(owners_direct) > 1: logger.debug('Removing %s, one of several owners, from %s.' % (cert_id, vgrid_name)) if not (cert_id in owners_direct): # the owner owns an upper vgrid, ownership is inherited # cannot remove, not last (inherited) owner logger.warning('Cannot delete: Inherited ownership.' + '\n Owners: %s,\n Direct owners: %s.' % (owners, owners_direct)) output_objects.append({'object_type': 'error_text', 'text': '''%s is owner of a parent %s. Owner removal has to be performed at the topmost vgrid''' % (cert_id, label)}) return (output_objects, returnvalues.CLIENT_ERROR) else: # Remove any tracker admin rights if configuration.trac_admin_path: public_tracker_dir = \ os.path.abspath(os.path.join( configuration.vgrid_public_base, vgrid_name, '.vgridtracker')) private_tracker_dir = \ os.path.abspath(os.path.join( configuration.vgrid_private_base, vgrid_name, '.vgridtracker')) vgrid_tracker_dir = \ os.path.abspath(os.path.join( configuration.vgrid_files_home, vgrid_name, '.vgridtracker')) for tracker_dir in [public_tracker_dir, private_tracker_dir, vgrid_tracker_dir]: if not rm_tracker_admin(configuration, cert_id, vgrid_name, tracker_dir, output_objects): return (output_objects, returnvalues.SYSTEM_ERROR) user_dir = os.path.abspath(os.path.join(configuration.user_home, cert_dir)) + os.sep # Do not touch vgrid share if still a member of a parent vgrid if vgrid_is_member(vgrid_name, cert_id, configuration): # list is in top-down order parent_vgrids = vgrid_list_parents(vgrid_name, configuration) inherit_vgrid_member = vgrid_name for parent in parent_vgrids: if vgrid_is_member(parent, cert_id, configuration, recursive=False): inherit_vgrid_member = parent break output_objects.append( {'object_type': 'text', 'text': '''NOTE: %s is still a member of parent %s %s. Preserving access to corresponding %s.''' % (cert_id, label, inherit_vgrid_member, label)}) else: (success, msg) = unlink_share(user_dir, vgrid_name) if not success: logger.error('Could not remove share link: %s.' % msg) output_objects.append({'object_type': 'error_text', 'text': 'Could not remove share links: %s.' % msg}) return (output_objects, returnvalues.SYSTEM_ERROR) # unlink shared web folders (success, msg) = unlink_web_folders(user_dir, vgrid_name) if not success: logger.error('Could not remove web links: %s.' % msg) output_objects.append({'object_type': 'error_text', 'text': 'Could not remove web links: %s.' % msg}) return (output_objects, returnvalues.SYSTEM_ERROR) # remove user from saved owners list (rm_status, rm_msg) = vgrid_remove_owners(configuration, vgrid_name, [cert_id]) if not rm_status: output_objects.append({'object_type': 'error_text', 'text': '%s of owners of %s' % (rm_msg, vgrid_name)}) return (output_objects, returnvalues.SYSTEM_ERROR) # Any parent vgrid membership is left untouched here as we only # force a normal refresh in unmap_inheritance unmap_inheritance(configuration, vgrid_name, cert_id) output_objects.append({'object_type': 'text', 'text': '%s successfully removed as owner of %s!' % (cert_id, vgrid_name)}) output_objects.append({'object_type': 'link', 'destination': 'adminvgrid.py?vgrid_name=%s' % vgrid_name, 'text': 'Back to administration for %s' % vgrid_name}) return (output_objects, returnvalues.OK) else: # no more direct owners - we try to remove this VGrid logger.debug('Leave %s from %s with no more direct owners: delete' % (vgrid_name, cert_id)) if not force(flags): output_objects.append({'object_type': 'text', 'text': ''' No more direct owners of %s - leaving will result in the %s getting deleted. Please use either of the links below to confirm or cancel. ''' % (vgrid_name, label)}) # Reuse csrf token from this request target_op = 'rmvgridowner' js_name = target_op csrf_token = accepted[csrf_field][-1] helper = html_post_helper(js_name, '%s.py' % target_op, {'vgrid_name': vgrid_name, 'cert_id': cert_id, 'flags': 'f', csrf_field: csrf_token}) output_objects.append({'object_type': 'html_form', 'text': helper}) output_objects.append({'object_type': 'link', 'destination': "javascript: %s();" % js_name, 'class': 'removelink iconspace', 'text': 'Really leave and delete %s' % vgrid_name}) output_objects.append({'object_type': 'text', 'text': ''}) output_objects.append({'object_type': 'link', 'destination': 'adminvgrid.py?vgrid_name=%s' % vgrid_name, 'text': 'Back to administration for %s' % vgrid_name}) return (output_objects, returnvalues.OK) # check if any resources participate or sub-vgrids depend on this one (list_status, subs) = vgrid_list_subvgrids(vgrid_name, configuration) if not list_status: logger.error('Error loading sub-vgrid for %s: %s)' % (vgrid_name, subs)) output_objects.append({'object_type': 'error_text', 'text': ''' An internal error occurred, error conditions have been logged.'''}) output_objects.append({'object_type': 'text', 'text': ''' You can help us fix the problem by notifying the administrators via mail about what you wanted to do when the error happened.'''}) return (output_objects, returnvalues.CLIENT_ERROR) if len(subs) > 0: logger.debug('Cannot delete: still has sub-vgrids: %s' % subs) output_objects.append( {'object_type': 'error_text', 'text': '%s has one or more child %ss and cannot be deleted.' % (vgrid_name, label)}) output_objects.append( {'object_type': 'text', 'text': '''To leave (and delete) %s first remove all its children: %s.''' % (vgrid_name, ', '.join(subs))}) return (output_objects, returnvalues.CLIENT_ERROR) # we consider the local members and resources here, not inherited ones (member_status, members_direct) = vgrid_members(vgrid_name, configuration, False) (resource_status, resources_direct) = vgrid_resources(vgrid_name, configuration, False) if not member_status or not resource_status: logger.warning('failed to load %s members or resources: %s %s' % (vgrid_name, members_direct, resources_direct)) output_objects.append( {'object_type': 'error_text', 'text': 'could not load %s members or resources for %s.' % (label, vgrid_name)}) return (output_objects, returnvalues.SYSTEM_ERROR) if len(resources_direct) > 0: logger.debug('Cannot delete: still has direct resources %s.' % resources_direct) output_objects.append( {'object_type': 'error_text', 'text': '%s still has resources and cannot be deleted.' % vgrid_name}) output_objects.append({'object_type': 'text', 'text': ''' To leave (and delete) %s, first remove the participating resources.''' % vgrid_name}) return (output_objects, returnvalues.CLIENT_ERROR) if len(members_direct) > 0: logger.debug('Cannot delete: still has direct members %s.' % members_direct) output_objects.append( {'object_type': 'error_text', 'text': '%s still has members and cannot be deleted.' % vgrid_name}) output_objects.append({'object_type': 'text', 'text': ''' To leave (and delete) %s, first remove all members.''' % vgrid_name}) return (output_objects, returnvalues.CLIENT_ERROR) # Deleting write restricted VGrid is not allowed (load_status, saved_settings) = vgrid_settings(vgrid_name, configuration, recursive=True, as_dict=True) if not load_status: output_objects.append( {'object_type': 'error_text', 'text': 'failed to load saved %s settings' % vgrid_name}) return (output_objects, returnvalues.SYSTEM_ERROR) if saved_settings.get('write_shared_files', keyword_members) != \ keyword_members: logger.warning("%s can't delete vgrid %s - write limited!" % (client_id, vgrid_name)) output_objects.append( {'object_type': 'error_text', 'text': """You can't delete write-restricted %ss - first remove any write restrictions for shared files on the admin page and then try again.""" % label}) return (output_objects, returnvalues.CLIENT_ERROR) # When reaching here, OK to remove the VGrid. # if top-level: unlink, remove all files and directories, # in all cases: remove configuration entry for the VGrid # unlink and move new-style vgrid sub dir to parent logger.info('Deleting %s and all related data as requested by %s' % (vgrid_name, cert_id)) if (cert_id in owners_direct): # owner owns this vgrid, direct ownership logger.debug('%s looks like a top-level vgrid.' % vgrid_name) logger.debug('Deleting all related files.') user_dir = os.path.abspath(os.path.join(configuration.user_home, cert_dir)) + os.sep (share_lnk, share_msg) = unlink_share(user_dir, vgrid_name) (web_lnk, web_msg) = unlink_web_folders(user_dir, vgrid_name) (files_act, files_msg) = abandon_vgrid_files(vgrid_name, configuration) else: # owner owns some parent vgrid - ownership is only inherited logger.debug('%s looks like a sub-vgrid, ownership inherited.' % vgrid_name) logger.debug('Only removing entry, leaving files in place.') share_lnk, share_msg = True, '' web_lnk, web_msg = True, '' (files_act, files_msg) = inherit_vgrid_files(vgrid_name, configuration) (removed, entry_msg) = remove_vgrid_entry(vgrid_name, configuration) output_objects.append({'object_type': 'text', 'text': '%s has been removed with last owner.' % vgrid_name}) output_objects.append({'object_type': 'link', 'destination': 'vgridman.py', 'text': 'Back to the overview.'}) if not share_lnk or not web_lnk or not files_act or not removed: err = '\n'.join([share_msg, web_msg, files_msg, entry_msg]) logger.error('Errors while removing %s:\n%s.' % (vgrid_name, err)) output_objects.append({'object_type': 'error_text', 'text': ''' An internal error occurred, error conditions have been logged.'''}) output_objects.append({'object_type': 'text', 'text': ''' You can help us fix the problem by notifying the administrators via mail about what you wanted to do when the error happened.'''}) return (output_objects, returnvalues.CLIENT_ERROR) else: # Remove vgrid from vgrid cache (after deleting all) unmap_vgrid(configuration, vgrid_name) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] title_entry = find_entry(output_objects, 'title') label = "%s" % configuration.site_vgrid_label title_entry['text'] = "%s Details" % label output_objects.append({'object_type': 'header', 'text': 'Show %s Details' % label}) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) vgrid_list = accepted['vgrid_name'] status = returnvalues.OK vgrid_access = user_vgrid_access(configuration, client_id) for vgrid_name in vgrid_list: vgrid_dict = {'vgrid_name': vgrid_name} (settings_status, settings_dict) = vgrid_settings(vgrid_name, configuration, recursive=True, as_dict=True) if not settings_status: settings_dict = {} logger.info("loaded vgrid %s settings: %s" % (vgrid_name, settings_dict)) vgrid_dict.update(settings_dict) if user_view_access(configuration, vgrid_name, client_id, settings_dict, 'visible_owners'): (owners_status, owners) = vgrid_owners(vgrid_name, configuration) if owners_status: vgrid_dict['owners'] = owners if user_view_access(configuration, vgrid_name, client_id, settings_dict, 'visible_members'): (members_status, members) = vgrid_members(vgrid_name, configuration) if members_status: vgrid_dict['members'] = members if user_view_access(configuration, vgrid_name, client_id, settings_dict, 'visible_resources'): (res_status, resources) = vgrid_resources(vgrid_name, configuration) if res_status: vgrid_dict['resources'] = resources if user_view_access(configuration, vgrid_name, client_id, settings_dict, 'create_sharelink'): vgrid_dict['sharelink'] = settings_dict.get('create_sharelink', keyword_owners) # Report no such vgrid if hidden if settings_dict.get('hidden', False) and \ not client_id in vgrid_dict.get('owners', []): output_objects.append({'object_type': 'error_text', 'text': 'No such %s: %s' % (label, vgrid_name)}) status = returnvalues.CLIENT_ERROR continue # Show vgrid details based on participation and visibility settings vgrid_item = build_vgriditem_object_from_vgrid_dict(configuration, vgrid_name, vgrid_dict, vgrid_access) output_objects.append(vgrid_item) if client_id in vgrid_dict.get('owners', []): output_objects.append({'object_type': 'sectionheader', 'text': 'Administrate'}) output_objects.append({'object_type': 'link', 'destination': 'adminvgrid.py?vgrid_name=%s' % vgrid_name, 'class': 'adminlink iconspace', 'title': 'Administrate %s' % vgrid_name, 'text': 'Administrate %s' % vgrid_name, }) return (output_objects, status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] title_entry = find_entry(output_objects, 'title') label = "%s" % configuration.site_vgrid_label title_entry['text'] = "Administrate %s" % label # NOTE: Delay header entry here to include vgrid name (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) vgrid_name = accepted['vgrid_name'][-1] # prepare for confirm dialog, tablesort and toggling the views (css/js) # jquery support for tablesorter and confirmation on request and leave # requests table initially sorted by 0, 4, 3 (type first, then date and # with alphabetical client ID last) # sharelinks table initially sorted by 5, 4 reversed (active first and # in growing age) table_specs = [{ 'table_id': 'accessrequeststable', 'pager_id': 'accessrequests_pager', 'sort_order': '[[0,0],[4,0],[3,0]]' }, { 'table_id': 'sharelinkstable', 'pager_id': 'sharelinks_pager', 'sort_order': '[[5,1],[4,1]]' }] (add_import, add_init, add_ready) = man_base_js(configuration, table_specs, {'width': 600}) add_init += ''' var toggleHidden = function(classname) { // classname supposed to have a leading dot $(classname).toggleClass("hidden"); }; /* helpers for dynamic form input fields */ function onOwnerInputChange() { makeSpareFields("#dynownerspares", "cert_id"); } function onMemberInputChange() { makeSpareFields("#dynmemberspares", "cert_id"); } function onResourceInputChange() { makeSpareFields("#dynresourcespares", "unique_resource_name"); } ''' add_ready += ''' /* init add owners/member/resource forms with dynamic input fields */ onOwnerInputChange(); $("#dynownerspares").on("blur", "input[name=cert_id]", function(event) { //console.debug("in add owner blur handler"); onOwnerInputChange(); } ); onMemberInputChange(); $("#dynmemberspares").on("blur", "input[name=cert_id]", function(event) { //console.debug("in add member blur handler"); onMemberInputChange(); } );''' if configuration.site_enable_resources: add_ready += ''' onResourceInputChange(); $("#dynresourcespares").on("blur", "input[name=unique_resource_name]", function(event) { console.debug("in resource blur handler"); onResourceInputChange(); } ); ''' title_entry['script']['advanced'] += add_import title_entry['script']['init'] += add_init title_entry['script']['ready'] += add_ready output_objects.append({ 'object_type': 'html_form', 'text': man_base_html(configuration) }) form_method = 'post' csrf_limit = get_csrf_limit(configuration) fill_helpers = { 'short_title': configuration.short_title, 'vgrid_label': label, 'form_method': form_method, 'csrf_field': csrf_field, 'csrf_limit': csrf_limit } output_objects.append({ 'object_type': 'header', 'text': "Administrate '%s'" % vgrid_name }) if not vgrid_is_owner(vgrid_name, client_id, configuration): output_objects.append({ 'object_type': 'error_text', 'text': 'Only owners of %s can administrate it.' % vgrid_name }) target_op = "sendrequestaction" csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) js_name = 'reqvgridowner%s' % hexlify(vgrid_name) helper = html_post_helper( js_name, '%s.py' % target_op, { 'vgrid_name': vgrid_name, 'request_type': 'vgridowner', 'request_text': '', csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) output_objects.append({ 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s', '%s');" % (js_name, "Request ownership of " + vgrid_name + ":<br/>" + "\nPlease write a message to the owners below.", 'request_text'), 'class': 'addadminlink iconspace', 'title': 'Request ownership of %s' % vgrid_name, 'text': 'Apply to become an owner' }) return (output_objects, returnvalues.SYSTEM_ERROR) for (item, scr) in zip(['owner', 'member', 'resource'], ['vgridowner', 'vgridmember', 'vgridres']): if item == 'resource' and not configuration.site_enable_resources: continue output_objects.append({ 'object_type': 'sectionheader', 'text': "%ss" % item.title() }) (init_status, oobjs) = vgrid_add_remove_table(client_id, vgrid_name, item, scr, configuration) if not init_status: output_objects.extend(oobjs) return (output_objects, returnvalues.SYSTEM_ERROR) else: output_objects.append({ 'object_type': 'html_form', 'text': '<div class="div-%s">' % item }) output_objects.append({ 'object_type': 'link', 'destination': "javascript:toggleHidden('.div-%s');" % item, 'class': 'removeitemlink iconspace', 'title': 'Toggle view', 'text': 'Hide %ss' % item.title() }) output_objects.extend(oobjs) output_objects.append({ 'object_type': 'html_form', 'text': '</div><div class="hidden div-%s">' % item }) output_objects.append({ 'object_type': 'link', 'destination': "javascript:toggleHidden('.div-%s');" % item, 'class': 'additemlink iconspace', 'title': 'Toggle view', 'text': 'Show %ss' % item.title() }) output_objects.append({ 'object_type': 'html_form', 'text': '</div>' }) # Pending requests target_op = "addvgridowner" csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( "acceptvgridownerreq", "%s.py" % target_op, { 'vgrid_name': vgrid_name, 'cert_id': '__DYNAMIC__', 'request_name': '__DYNAMIC__', csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) target_op = "addvgridmember" csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( "acceptvgridmemberreq", "%s.py" % target_op, { 'vgrid_name': vgrid_name, 'cert_id': '__DYNAMIC__', 'request_name': '__DYNAMIC__', csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) target_op = "addvgridres" csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( "acceptvgridresourcereq", "%s.py" % target_op, { 'vgrid_name': vgrid_name, 'unique_resource_name': '__DYNAMIC__', 'request_name': '__DYNAMIC__', csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) target_op = "rejectvgridreq" csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) helper = html_post_helper( "rejectvgridreq", "%s.py" % target_op, { 'vgrid_name': vgrid_name, 'request_name': '__DYNAMIC__', csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) request_dir = os.path.join(configuration.vgrid_home, vgrid_name) request_list = [] for req_name in list_access_requests(configuration, request_dir): req = load_access_request(configuration, request_dir, req_name) if not req: continue if not req.get('request_type', None) in ["vgridowner", "vgridmember", "vgridresource"]: logger.error("unexpected request_type %(request_type)s" % req) continue request_item = build_accessrequestitem_object(configuration, req) # Convert filename with exotic chars into url-friendly pure hex version shared_args = {"request_name": hexlify(req["request_name"])} accept_args, reject_args = {}, {} accept_args.update(shared_args) reject_args.update(shared_args) if req['request_type'] == "vgridresource": accept_args["unique_resource_name"] = req["entity"] else: accept_args["cert_id"] = req["entity"] request_item['acceptrequestlink'] = { 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s', %s, %s);" % ("accept%(request_type)sreq" % req, "Accept %(target)s %(request_type)s request from %(entity)s" % req, 'undefined', "{%s}" % ', '.join(["'%s': '%s'" % pair for pair in accept_args.items()])), 'class': 'addlink iconspace', 'title': 'Accept %(target)s %(request_type)s request from %(entity)s' % req, 'text': '' } request_item['rejectrequestlink'] = { 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s', %s, %s);" % ("rejectvgridreq", "Reject %(target)s %(request_type)s request from %(entity)s" % req, 'undefined', "%s" % reject_args), 'class': 'removelink iconspace', 'title': 'Reject %(target)s %(request_type)s request from %(entity)s' % req, 'text': '' } request_list.append(request_item) output_objects.append({ 'object_type': 'sectionheader', 'text': "Pending Requests" }) output_objects.append({ 'object_type': 'table_pager', 'id_prefix': 'accessrequests_', 'entry_name': 'access requests', 'default_entries': default_pager_entries }) output_objects.append({ 'object_type': 'accessrequests', 'accessrequests': request_list }) # VGrid Share links # Table columns to skip skip_list = [ 'editsharelink', 'delsharelink', 'invites', 'expire', 'single_file' ] # NOTE: Inheritance is a bit tricky for sharelinks because parent shares # only have relevance if they actually share a path that is a prefix of # vgrid_name. (share_status, share_list) = vgrid_sharelinks(vgrid_name, configuration) sharelinks = [] if share_status: for share_dict in share_list: rel_path = share_dict['path'].strip(os.sep) parent_vgrids = vgrid_list_parents(vgrid_name, configuration) include_share = False # Direct sharelinks (careful not to greedy match A/B with A/BCD) if rel_path == vgrid_name or \ rel_path.startswith(vgrid_name+os.sep): include_share = True # Parent vgrid sharelinks that in effect also give access here for parent in parent_vgrids: if rel_path == parent: include_share = True if include_share: share_item = build_sharelinkitem_object( configuration, share_dict) sharelinks.append(share_item) else: logger.warning("failed to load vgrid sharelinks for %s: %s" % (vgrid_name, share_list)) output_objects.append({ 'object_type': 'sectionheader', 'text': "Share Links" }) output_objects.append({ 'object_type': 'html_form', 'text': '<p>Current share links in %s shared folder</p>' % vgrid_name }) output_objects.append({ 'object_type': 'table_pager', 'id_prefix': 'sharelinks_', 'entry_name': 'share links', 'default_entries': default_pager_entries }) output_objects.append({ 'object_type': 'sharelinks', 'sharelinks': sharelinks, 'skip_list': skip_list }) # VGrid settings output_objects.append({'object_type': 'sectionheader', 'text': "Settings"}) (direct_status, direct_dict) = vgrid_settings(vgrid_name, configuration, recursive=False, as_dict=True) if not direct_status or not direct_dict: direct_dict = {} (settings_status, settings_dict) = vgrid_settings(vgrid_name, configuration, recursive=True, as_dict=True) if not settings_status or not settings_dict: settings_dict = {} form_method = 'post' csrf_limit = get_csrf_limit(configuration) # Always set these values settings_dict.update({ 'vgrid_name': vgrid_name, 'vgrid_label': label, 'owners': keyword_owners, 'members': keyword_members, 'all': keyword_all, 'form_method': form_method, 'csrf_field': csrf_field, 'csrf_limit': csrf_limit }) target_op = 'vgridsettings' csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) settings_dict.update({'target_op': target_op, 'csrf_token': csrf_token}) settings_form = ''' <form method="%(form_method)s" action="%(target_op)s.py"> <fieldset> <legend>%(vgrid_label)s configuration</legend> <input type="hidden" name="%(csrf_field)s" value="%(csrf_token)s" /> <input type="hidden" name="vgrid_name" value="%(vgrid_name)s" /> ''' description = settings_dict.get('description', '') settings_form += ''' <h4>Public description</h4> <textarea class="fillwidth padspace" name="description" rows=10 >%s</textarea> ''' % description settings_form += '<br/>' settings_form += '''<p>All visibility options below can be set to owners, members or everyone and by default only owners can see participation. In effect setting visibility to <em>members</em> means that owners and members can see the corresponding participants. Similarly setting a visibility flag to <em>everyone</em> means that all %s users can see the participants.</p> ''' % configuration.short_title visibility_options = [("Owners are visible to", "visible_owners"), ("Members are visible to", "visible_members"), ("Resources are visible to", "visible_resources")] for (title, field) in visibility_options: settings_form += '<h4>%s</h4>' % title if direct_dict.get(field, False): choices = _valid_visible + _reset_choice else: choices = _valid_visible + _keep_choice for (key, val) in choices: checked = '' if settings_dict.get(field, keyword_owners) == val: checked = "checked" settings_form += ''' <input type="radio" name="%s" value="%s" %s/> %s ''' % (field, val, checked, key) settings_form += '<br/>' field = 'restrict_settings_adm' restrict_settings_adm = settings_dict.get(field, default_vgrid_settings_limit) if direct_dict.get(field, False): direct_note = _reset_note else: direct_note = _keep_note settings_form += ''' <h4>Restrict Settings</h4> Restrict changing of these settings to only the first <input type="number" name="restrict_settings_adm" min=0 max=999 minlength=1 maxlength=3 value=%d required /> owners %s. ''' % (restrict_settings_adm, direct_note) settings_form += '<br/>' field = 'restrict_owners_adm' restrict_owners_adm = settings_dict.get(field, default_vgrid_settings_limit) if direct_dict.get(field, False): direct_note = _reset_note else: direct_note = _keep_note settings_form += ''' <h4>Restrict Owner Administration</h4> Restrict administration of owners to only the first <input type="number" name="restrict_owners_adm" min=0 max=999 minlength=1 maxlength=3 value=%d required /> owners %s. ''' % (restrict_owners_adm, direct_note) settings_form += '<br/>' field = 'restrict_members_adm' restrict_members_adm = settings_dict.get(field, default_vgrid_settings_limit) if direct_dict.get(field, False): direct_note = _reset_note else: direct_note = _keep_note settings_form += ''' <h4>Restrict Member Administration</h4> Restrict administration of members to only the first <input type="number" name="restrict_members_adm" min=0 max=999 minlength=1 maxlength=3 value=%d required /> owners %s. ''' % (restrict_members_adm, direct_note) settings_form += '<br/>' field = 'restrict_resources_adm' restrict_resources_adm = settings_dict.get(field, default_vgrid_settings_limit) if direct_dict.get(field, False): direct_note = _reset_note else: direct_note = _keep_note settings_form += ''' <h4>Restrict Resource Administration</h4> Restrict administration of resources to only the first <input type="number" name="restrict_resources_adm" min=0 max=999 minlength=1 maxlength=3 value=%d required /> owners %s. ''' % (restrict_resources_adm, direct_note) settings_form += '<br/>' if vgrid_restrict_write_support(configuration): settings_form += '''<p>All write access options below can be set to owners, members or none. By default only owners can write web pages while owners and members can edit data in the shared folders. In effect setting write access to <em>members</em> means that owners and members have full access. Similarly setting a write access flag to <em>owners</em> means that only owners can modify the data, while members can only read and use it. Finally setting a write access flag to <em>none</em> means that neither owners nor members can modify the data there, effectively making it read-only. Some options are not yet supported and thus are disabled below. </p> ''' writable_options = [ ("Shared files write access", "write_shared_files", keyword_members), ("Private web page write access", "write_priv_web", keyword_owners), ("Public web page write access", "write_pub_web", keyword_owners), ] else: writable_options = [] for (title, field, default) in writable_options: settings_form += '<h4>%s</h4>' % title if direct_dict.get(field, False): choices = _valid_write_access + _reset_choice else: choices = _valid_write_access + _keep_choice for (key, val) in choices: disabled = '' # TODO: remove these artifical limits once we support changing # TODO: also add check for vgrid web reshare in sharelink then if field == 'write_shared_files' and val == keyword_owners: disabled = 'disabled' elif field == 'write_priv_web' and val in [ keyword_members, keyword_none ]: disabled = 'disabled' elif field == 'write_pub_web' and val in [ keyword_members, keyword_none ]: disabled = 'disabled' checked = '' if settings_dict.get(field, default) == val: checked = "checked" settings_form += ''' <input type="radio" name="%s" value="%s" %s %s /> %s ''' % (field, val, checked, disabled, key) settings_form += '<br/>' sharelink_options = [("Limit sharelink creation to", "create_sharelink")] for (title, field) in sharelink_options: settings_form += '<h4>%s</h4>' % title if direct_dict.get(field, False): choices = _valid_sharelink + _reset_choice else: choices = _valid_sharelink + _keep_choice for (key, val) in choices: checked = '' if settings_dict.get(field, keyword_owners) == val: checked = "checked" settings_form += ''' <input type="radio" name="%s" value="%s" %s/> %s ''' % (field, val, checked, key) settings_form += '<br/>' field = 'request_recipients' request_recipients = settings_dict.get(field, default_vgrid_settings_limit) if direct_dict.get(field, False): direct_note = _reset_note else: direct_note = _keep_note settings_form += ''' <h4>Request Recipients</h4> Notify only first <input type="number" name="request_recipients" min=0 max=999 minlength=1 maxlength=3 value=%d required /> owners about access requests %s. ''' % (request_recipients, direct_note) settings_form += '<br/>' bool_options = [ ("Hidden", "hidden"), ] for (title, field) in bool_options: settings_form += '<h4>%s</h4>' % title if direct_dict.get(field, False): choices = _valid_bool + _reset_choice else: choices = _valid_bool + _keep_choice for (key, val) in choices: checked, inherit_note = '', '' if settings_dict.get(field, False) == val: checked = "checked" if direct_dict.get(field, False) != \ settings_dict.get(field, False): inherit_note = ''' <span class="warningtext iconspace"> Forced by a parent %(vgrid_label)s. Please disable there first if you want to change the value here.</span>''' % settings_dict settings_form += ''' <input type="radio" name="%s" value="%s" %s /> %s ''' % (field, val, checked, key) settings_form += '%s<br/>' % inherit_note settings_form += '<br/>' settings_form += ''' <input type="submit" value="Save settings" /> </fieldset> </form> ''' output_objects.append({ 'object_type': 'html_form', 'text': settings_form % settings_dict }) # Checking/fixing of missing components output_objects.append({ 'object_type': 'sectionheader', 'text': "Repair/Add Components" }) target_op = 'updatevgrid' csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) settings_dict.update({'target_op': target_op, 'csrf_token': csrf_token}) output_objects.append({ 'object_type': 'html_form', 'text': ''' <form method="%(form_method)s" action="%(target_op)s.py"> <input type="hidden" name="%(csrf_field)s" value="%(csrf_token)s" /> <input type="hidden" name="vgrid_name" value="%(vgrid_name)s" /> <input type="submit" value="Repair components" /> </form> ''' % settings_dict }) (owners_status, owners_direct) = vgrid_owners(vgrid_name, configuration, False) if not owners_status: logger.error("failed to load owners for %s: %s" % (vgrid_name, owners_direct)) return (output_objects, returnvalues.SYSTEM_ERROR) (members_status, members_direct) = vgrid_members(vgrid_name, configuration, False) if not members_status: logger.error("failed to load members for %s: %s" % (vgrid_name, members_direct)) return (output_objects, returnvalues.SYSTEM_ERROR) (resources_status, resources_direct) = vgrid_resources(vgrid_name, configuration, False) if not resources_status: logger.error("failed to load resources for %s: %s" % (vgrid_name, resources_direct)) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({ 'object_type': 'sectionheader', 'text': "Delete %s " % vgrid_name }) if len(owners_direct) > 1 or members_direct or resources_direct: output_objects.append({ 'object_type': 'html_form', 'text': ''' To delete <b>%(vgrid)s</b> first remove all resources, members and owners ending with yourself. ''' % { 'vgrid': vgrid_name } }) else: output_objects.append({ 'object_type': 'html_form', 'text': ''' <p>As the last owner you can leave and delete <b>%(vgrid)s</b> including all associated shared files and components.<br/> </p> <p class="warningtext"> You cannot undo such delete operations, so please use with great care! </p> ''' % { 'vgrid': vgrid_name } }) target_op = "rmvgridowner" csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) js_name = 'rmlastvgridowner' helper = html_post_helper( js_name, '%s.py' % target_op, { 'vgrid_name': vgrid_name, 'cert_id': client_id, 'flags': 'f', csrf_field: csrf_token }) output_objects.append({'object_type': 'html_form', 'text': helper}) output_objects.append({ 'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s');" % (js_name, 'Really leave and delete %s?' % vgrid_name), 'class': 'removelink iconspace', 'title': 'Leave and delete %s' % vgrid_name, 'text': 'Leave and delete %s' % vgrid_name }) # Spacing output_objects.append({ 'object_type': 'html_form', 'text': ''' <div class="vertical-spacer"></div> ''' }) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) vgrid_name = accepted['vgrid_name'][-1] flags = ''.join(accepted['flags']) cert_id = accepted['cert_id'][-1] cert_dir = client_id_dir(cert_id) # inherited vgrid membership inherit_vgrid_member = False title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Remove %s' % configuration.site_vgrid_label output_objects.append({'object_type': 'header', 'text' : 'Remove %s Owner' % \ configuration.site_vgrid_label}) # Validity of user and vgrid names is checked in this init function so # no need to worry about illegal directory traversal through variables (ret_val, msg, _) = \ init_vgrid_script_add_rem(vgrid_name, client_id, cert_id, 'owner', configuration) if not ret_val: output_objects.append({'object_type': 'error_text', 'text' : msg}) return (output_objects, returnvalues.CLIENT_ERROR) # don't remove if not already an owner if not vgrid_is_owner(vgrid_name, cert_id, configuration): output_objects.append({'object_type': 'error_text', 'text' : '%s is not an owner of %s or a parent %s.' % (cert_id, vgrid_name, configuration.site_vgrid_label)}) return (output_objects, returnvalues.CLIENT_ERROR) # we need the local owners file to detect inherited ownerships (status, owners_direct) = vgrid_owners(vgrid_name, configuration, False) (all_status, owners) = vgrid_owners(vgrid_name, configuration, True) if not status or not all_status: logger.error('Error loading owners for %s: %s / %s' % (vgrid_name, owners_direct, owners)) output_objects.append({'object_type': 'error_text', 'text' : 'An internal error occurred, error conditions have been logged.'}) output_objects.append({'object_type': 'text', 'text' : ''' You can help us fix the problem by notifying the administrators via mail about what you wanted to do when the error happened.'''}) return (output_objects, returnvalues.CLIENT_ERROR) # find out whether to just remove an owner or delete the whole thing. # ask about delete if last or no direct owners. if len(owners_direct) > 1: logger.debug('Removing %s, one of several owners, from %s.' % (cert_id, vgrid_name)) if not (cert_id in owners_direct): # the owner owns an upper vgrid, ownership is inherited # cannot remove, not last (inherited) owner logger.debug('Cannot delete: Inherited ownership.' + '\n Owners: %s,\n Direct owners: %s.' % (owners, owners_direct)) output_objects.append({'object_type': 'error_text', 'text' : '''%s is owner of a parent %s. Owner removal has to be performed at the topmost vgrid''' % \ (cert_id, configuration.site_vgrid_label)}) return (output_objects, returnvalues.CLIENT_ERROR) else: # Remove any tracker admin rights if configuration.trac_admin_path: public_tracker_dir = \ os.path.abspath(os.path.join( configuration.vgrid_public_base, vgrid_name, '.vgridtracker')) private_tracker_dir = \ os.path.abspath(os.path.join( configuration.vgrid_private_base, vgrid_name, '.vgridtracker')) vgrid_tracker_dir = \ os.path.abspath(os.path.join( configuration.vgrid_files_home, vgrid_name, '.vgridtracker')) for tracker_dir in [public_tracker_dir, private_tracker_dir, vgrid_tracker_dir]: if not rm_tracker_admin(configuration, cert_id, vgrid_name, tracker_dir, output_objects): return (output_objects, returnvalues.SYSTEM_ERROR) user_dir = os.path.abspath(os.path.join(configuration.user_home, cert_dir)) + os.sep # Do not touch vgrid share if still a member of a parent vgrid if vgrid_is_member(vgrid_name, cert_id, configuration): # list is in top-down order parent_vgrids = vgrid_list_parents(vgrid_name, configuration) inherit_vgrid_member = vgrid_name for parent in parent_vgrids: if vgrid_is_member(parent, cert_id, configuration, recursive=False): inherit_vgrid_member = parent break output_objects.append( {'object_type': 'text', 'text' : '''NOTE: %s is still a member of parent %s %s. Preserving access to corresponding %s.''' % \ (cert_id, configuration.site_vgrid_label, inherit_vgrid_member, configuration.site_vgrid_label) }) else: (success, msg) = unlink_share(user_dir, vgrid_name) if not success: logger.error('Could not remove share link: %s.' % msg) output_objects.append({'object_type': 'error_text', 'text' : 'Could not remove share links: %s.' % msg}) return (output_objects, returnvalues.SYSTEM_ERROR) # unlink shared web folders (success, msg) = unlink_web_folders(user_dir, vgrid_name) if not success: logger.error('Could not remove web links: %s.' % msg) output_objects.append({'object_type': 'error_text', 'text' : 'Could not remove web links: %s.' % msg}) return (output_objects, returnvalues.SYSTEM_ERROR) # remove user from saved owners list (rm_status, rm_msg) = vgrid_remove_owners(configuration, vgrid_name, [cert_id]) if not rm_status: output_objects.append({'object_type': 'error_text', 'text' : '%s of owners of %s' % (rm_msg, vgrid_name)}) return (output_objects, returnvalues.SYSTEM_ERROR) # Any parent vgrid membership is left untouched here as we only # force a normal refresh in unmap_inheritance unmap_inheritance(configuration, vgrid_name, cert_id) output_objects.append({'object_type': 'text', 'text' : '%s successfully removed as owner of %s!' % (cert_id, vgrid_name)}) output_objects.append({'object_type': 'link', 'destination': 'adminvgrid.py?vgrid_name=%s' % vgrid_name, 'text': 'Back to administration for %s' % vgrid_name}) return (output_objects, returnvalues.OK) else: # no more direct owners - we try to remove this VGrid logger.debug('Leave %s from %s with no more direct owners: delete' % (vgrid_name, cert_id)) if not force(flags): output_objects.append({'object_type': 'text', 'text' : ''' No more direct owners of %s - leaving will result in the %s getting deleted. Please use either of the links below to confirm or cancel. ''' % (vgrid_name, configuration.site_vgrid_label)}) js_name = 'rmvgridowner%s' % hexlify(vgrid_name) helper = html_post_helper(js_name, 'rmvgridowner.py', {'vgrid_name': vgrid_name, 'cert_id': cert_id, 'flags': 'f'}) output_objects.append({'object_type': 'html_form', 'text': helper}) output_objects.append({'object_type': 'link', 'destination': "javascript: %s();" % js_name, 'class': 'removelink', 'text': 'Really leave and delete %s' % vgrid_name}) output_objects.append({'object_type': 'text', 'text' : ''}) output_objects.append({'object_type': 'link', 'destination': 'adminvgrid.py?vgrid_name=%s' % vgrid_name, 'text': 'Back to administration for %s' % vgrid_name}) return (output_objects, returnvalues.OK) # check if any resources participate or sub-vgrids depend on this one (status, subs) = vgrid_list_subvgrids(vgrid_name, configuration) if not status: logger.error('Error loading sub-%ss for %s: %s)' % (configuration.site_vgrid_label, vgrid_name, subs)) output_objects.append({'object_type': 'error_text', 'text' : ''' An internal error occurred, error conditions have been logged.'''}) output_objects.append({'object_type': 'text', 'text' : ''' You can help us fix the problem by notifying the administrators via mail about what you wanted to do when the error happened.'''}) return (output_objects, returnvalues.CLIENT_ERROR) if len(subs) > 0: logger.debug('Cannot delete: still has sub-%ss %s.' % (configuration.site_vgrid_label, subs)) output_objects.append({'object_type': 'error_text', 'text' : \ '%s has sub-structures and cannot be deleted.' % vgrid_name}) output_objects.append({'object_type': 'text', 'text' : ''' To leave (and delete) %s, first remove its sub-structures: %s.''' % (vgrid_name, ', '.join(subs))}) return (output_objects, returnvalues.CLIENT_ERROR) # we consider the local members and resources here, not inherited ones (member_status, members_direct) = vgrid_members(vgrid_name, configuration, False) (resource_status, resources_direct) = vgrid_resources(vgrid_name, configuration, False) if not member_status or not resource_status: logger.warning('failed to load %s members or resources: %s %s' % (vgrid_name, members_direct, resources_direct)) output_objects.append({'object_type': 'error_text', 'text' : \ 'could not load %s members or resources for %s.' % \ (configuration.site_vgrid_label, vgrid_name)}) return (output_objects, returnvalues.SYSTEM_ERROR) if len(resources_direct) > 0: logger.debug('Cannot delete: still has direct resources %s.' % resources_direct) output_objects.append({'object_type': 'error_text', 'text' : \ '%s still has resources and cannot be deleted.' % vgrid_name}) output_objects.append({'object_type': 'text', 'text' : ''' To leave (and delete) %s, first remove the participating resources.''' % vgrid_name}) return (output_objects, returnvalues.CLIENT_ERROR) if len(members_direct) > 0: logger.debug('Cannot delete: still has direct members %s.' % members_direct) output_objects.append({'object_type': 'error_text', 'text' : \ '%s still has members and cannot be deleted.' % vgrid_name}) output_objects.append({'object_type': 'text', 'text' : ''' To leave (and delete) %s, first remove all members.''' % vgrid_name}) return (output_objects, returnvalues.CLIENT_ERROR) # When reaching here, OK to remove the VGrid. # if top-level: unlink, remove all files and directories, # in all cases: remove configuration entry for the VGrid if (cert_id in owners_direct): # owner owns this vgrid, direct ownership logger.debug('%s looks like a top-level %s.' % \ (configuration.site_vgrid_label, vgrid_name)) logger.debug('Deleting all related files.') user_dir = os.path.abspath(os.path.join(configuration.user_home, cert_dir)) + os.sep (share_lnk, msg1) = unlink_share(user_dir, vgrid_name) (web_lnk, msg1) = unlink_web_folders(user_dir, vgrid_name) (abandoned, msg2) = abandon_vgrid_files(vgrid_name, configuration) else: # owner owns an upper vgrid, ownership is inherited logger.debug('%s looks like a sub-%s, ownership inherited.' % (vgrid_name, configuration.site_vgrid_label)) logger.debug('Only removing entry, leaving files in place.') share_lnk = True web_lnk = True abandoned = True msg1 = '' msg2 = '' (removed, msg3) = remove_vgrid_entry(vgrid_name, configuration) output_objects.append({'object_type': 'text', 'text' : '%s has been removed with last owner.' % vgrid_name}) output_objects.append({'object_type': 'link', 'destination': 'vgridadmin.py', 'text': 'Back to the overview.'}) if not share_lnk or not web_lnk or not abandoned or not removed: logger.error('Errors while removing %s:\n%s.' % (vgrid_name, '\n'.join([msg1,msg2,msg3]))) output_objects.append({'object_type': 'error_text', 'text' : ''' An internal error occurred, error conditions have been logged.'''}) output_objects.append({'object_type': 'text', 'text' : ''' You can help us fix the problem by notifying the administrators via mail about what you wanted to do when the error happened.'''}) return (output_objects, returnvalues.CLIENT_ERROR) else: # Remove vgrid from vgrid cache (after deleting all) unmap_vgrid(configuration, vgrid_name) return (output_objects, returnvalues.OK)