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) vgrid_name = accepted['vgrid_name'][-1] path = accepted['path'][-1] if not vgrid_is_owner_or_member(vgrid_name, client_id, configuration): output_objects.append({'object_type': 'error_text', 'text': '''You must be an owner or member of %s %s to access the private files.''' % (vgrid_name, configuration.site_vgrid_label)}) return (output_objects, returnvalues.CLIENT_ERROR) # Please note that base_dir must end in slash to avoid access to other # user dirs when own name is a prefix of another user name base_dir = os.path.abspath(os.path.join(configuration.vgrid_private_base, vgrid_name)) + os.sep # Strip leading slashes to avoid join() throwing away prefix rel_path = path.lstrip(os.sep) real_path = os.path.abspath(os.path.join(base_dir, rel_path)) if not valid_user_path(real_path, base_dir, True): output_objects.append({'object_type': 'error_text', 'text': '''You are not allowed to use paths outside %s private files dir.''' % configuration.site_vgrid_label}) return (output_objects, returnvalues.CLIENT_ERROR) try: private_fd = open(real_path, 'rb') entry = {'object_type': 'binary', 'data': private_fd.read()} # Cut away all the usual web page formatting to show only contents output_objects = [{'object_type': 'start', 'headers': []}, entry, {'object_type': 'script_status'}, {'object_type': 'end'}] private_fd.close() except Exception, exc: output_objects.append({'object_type': 'error_text', 'text' : 'Error reading %s private file (%s)' % (configuration.site_vgrid_label, exc)}) return (output_objects, returnvalues.SYSTEM_ERROR)
def user_view_access(configuration, vgrid_name, client_id, settings_dict, field): """Check if client_id has access to view field participation for vgrid_name based on saved settings_dict. """ required = settings_dict.get(field, keyword_owners) if required == keyword_owners: access = vgrid_is_owner(vgrid_name, client_id, configuration) elif required == keyword_members: access = vgrid_is_owner_or_member(vgrid_name, client_id, configuration) elif required == keyword_all: access = True else: access = False return access
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 Workflows' % 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] operation = accepted['operation'][-1] flags = ''.join(accepted['flags'][-1]) if not vgrid_is_owner_or_member(vgrid_name, client_id, configuration): output_objects.append({ 'object_type': 'error_text', 'text': '''You must be an owner or member of %s vgrid to access the workflows.''' % vgrid_name }) return (output_objects, returnvalues.CLIENT_ERROR) if not operation in allowed_operations: output_objects.append({ 'object_type': 'error_text', 'text': '''Operation must be one of %s.''' % ', '.join(allowed_operations) }) return (output_objects, returnvalues.OK) if operation in show_operations: # jquery support for tablesorter (and unused confirmation dialog) # table initially sorted by 0 (last update / date) refresh_call = 'ajax_workflowjobs("%s", "%s")' % (vgrid_name, flags) table_spec = { 'table_id': 'workflowstable', 'sort_order': '[[0,1]]', 'refresh_call': refresh_call } (add_import, add_init, add_ready) = man_base_js(configuration, [table_spec]) if operation == "show": add_ready += '%s;' % refresh_call add_ready += ''' /* Init variables helper as foldable but closed and with individual heights */ $(".variables-accordion").accordion({ collapsible: true, active: false, heightStyle: "content" }); /* fix and reduce accordion spacing */ $(".ui-accordion-header").css("padding-top", 0) .css("padding-bottom", 0).css("margin", 0); /* NOTE: requires managers CSS fix for proper tab bar height */ $(".workflow-tabs").tabs(); $("#logarea").scrollTop($("#logarea")[0].scrollHeight); ''' 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) }) output_objects.append({ 'object_type': 'header', 'text': '%s Workflows for %s' % (label, vgrid_name) }) logger.info('vgridworkflows %s %s' % (vgrid_name, operation)) # Iterate through jobs and list details for each trigger_jobs = [] log_content = '' if operation in list_operations: trigger_job_dir = os.path.join( configuration.vgrid_home, os.path.join(vgrid_name, '.%s.jobs' % configuration.vgrid_triggers)) trigger_job_pending_dir = os.path.join(trigger_job_dir, 'pending_states') trigger_job_final_dir = os.path.join(trigger_job_dir, 'final_states') if makedirs_rec(trigger_job_pending_dir, configuration) \ and makedirs_rec(trigger_job_final_dir, configuration): abs_vgrid_dir = '%s/' \ % os.path.abspath(os.path.join(configuration.vgrid_files_home, vgrid_name)) for filename in os.listdir(trigger_job_pending_dir): trigger_job_filepath = \ os.path.join(trigger_job_pending_dir, filename) trigger_job = unpickle(trigger_job_filepath, logger) serverjob_filepath = \ os.path.join(configuration.mrsl_files_dir, os.path.join( client_id_dir(trigger_job['owner']), '%s.mRSL' % trigger_job['jobid'])) serverjob = unpickle(serverjob_filepath, logger) if serverjob: if serverjob['STATUS'] in pending_states: trigger_event = trigger_job['event'] trigger_rule = trigger_job['rule'] trigger_action = trigger_event['event_type'] trigger_time = time.ctime(trigger_event['time_stamp']) trigger_path = '%s %s' % \ (trigger_event['src_path'].replace( abs_vgrid_dir, ''), trigger_event['dest_path'].replace( abs_vgrid_dir, '')) job = { 'object_type': 'trigger_job', 'job_id': trigger_job['jobid'], 'rule_id': trigger_rule['rule_id'], 'path': trigger_path, 'action': trigger_action, 'time': trigger_time, 'status': serverjob['STATUS'] } if not job['rule_id'].startswith(img_trigger_prefix) \ or verbose(flags): trigger_jobs.append(job) elif serverjob['STATUS'] in final_states: src_path = os.path.join(trigger_job_pending_dir, filename) dest_path = os.path.join(trigger_job_final_dir, filename) move_file(src_path, dest_path, configuration) else: logger.error( 'Trigger job: %s, unknown state: %s' % (trigger_job['jobid'], serverjob['STATUS'])) log_content = read_trigger_log(configuration, vgrid_name, flags) if operation in show_operations: # Always run as rule creator to avoid users being able to act on behalf # of ANY other user using triggers (=exploit) extra_fields = [ ('path', None), ('match_dirs', ['False', 'True']), ('match_recursive', ['False', 'True']), ('changes', [keyword_all] + valid_trigger_changes), ('action', [keyword_auto] + valid_trigger_actions), ('arguments', None), ('run_as', client_id), ] # NOTE: we do NOT show saved template contents - see addvgridtriggers optional_fields = [('rate_limit', None), ('settle_time', None)] # Only include system triggers in verbose mode if verbose(flags): system_filter = [] else: system_filter = [('rule_id', '%s_.*' % img_trigger_prefix)] (init_status, oobjs) = vgrid_add_remove_table(client_id, vgrid_name, 'trigger', 'vgridtrigger', configuration, extra_fields + optional_fields, filter_items=system_filter) if not init_status: output_objects.append({ 'object_type': 'error_text', 'text': 'failed to load triggers: %s' % oobjs }) return (output_objects, returnvalues.SYSTEM_ERROR) # Generate variable helper values for a few concrete samples for help # text vars_html = '' dummy_rule = {'run_as': client_id, 'vgrid_name': vgrid_name} samples = [('input.txt', 'modified'), ('input/image42.raw', 'changed')] for (path, change) in samples: vgrid_path = os.path.join(vgrid_name, path) vars_html += "<b>Expanded variables when %s is %s:</b><br/>" % \ (vgrid_path, change) expanded = get_path_expand_map(vgrid_path, dummy_rule, change) for (key, val) in expanded.items(): vars_html += " %s: %s<br/>" % (key, val) commands_html = '' commands = get_usage_map(configuration) for usage in commands.values(): commands_html += " %s<br/>" % usage helper_html = """ <div class='variables-accordion'> <h4>Help on available trigger variable names and values</h4> <p> Triggers can use a number of helper variables on the form +TRIGGERXYZ+ to dynamically act on targets. Some of the values are bound to the rule owner the %s while the remaining ones are automatically expanded for the particular trigger target as shown in the following examples:<br/> %s </p> <h4>Help on available trigger commands and arguments</h4> <p> It is possible to set up trigger rules that basically run any operation with a side effect you could manually do on %s. I.e. like submitting/cancelling a job, creating/moving/deleting a file or directory and so on. When you select 'command' as the action for a trigger rule, you have the following commands at your disposal:<br/> %s </p> </div> """ % (label, vars_html, configuration.short_title, commands_html) # Make page with manage triggers tab and active jobs and log tab output_objects.append({ 'object_type': 'html_form', 'text': ''' <div id="wrap-tabs" class="workflow-tabs"> <ul> <li><a href="#manage-tab">Manage Triggers</a></li> <li><a href="#jobs-tab">Active Trigger Jobs</a></li> </ul> ''' }) # Display existing triggers and form to add new ones output_objects.append({ 'object_type': 'html_form', 'text': ''' <div id="manage-tab"> ''' }) output_objects.append({ 'object_type': 'sectionheader', 'text': 'Manage Triggers' }) output_objects.extend(oobjs) output_objects.append({ 'object_type': 'html_form', 'text': helper_html }) if configuration.site_enable_crontab: output_objects.append({ 'object_type': 'html_form', 'text': ''' <p>You can combine these workflows with the personal ''' }) output_objects.append({ 'object_type': 'link', 'destination': 'crontab.py', 'class': 'crontablink iconspace', 'text': 'schedule task' }) output_objects.append({ 'object_type': 'html_form', 'text': ''' facilities in case you want to trigger flows at given times rather than only in reaction to file system events.</p> ''' }) output_objects.append({ 'object_type': 'html_form', 'text': ''' </div> ''' }) # Display active trigger jobs and recent logs for this vgrid output_objects.append({ 'object_type': 'html_form', 'text': ''' <div id="jobs-tab"> ''' }) output_objects.append({ 'object_type': 'sectionheader', 'text': 'Active Trigger Jobs' }) output_objects.append({ 'object_type': 'table_pager', 'entry_name': 'job', 'default_entries': default_pager_entries }) output_objects.append({ 'object_type': 'trigger_job_list', 'trigger_jobs': trigger_jobs }) if operation in show_operations: output_objects.append({ 'object_type': 'sectionheader', 'text': 'Trigger Log' }) output_objects.append({ 'object_type': 'trigger_log', 'log_content': log_content }) if operation in show_operations: output_objects.append({ 'object_type': 'html_form', 'text': ''' </div> ''' }) output_objects.append({ 'object_type': 'html_form', 'text': ''' </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) vgrid_name = accepted['vgrid_name'][-1] if not vgrid_is_owner_or_member(vgrid_name, client_id, configuration): output_objects.append({'object_type': 'error_text', 'text': '''You must be an owner or member of %s vgrid to access the workflows.''' % vgrid_name}) return (output_objects, returnvalues.CLIENT_ERROR) title_entry = find_entry(output_objects, 'title') title_entry['text'] = '%s Workflows' \ % configuration.site_vgrid_label title_entry['style'] = themed_styles(configuration) title_entry['javascript'] = \ ''' <script type="text/javascript" src="/images/js/jquery.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.pager.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.widgets.js"></script> <script type="text/javascript" src="/images/js/jquery-ui.js"></script> <script type="text/javascript"> $(document).ready(function() { $("#logarea").scrollTop($("#logarea")[0].scrollHeight); // table initially sorted by 0 (last update / date) var sortOrder = [[0,1]]; // use image path for sorting if there is any inside var imgTitle = function(contents) { var key = $(contents).find("a").attr("class"); if (key == null) { key = $(contents).html(); } return key; } $("#workflowstable").tablesorter({widgets: ["zebra", "saveSort"], sortList:sortOrder, textExtraction: imgTitle }) .tablesorterPager({ container: $("#pager"), size: %s }); } ); </script> ''' \ % default_pager_entries output_objects.append({'object_type': 'html_form', 'text': ''' <div id="confirm_dialog" title="Confirm" style="background:#fff;"> <div id="confirm_text"><!-- filled by js --></div> <textarea cols="72" rows="10" id="confirm_input" style="display:none;"></textarea> </div> '''}) output_objects.append({'object_type': 'header', 'text': '%s Workflows for %s' % (configuration.site_vgrid_label, vgrid_name)}) logger.info('vgridworkflows %s' % vgrid_name) # Display active trigger jobs for this vgrid output_objects.append({'object_type': 'sectionheader', 'text': 'Active Trigger Jobs'}) html = '<table><thead><tr>' html += '<th>Job ID</th>' html += '<th>Rule</th>' html += '<th>Path</th>' html += '<th>Change</th>' html += '<th>Time</th>' html += '<th>Status</th>' html += '</tr></thead>' html += '<tbody>' trigger_job_dir = os.path.join(configuration.vgrid_home, os.path.join(vgrid_name, '.%s.jobs' % configuration.vgrid_triggers)) trigger_job_pending_dir = os.path.join(trigger_job_dir, 'pending_states') trigger_job_final_dir = os.path.join(trigger_job_dir, 'final_states' ) if makedirs_rec(trigger_job_pending_dir, logger) \ and makedirs_rec(trigger_job_final_dir, logger): abs_vgrid_dir = '%s/' \ % os.path.abspath(os.path.join(configuration.vgrid_files_home, vgrid_name)) for filename in os.listdir(trigger_job_pending_dir): trigger_job_filepath = \ os.path.join(trigger_job_pending_dir, filename) trigger_job = unpickle(trigger_job_filepath, logger) serverjob_filepath = \ os.path.join(configuration.mrsl_files_dir, os.path.join(client_id_dir(trigger_job['owner' ]), '%s.mRSL' % trigger_job['jobid'])) serverjob = unpickle(serverjob_filepath, logger) if serverjob: if serverjob['STATUS'] in pending_states: trigger_event = trigger_job['event'] trigger_rule = trigger_job['rule'] trigger_action = trigger_event['event_type'] trigger_time = time.ctime(trigger_event['time_stamp' ]) trigger_path = '%s %s' % (trigger_event['src_path' ].replace(abs_vgrid_dir, ''), trigger_event['dest_path' ].replace(abs_vgrid_dir, '')) html += \ '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></td><td>%s</td>' \ % (trigger_job['jobid'], trigger_rule['rule_id' ], trigger_path, trigger_action, trigger_time, serverjob['STATUS']) elif serverjob['STATUS'] in final_states: src_path = os.path.join(trigger_job_pending_dir, filename) dest_path = os.path.join(trigger_job_final_dir, filename) move_file(src_path, dest_path, configuration) else: logger.error('Trigger job: %s, unknown state: %s' % (trigger_job['jobid'], serverjob['STATUS'])) html += '</tbody>' html += '</table>' output_objects.append({'object_type': 'html_form', 'text': html}) # Display active trigger jobs for this vgrid output_objects.append({'object_type': 'sectionheader', 'text': 'Trigger Log'}) log_content = read_trigger_log(configuration, vgrid_name) output_objects.append({'object_type': 'html_form', 'text': ''' <div class="form_container"> <textarea id="logarea" rows=10 readonly="readonly">%s</textarea> </div> ''' % log_content}) output_objects.append({'object_type': 'sectionheader', 'text': 'Manage Triggers'}) # Always run as rule creator to avoid users being able to act on behalf # of ANY other user using triggers (=exploit) extra_fields = [ ('path', None), ('match_dirs', ['False', 'True']), ('match_recursive', ['False', 'True']), ('changes', [keyword_all] + valid_trigger_changes), ('action', [keyword_auto] + valid_trigger_actions), ('arguments', None), ('run_as', client_id), ] # NOTE: we do NOT show saved template contents - see addvgridtriggers optional_fields = [('rate_limit', None), ('settle_time', None)] (status, oobjs) = vgrid_add_remove_table( client_id, vgrid_name, 'trigger', 'vgridtrigger', configuration, extra_fields, optional_fields, ) output_objects.extend(oobjs) if not status: return (output_objects, returnvalues.SYSTEM_ERROR) 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 Forum' % label user_settings = title_entry.get('user_settings', {}) (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] action = accepted['action'][-1] thread = accepted['thread'][-1] msg_subject = accepted['msg_subject'][-1].strip() msg_body = accepted['msg_body'][-1].strip() if not vgrid_is_owner_or_member(vgrid_name, client_id, configuration): output_objects.append({ 'object_type': 'error_text', 'text': '''You must be an owner or member of %s %s to access the forum.''' % (vgrid_name, label) }) return (output_objects, returnvalues.CLIENT_ERROR) if not action in valid_actions: output_objects.append({ 'object_type': 'error_text', 'text': 'Invalid action "%s" (supported: %s)' % (action, ', '.join(valid_actions)) }) return (output_objects, returnvalues.CLIENT_ERROR) if action in post_actions: 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) # Please note that base_dir must end in slash to avoid access to other # user dirs when own name is a prefix of another user name base_dir = os.path.abspath( os.path.join(configuration.vgrid_private_base, vgrid_name)) + os.sep forum_base = os.path.abspath(os.path.join(base_dir, '.vgridforum')) # TODO: can we update style inline to avoid explicit themed_styles? title_entry['style'] = themed_styles(configuration, advanced=['forum.css'], user_settings=user_settings) add_import = ''' <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.pager.js"></script> <script type="text/javascript" src="/images/js/jquery.confirm.js"></script> ''' add_init = ''' function toggle_new(form_elem_id, link_elem_id) { form_elem = document.getElementById(form_elem_id); form_focus = document.getElementById(form_elem_id + "_main"); link_elem = document.getElementById(link_elem_id); if (!form_elem || !link_elem) return; if (form_elem.style.display != 'block') { form_elem.style.display = 'block'; form_focus.focus(); link_elem.style.display = 'none'; } else { form_elem.style.display = 'none'; link_elem.style.display = 'block'; link_elem.focus(); } } ''' add_ready = ''' // init confirmation dialog $( "#confirm_dialog" ).dialog( // see http://jqueryui.com/docs/dialog/ for options { autoOpen: false, modal: true, closeOnEscape: true, width: 640, buttons: { "Cancel": function() { $( "#" + name ).dialog("close"); } } }); // table initially sorted by 0 (last update / date) var sortOrder = [[0,1]]; // use image path for sorting if there is any inside var imgTitle = function(contents) { var key = $(contents).find("a").attr("class"); if (key == null) { key = $(contents).html(); } return key; } $("#forumtable").tablesorter({widgets: ["zebra"], sortList:sortOrder, textExtraction: imgTitle }) .tablesorterPager({ container: $("#pager"), size: %s }); $("#pagerrefresh").click(function() { location.reload(); }); ''' % default_pager_entries 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': ''' <div id="confirm_dialog" title="Confirm" style="background:#fff;"> <div id="confirm_text"><!-- filled by js --></div> <textarea cols="72" rows="10" id="confirm_input" style="display:none;"></textarea> </div> ''' }) output_objects.append({ 'object_type': 'sectionheader', 'text': '%s Forum for %s' % (label, vgrid_name) }) try: os.makedirs(forum_base) except: pass if not os.path.isdir(forum_base): output_objects.append({ 'object_type': 'error_text', 'text': '''No forum available for %s!''' % vgrid_name }) return (output_objects, returnvalues.SYSTEM_ERROR) post_error = None msg = '' logger.info("vgridforum %s %s %s" % (vgrid_name, action, thread)) if action in post_actions: if action == 'new_thread': try: (thread_hash, msg) = new_subject(forum_base, client_id, msg_subject, msg_body) query = 'vgrid_name=%s&action=show_thread&thread=%s'\ % (vgrid_name, thread_hash) url = "%s?%s" % (os.environ['SCRIPT_URI'], query) notify_subscribers(configuration, forum_base, vgrid_name, '', client_id, url) thread = thread_hash except ValueError, error: post_error = str(error) elif action == 'reply': try: (thread_hash, msg) = reply(forum_base, client_id, msg_body, thread) query = 'vgrid_name=%s&action=show_thread&thread=%s'\ % (vgrid_name, thread_hash) url = "%s?%s" % (os.environ['SCRIPT_URI'], query) notify_subscribers(configuration, forum_base, vgrid_name, '', client_id, url) notify_subscribers(configuration, forum_base, vgrid_name, thread_hash, client_id, url) except ValueError, error: post_error = str(error)
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) meta = ( """<meta http-equiv="refresh" content="%s" /> """ % configuration.sleep_secs ) style = themed_styles(configuration) script = """ <script type="text/javascript" src="/images/js/jquery.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> <script type="text/javascript" > $(document).ready(function() { // table initially sorted by col. 1 (name) var sortOrder = [[1,0]]; // use image path for sorting if there is any inside var imgTitle = function(contents) { var key = $(contents).find("a").attr("class"); if (key == null) { key = $(contents).html(); } return key; } $("table.monitor").tablesorter({widgets: ["zebra"], textExtraction: imgTitle, }); $("table.monitor").each(function () { try { $(this).trigger("sorton", [sortOrder]); } catch(err) { /* tablesorter chokes on empty tables - just continue */ } }); } ); </script> """ title_entry = find_entry(output_objects, "title") title_entry["text"] = "%s Monitor" % configuration.short_title title_entry["meta"] = meta title_entry["style"] = style title_entry["javascript"] = script allowed_vgrids = user_allowed_vgrids(configuration, client_id) vgrid_list = accepted["vgrid_name"] if all_vgrids in accepted["vgrid_name"]: vgrid_list = [i for i in vgrid_list if all_vgrids != i] + allowed_vgrids # Force list to sequence of unique entries for vgrid_name in set(vgrid_list): html = "" if not vgrid_is_owner_or_member(vgrid_name, client_id, configuration): output_objects.append( { "object_type": "error_text", "text": """You must be an owner or member of %s %s to access the monitor.""" % (vgrid_name, configuration.site_vgrid_label), } ) return (output_objects, returnvalues.CLIENT_ERROR) monitor_file = os.path.join(configuration.vgrid_home, vgrid_name, "%s.html" % configuration.vgrid_monitor) try: monitor_fd = open(monitor_file, "r") past_header = False for line in monitor_fd: if -1 != line.find("end of raw header"): past_header = True continue if not past_header: continue if -1 != line.find("begin raw footer:"): break html += str(line) monitor_fd.close() except Exception, exc: output_objects.append( { "object_type": "error_text", "text": "Error reading %s monitor page (%s)" % (configuration.site_vgrid_label, exc), } ) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({"object_type": "html_form", "text": html})
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) vgrid_name = accepted['vgrid_name'][-1] action = accepted['action'][-1] thread = accepted['thread'][-1] msg_subject = accepted['msg_subject'][-1].strip() msg_body = accepted['msg_body'][-1].strip() if not vgrid_is_owner_or_member(vgrid_name, client_id, configuration): output_objects.append({'object_type': 'error_text', 'text': '''You must be an owner or member of %s %s to access the forum.''' % (vgrid_name, configuration.site_vgrid_label)}) return (output_objects, returnvalues.CLIENT_ERROR) if not action in valid_actions: output_objects.append({'object_type': 'error_text', 'text' : 'Invalid action "%s" (supported: %s)' % \ (action, ', '.join(valid_actions))}) return (output_objects, returnvalues.CLIENT_ERROR) if action in post_actions and 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) # Please note that base_dir must end in slash to avoid access to other # user dirs when own name is a prefix of another user name base_dir = os.path.abspath(os.path.join(configuration.vgrid_private_base, vgrid_name)) + os.sep forum_base = os.path.abspath(os.path.join(base_dir, '.vgridforum')) title_entry = find_entry(output_objects, 'title') title_entry['text'] = '%s Forum' % configuration.site_vgrid_label css_helpers = {'css_base': os.path.join(configuration.site_images, 'css'), 'skin_base': configuration.site_skin_base} title_entry['style'] = themed_styles(configuration, advanced=['forum.css']) title_entry['javascript'] = ''' <script type="text/javascript" src="/images/js/jquery.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.pager.js"></script> <script type="text/javascript" src="/images/js/jquery-ui.js"></script> <script type="text/javascript" src="/images/js/jquery.confirm.js"></script> <script type="text/javascript"> function toggle_new(form_elem_id, link_elem_id) { form_elem = document.getElementById(form_elem_id); form_focus = document.getElementById(form_elem_id + "_main"); link_elem = document.getElementById(link_elem_id); if (!form_elem || !link_elem) return; if (form_elem.style.display != 'block') { form_elem.style.display = 'block'; form_focus.focus(); link_elem.style.display = 'none'; } else { form_elem.style.display = 'none'; link_elem.style.display = 'block'; link_elem.focus(); } } $(document).ready(function() { // init confirmation dialog $( "#confirm_dialog" ).dialog( // see http://jqueryui.com/docs/dialog/ for options { autoOpen: false, modal: true, closeOnEscape: true, width: 640, buttons: { "Cancel": function() { $( "#" + name ).dialog("close"); } } }); // table initially sorted by 0 (last update / date) var sortOrder = [[0,1]]; // use image path for sorting if there is any inside var imgTitle = function(contents) { var key = $(contents).find("a").attr("class"); if (key == null) { key = $(contents).html(); } return key; } $("#forumtable").tablesorter({widgets: ["zebra"], sortList:sortOrder, textExtraction: imgTitle }) .tablesorterPager({ container: $("#pager"), size: %s }); } ); </script> ''' % default_pager_entries output_objects.append({'object_type': 'html_form', 'text':''' <div id="confirm_dialog" title="Confirm" style="background:#fff;"> <div id="confirm_text"><!-- filled by js --></div> <textarea cols="72" rows="10" id="confirm_input" style="display:none;"></textarea> </div> ''' }) output_objects.append({'object_type': 'sectionheader', 'text' : '%s Forum for %s' % \ (configuration.site_vgrid_label, vgrid_name)}) try: os.makedirs(forum_base) except: pass if not os.path.isdir(forum_base): output_objects.append({'object_type': 'error_text', 'text': '''No forum available for %s!''' % vgrid_name}) return (output_objects, returnvalues.SYSTEM_ERROR) post_error = None msg = '' logger.info("vgridforum %s %s %s" % (vgrid_name, action, thread)) if action in post_actions: if action == 'new_thread': try: (thread_hash, msg) = new_subject(forum_base, client_id, msg_subject, msg_body) query = 'vgrid_name=%s&action=show_thread&thread=%s'\ % (vgrid_name,thread_hash) url = "%s?%s" % (os.environ['SCRIPT_URI'], query) notify_subscribers(configuration, forum_base, vgrid_name, '', client_id, url) thread = thread_hash except ValueError, error: post_error = str(error) elif action == 'reply': try: (thread_hash, msg) = reply(forum_base, client_id, msg_body, thread) query = 'vgrid_name=%s&action=show_thread&thread=%s'\ % (vgrid_name,thread_hash) url = "%s?%s" % (os.environ['SCRIPT_URI'], query) notify_subscribers(configuration, forum_base, vgrid_name, '', client_id, url) notify_subscribers(configuration, forum_base, vgrid_name, thread_hash, client_id, url) except ValueError, error: post_error = str(error)
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) status = returnvalues.OK 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) (stat, vgrid_list) = vgrid_list_vgrids(configuration) if not stat: output_objects.append({'object_type': 'error_text', 'text' : 'Error getting list of %s.' % \ configuration.site_vgrid_label}) # Check if user wants advanced VGrid component links settings = load_settings(client_id, configuration) collaboration_links = settings.get('SITE_COLLABORATION_LINKS', 'default') if not collaboration_links in configuration.site_collaboration_links or \ collaboration_links == 'default': active_vgrid_links = configuration.site_default_vgrid_links elif collaboration_links == 'advanced': active_vgrid_links = configuration.site_advanced_vgrid_links # Iterate through vgrids and print details for each member_list = {'object_type': 'vgrid_list', 'vgrids': [], 'components': active_vgrid_links} if 'monitor' in active_vgrid_links: vgrid_list = [all_vgrids] + vgrid_list else: vgrid_list.remove(default_vgrid) for vgrid_name in vgrid_list: vgrid_obj = {'object_type': 'vgrid', 'name': vgrid_name} if vgrid_name == default_vgrid: # Everybody is member and allowed to see statistics, Noone # can own it or leave it. Do not add any page links. vgrid_obj['privatemonitorlink'] = {'object_type': 'link', 'destination': 'showvgridmonitor.py?vgrid_name=%s'\ % vgrid_name, 'class': 'monitorlink', 'title': 'View %s monitor' % vgrid_name, 'text': 'View'} vgrid_obj['memberlink'] = {'object_type': 'link', 'destination':'', 'class': 'infolink', 'title': 'Every user is member of the %s %s' \ % (default_vgrid, configuration.site_vgrid_label), 'text': ''} vgrid_obj['administratelink'] = {'object_type': 'link', 'destination':'', 'class': 'infolink', 'title': 'Nobody owns the %s %s' \ % (default_vgrid, configuration.site_vgrid_label), 'text': ''} member_list['vgrids'].append(vgrid_obj) continue elif vgrid_name == all_vgrids: # Only show global monitor link for all_vgrids, Noone # can own it or leave it. Do not add any page links. vgrid_obj['privatemonitorlink'] = {'object_type': 'link', 'destination': 'showvgridmonitor.py?vgrid_name=%s'\ % vgrid_name, 'class': 'monitorlink', 'title': 'View global monitor', 'text': 'View'} vgrid_obj['memberlink'] = {'object_type': 'link', 'destination':'', 'class': 'infolink', 'title': 'Not a real %s - only for global monitor' % \ configuration.site_vgrid_label, 'text': ''} vgrid_obj['administratelink'] = {'object_type': 'link', 'destination':'', 'class': 'infolink', 'title': 'Not a real %s - only for global monitor' % \ configuration.site_vgrid_label, 'text': ''} member_list['vgrids'].append(vgrid_obj) continue # links for everyone: public pages and membership request vgrid_obj['publicscmlink'] = {'object_type': 'link', 'destination': '%s/vgridpublicscm/%s'\ % (configuration.migserver_http_url, vgrid_name), 'class': 'scmlink public', 'title': 'Open %s public SCM' % \ vgrid_name, 'text': 'Open'} vgrid_obj['publictrackerlink'] = {'object_type': 'link', 'destination': '%s/vgridpublictracker/%s'\ % (configuration.migserver_http_url, vgrid_name), 'class': 'trackerlink public', 'title': 'Open %s public tracker' % \ vgrid_name, 'text': 'Open'} vgrid_obj['enterpubliclink'] = {'object_type': 'link', 'destination': '%s/vgrid/%s/path/index.html' % \ (configuration.migserver_http_url, vgrid_name), 'class': 'urllink member', 'title': 'View public %s web page' % \ vgrid_name, 'text': 'View'} # link to become member: overwritten later for members js_name = 'reqvgridmember%s' % hexlify(vgrid_name) helper = html_post_helper(js_name, 'sendrequestaction.py', {'vgrid_name': vgrid_name, 'request_type': 'vgridmember', 'request_text': ''}) output_objects.append({'object_type': 'html_form', 'text': helper}) vgrid_obj['memberlink'] = \ {'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s', '%s');"\ % (js_name, "Request membership of " + \ vgrid_name + ":<br/>" + \ "\nPlease write a message to the owners (field below).", 'request_text'), 'class': 'addlink', 'title': 'Request membership of %s' % \ vgrid_name, 'text': ''} # link to become owner: overwritten later for owners js_name = 'reqvgridowner%s' % hexlify(vgrid_name) helper = html_post_helper(js_name, 'sendrequestaction.py', {'vgrid_name': vgrid_name, 'request_type': 'vgridowner', 'request_text': ''}) output_objects.append({'object_type': 'html_form', 'text': helper}) vgrid_obj['administratelink'] = \ {'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s', '%s');"\ % (js_name, "Request ownership of " + \ vgrid_name + ":<br/>" + \ "\nPlease write a message to the owners (field below).", 'request_text'), 'class': 'addadminlink', 'title': 'Request ownership of %s' % \ vgrid_name, 'text': ''} # members/owners are allowed to view private pages and monitor if vgrid_is_owner_or_member(vgrid_name, client_id, configuration): vgrid_obj['enterprivatelink'] = {'object_type': 'link', 'destination': '../vgrid/%s/path/index.html' % \ vgrid_name, 'class': 'urllink owner', 'title': 'View private %s web page' % \ vgrid_name, 'text': 'View'} vgrid_obj['sharedfolderlink'] = {'object_type': 'link', 'destination': 'fileman.py?path=%s/' % vgrid_name, 'class': 'sharedfolderlink', 'title': 'Open shared %s folder' \ % vgrid_name, 'text': 'Open'} vgrid_obj['memberscmlink'] = {'object_type': 'link', 'destination': '/vgridscm/%s' % \ vgrid_name, 'class': 'scmlink member', 'title': 'View %s members scm' % \ vgrid_name, 'text': 'View'} vgrid_obj['membertrackerlink'] = {'object_type': 'link', 'destination': '/vgridtracker/%s' % \ vgrid_name, 'class': 'trackerlink member', 'title': 'View %s members tracker' % \ vgrid_name, 'text': 'View'} vgrid_obj['privateforumlink'] = {'object_type': 'link', 'destination': 'vgridforum.py?vgrid_name=%s' % \ vgrid_name, 'class': 'forumlink', 'title': 'Open %s private forum' \ % vgrid_name, 'text': 'Open'} vgrid_obj['privateworkflowslink'] = {'object_type': 'link', 'destination': 'vgridworkflows.py?vgrid_name=%s' % \ vgrid_name, 'class': 'workflowslink', 'title': 'Open %s private workflows' \ % vgrid_name, 'text': 'Open'} vgrid_obj['privatemonitorlink'] = {'object_type': 'link', 'destination': 'showvgridmonitor.py?vgrid_name=%s'\ % vgrid_name, 'class': 'monitorlink', 'title': 'View %s monitor' % \ vgrid_name, 'text': 'View'} # to leave this VGrid (remove ourselves). Note that we are # going to overwrite the link later for owners. js_name = 'rmvgridmember%s' % hexlify(vgrid_name) helper = html_post_helper(js_name, 'rmvgridmember.py', {'vgrid_name': vgrid_name, 'cert_id': client_id}) output_objects.append({'object_type': 'html_form', 'text': helper}) vgrid_obj['memberlink'] = \ {'object_type': 'link', 'destination': "javascript: confirmDialog(%s, '%s');"\ % (js_name, "Really leave " + vgrid_name + "?"), 'class': 'removelink', 'title': 'Leave %s members' % vgrid_name, 'text': ''} # owners are allowed to edit pages and administrate if vgrid_is_owner(vgrid_name, client_id, configuration): vgrid_obj['ownerscmlink'] = {'object_type': 'link', 'destination': '/vgridownerscm/%s' % \ vgrid_name, 'class': 'scmlink owner', 'title': 'View %s owners scm' % \ vgrid_name, 'text': 'View'} vgrid_obj['ownertrackerlink'] = {'object_type': 'link', 'destination': '/vgridownertracker/%s' % \ vgrid_name, 'class': 'trackerlink owner', 'title': 'View %s owners tracker' % \ vgrid_name, 'text': 'View'} # correct the link to leave the VGrid js_name = 'rmvgridowner%s' % hexlify(vgrid_name) helper = html_post_helper(js_name, 'rmvgridowner.py', {'vgrid_name': vgrid_name, 'cert_id': client_id}) output_objects.append({'object_type': 'html_form', 'text': helper}) vgrid_obj['memberlink']['destination'] = \ "javascript: confirmDialog(%s,'%s');" % \ (js_name, "Really leave " + vgrid_name + "?") vgrid_obj['memberlink']['class'] = 'removeadminlink' vgrid_obj['memberlink']['title'] = 'Leave %s owners' % vgrid_name # add more links: administrate and edit pages vgrid_obj['administratelink'] = {'object_type': 'link', 'destination': 'adminvgrid.py?vgrid_name=%s'\ % vgrid_name, 'class': 'adminlink', 'title': 'Administrate %s' % vgrid_name, 'text': ''} vgrid_obj['editprivatelink'] = {'object_type': 'link', 'destination': 'fileman.py?path=private_base/%s/'\ % vgrid_name, 'class': 'editlink owner', 'title': 'Edit private %s web page' % vgrid_name, 'text': 'Edit'} vgrid_obj['editpubliclink'] = {'object_type': 'link', 'destination': 'fileman.py?path=public_base/%s/'\ % vgrid_name, 'class': 'editlink member', 'title': 'Edit public %s web page' % vgrid_name, 'text': 'Edit'} member_list['vgrids'].append(vgrid_obj) title_entry = find_entry(output_objects, 'title') label = "%ss" % configuration.site_vgrid_label # Append VGrid note if custom if label != 'VGrid': label += ' (i.e. VGrids)' title_entry['text'] = '%s administration' % label # jquery support for tablesorter and confirmation on "leave": title_entry['style'] = themed_styles(configuration) title_entry['javascript'] = ''' <script type="text/javascript" src="/images/js/jquery.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.pager.js"></script> <script type="text/javascript" src="/images/js/jquery.tablesorter.widgets.js"></script> <script type="text/javascript" src="/images/js/jquery-ui.js"></script> <script type="text/javascript" src="/images/js/jquery.confirm.js"></script> <script type="text/javascript" > $(document).ready(function() { // init confirmation dialog $( "#confirm_dialog" ).dialog( // see http://jqueryui.com/docs/dialog/ for options { autoOpen: false, modal: true, closeOnEscape: true, width: 500, buttons: { "Cancel": function() { $( "#" + name ).dialog("close"); } } }); // table initially sorted by col. 1 (admin), then 2 (member), then 0 (name) var sortOrder = [[1,1],[2,1],[0,0]]; // use image path for sorting if there is any inside var imgTitle = function(contents) { var key = $(contents).find("a").attr("class"); if (key == null) { key = $(contents).html(); } return key; } $("#vgridtable").tablesorter({widgets: ["zebra", "saveSort"], sortList:sortOrder, textExtraction: imgTitle }) .tablesorterPager({ container: $("#pager"), size: %s }); } ); </script> ''' % default_pager_entries output_objects.append({'object_type': 'html_form', 'text':''' <div id="confirm_dialog" title="Confirm" style="background:#fff;"> <div id="confirm_text"><!-- filled by js --></div> <textarea cols="40" rows="4" id="confirm_input" style="display:none;"></textarea> </div> ''' }) output_objects.append({'object_type': 'header', 'text': label}) output_objects.append({'object_type': 'text', 'text' : ''' %ss share files, a number of collaboration tools and resources. Members can access web pages, files, tools and resources. Owners can additionally edit pages, as well as add and remove members or resources. ''' % configuration.site_vgrid_label }) if configuration.site_vgrid_label != 'VGrid': output_objects.append({'object_type': 'text', 'text' : """Please note that for historical reasons %ss are also referred to as VGrids in some contexts.""" % \ configuration.site_vgrid_label}) output_objects.append({'object_type': 'sectionheader', 'text' : '%ss managed on this server' % \ configuration.site_vgrid_label}) output_objects.append({'object_type': 'table_pager', 'entry_name': '%ss' % \ configuration.site_vgrid_label, 'default_entries': default_pager_entries}) output_objects.append(member_list) user_map = get_full_user_map(configuration) user_dict = user_map.get(client_id, None) # Optional limitation of create vgrid permission if user_dict and vgrid_create_allowed(configuration, user_dict): output_objects.append({'object_type': 'sectionheader', 'text' : 'Additional %ss' % \ configuration.site_vgrid_label}) output_objects.append( {'object_type': 'text', 'text': '''Please enter a name for the new %(label)s to add, using slashes to specify nesting. I.e. if you own a %(label)s called ABC, you can create a sub-%(label)s called DEF by entering ABC/DEF below.''' % \ {'label': configuration.site_vgrid_label}}) output_objects.append({'object_type': 'html_form', 'text': '''<form method="post" action="createvgrid.py"> <input type="text" size=40 name="vgrid_name" /> <input type="hidden" name="output_format" value="html" /> <input type="submit" value="Create %s" /> </form> ''' % configuration.site_vgrid_label}) output_objects.append({'object_type': 'sectionheader', 'text' : 'Request Access to %ss' % \ configuration.site_vgrid_label}) output_objects.append( {'object_type': 'text', 'text': '''You can request access to %(label)ss using the individual plus-icons above directly or by entering the name of the %(label)s to request access to, what kind of access and an optional message to the admins below''' % \ {'label': configuration.site_vgrid_label}}) output_objects.append({'object_type': 'html_form', 'text': '''<form method="post" action="sendrequestaction.py"> <input type="text" size=40 name="vgrid_name" /> <select name="request_type"> <option value="vgridmember">membership</option> <option value="vgridowner">ownership</option> </select> <input type="text" size=50 name="request_text" /> <input type="hidden" name="output_format" value="html" /> <input type="submit" value="Request %s access" /> </form> ''' % configuration.site_vgrid_label}) 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'] = '%s Resource Monitor' % 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) meta = '''<meta http-equiv="refresh" content="%s" /> ''' % configuration.sleep_secs add_import = ''' <script type="text/javascript" src="/images/js/jquery.tablesorter.js"></script> ''' add_init = '' add_ready = ''' // table initially sorted by col. 1 (name) var sortOrder = [[1,0]]; // use image path for sorting if there is any inside var imgTitle = function(contents) { var key = $(contents).find("a").attr("class"); if (key == null) { key = $(contents).html(); } return key; } $("table.monitor").tablesorter({widgets: ["zebra"], textExtraction: imgTitle, }); $("table.monitor").each(function () { try { $(this).trigger("sorton", [sortOrder]); } catch(err) { /* tablesorter chokes on empty tables - just continue */ } }); ''' title_entry['script']['advanced'] += add_import title_entry['script']['init'] += add_init title_entry['script']['ready'] += add_ready title_entry['meta'] = meta vgrid_access = user_vgrid_access(configuration, client_id) vgrid_list = accepted['vgrid_name'] if all_vgrids in accepted['vgrid_name']: vgrid_list = [i for i in vgrid_list if all_vgrids != i]\ + vgrid_access # Force list to sequence of unique entries for vgrid_name in set(vgrid_list): html = '' if not vgrid_is_owner_or_member(vgrid_name, client_id, configuration): output_objects.append({'object_type': 'error_text', 'text': '''You must be an owner or member of %s %s to access the monitor.''' % (vgrid_name, label)}) return (output_objects, returnvalues.CLIENT_ERROR) monitor_file = os.path.join(configuration.vgrid_home, vgrid_name, '%s.html' % configuration.vgrid_monitor) try: monitor_fd = open(monitor_file, 'r') past_header = False for line in monitor_fd: if -1 != line.find('end of raw header'): past_header = True continue if not past_header: continue if -1 != line.find('begin raw footer:'): break html += str(line) monitor_fd.close() except Exception, exc: output_objects.append({'object_type': 'error_text', 'text': 'Error reading %s monitor page (%s)' % (label, exc)}) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({'object_type': 'html_form', 'text': html})