コード例 #1
0
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 send request' % configuration.short_title
    output_objects.append({
        'object_type': 'header',
        'text': '%s send request' % configuration.short_title
    })
    (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)

    target_id = client_id
    vgrid_name = accepted['vgrid_name'][-1].strip()
    visible_user_names = accepted['cert_id']
    visible_res_names = accepted['unique_resource_name']
    request_type = accepted['request_type'][-1].strip().lower()
    request_text = accepted['request_text'][-1].strip()
    protocols = [proto.strip() for proto in accepted['protocol']]
    use_any = False
    if any_protocol in protocols:
        use_any = True
        protocols = configuration.notify_protocols
    protocols = [proto.lower() for proto in protocols]

    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)

    valid_request_types = [
        'resourceowner', 'resourceaccept', 'resourcereject', 'vgridowner',
        'vgridmember', 'vgridresource', 'vgridaccept', 'vgridreject', 'plain'
    ]
    if not request_type in valid_request_types:
        output_objects.append({
            'object_type':
            'error_text',
            'text':
            '%s is not a valid request_type (valid types: %s)!' %
            (request_type.lower(), valid_request_types)
        })
        return (output_objects, returnvalues.CLIENT_ERROR)

    if not protocols:
        output_objects.append({
            'object_type': 'error_text',
            'text': 'No protocol specified!'
        })
        return (output_objects, returnvalues.CLIENT_ERROR)

    user_map = get_user_map(configuration)
    reply_to = user_map[client_id][USERID]
    # Try to point replies to client_id email
    client_email = extract_field(reply_to, 'email')

    if request_type == "plain":
        if not visible_user_names:
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No user ID specified!'
            })
            return (output_objects, returnvalues.CLIENT_ERROR)

        user_id = visible_user_names[-1].strip()
        anon_map = anon_to_real_user_map(configuration)
        if anon_map.has_key(user_id):
            user_id = anon_map[user_id]
        if not user_map.has_key(user_id):
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No such user: %s' % user_id
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_name = user_id
        user_dict = user_map[user_id]
        vgrid_access = user_vgrid_access(configuration, client_id)
        vgrids_allow_email = user_dict[CONF].get('VGRIDS_ALLOW_EMAIL', [])
        vgrids_allow_im = user_dict[CONF].get('VGRIDS_ALLOW_IM', [])
        if any_vgrid in vgrids_allow_email:
            email_vgrids = vgrid_access
        else:
            email_vgrids = set(vgrids_allow_email).intersection(vgrid_access)
        if any_vgrid in vgrids_allow_im:
            im_vgrids = vgrid_access
        else:
            im_vgrids = set(vgrids_allow_im).intersection(vgrid_access)
        if use_any:
            # Do not try disabled protocols if ANY was requested
            if not email_vgrids:
                protocols = [
                    proto for proto in protocols
                    if proto not in email_keyword_list
                ]
            if not im_vgrids:
                protocols = [
                    proto for proto in protocols if proto in email_keyword_list
                ]
        if not email_vgrids and [
                proto for proto in protocols if proto in email_keyword_list
        ]:
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'You are not allowed to send emails to %s!' % user_id
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        if not im_vgrids and [
                proto for proto in protocols if proto not in email_keyword_list
        ]:
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'You are not allowed to send instant messages to %s!' % user_id
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        for proto in protocols:
            if not user_dict[CONF].get(proto.upper(), False):
                if use_any:
                    # Remove missing protocols if ANY protocol was requested
                    protocols = [i for i in protocols if i != proto]
                else:
                    output_objects.append({
                        'object_type':
                        'error_text',
                        'text':
                        'User %s does not accept %s messages!' %
                        (user_id, proto)
                    })
                    return (output_objects, returnvalues.CLIENT_ERROR)
        if not protocols:
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'User %s does not accept requested protocol(s) messages!' %
                user_id
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_list = [user_id]
    elif request_type in ["vgridaccept", "vgridreject"]:
        # Always allow accept messages but only between owners/members
        if not visible_user_names and not visible_res_names:
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No user or resource ID specified!'
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        if not vgrid_name:
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No vgrid_name specified!'
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        if vgrid_name.upper() == default_vgrid.upper():
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'No requests for %s are allowed!' % default_vgrid
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        if not vgrid_is_owner(vgrid_name, client_id, configuration):
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'You are not an owner of %s or a parent %s!' %
                (vgrid_name, label)
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        # NOTE: we support exactly one vgrid but multiple users/resources here
        if visible_user_names:
            logger.info("setting user recipients: %s" % visible_user_names)
            target_list = [user_id.strip() for user_id in visible_user_names]
        elif visible_res_names:
            # vgrid resource accept - lookup and notify resource owners
            logger.info("setting res owner recipients: %s" % visible_res_names)
            target_list = []
            for unique_resource_name in visible_res_names:
                logger.info("loading res owners for %s" % unique_resource_name)
                (load_status,
                 res_owners) = resource_owners(configuration,
                                               unique_resource_name)
                if not load_status:
                    output_objects.append({
                        'object_type':
                        'error_text',
                        'text':
                        'Could not lookup owners of %s!' % unique_resource_name
                    })
                    continue
                logger.info("adding res owners to recipients: %s" % res_owners)
                target_list += [user_id for user_id in res_owners]

        target_id = '%s %s owners' % (vgrid_name, label)
        target_name = vgrid_name
    elif request_type in ["resourceaccept", "resourcereject"]:
        # Always allow accept messages between actual resource owners
        if not visible_user_names:
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No user ID specified!'
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        if not visible_res_names:
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No resource ID specified!'
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        # NOTE: we support exactly one resource but multiple users here
        unique_resource_name = visible_res_names[-1].strip()
        target_name = unique_resource_name
        res_map = get_resource_map(configuration)
        if not res_map.has_key(unique_resource_name):
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'No such resource: %s' % unique_resource_name
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        owners_list = res_map[unique_resource_name][OWNERS]
        if not client_id in owners_list:
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'You are not an owner of %s!' % unique_resource_name
            })
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'Invalid resource %s message!' % request_type
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_id = '%s resource owners' % unique_resource_name
        target_name = unique_resource_name
        target_list = [user_id.strip() for user_id in visible_user_names]
    elif request_type == "resourceowner":
        if not visible_res_names:
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No resource ID specified!'
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        # NOTE: we support exactly one resource but multiple users here
        unique_resource_name = visible_res_names[-1].strip()
        anon_map = anon_to_real_res_map(configuration.resource_home)
        if anon_map.has_key(unique_resource_name):
            unique_resource_name = anon_map[unique_resource_name]
        target_name = unique_resource_name
        res_map = get_resource_map(configuration)
        if not res_map.has_key(unique_resource_name):
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'No such resource: %s' % unique_resource_name
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_list = res_map[unique_resource_name][OWNERS]
        if client_id in target_list:
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'You are already an owner of %s!' % unique_resource_name
            })
            return (output_objects, returnvalues.CLIENT_ERROR)

        request_dir = os.path.join(configuration.resource_home,
                                   unique_resource_name)
        access_request = {
            'request_type': request_type,
            'entity': client_id,
            'target': unique_resource_name,
            'request_text': request_text
        }
        if not save_access_request(configuration, request_dir, access_request):
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'Could not save request - owners may still manually add you'
            })
            return (output_objects, returnvalues.SYSTEM_ERROR)
    elif request_type in ["vgridmember", "vgridowner", "vgridresource"]:
        if not vgrid_name:
            output_objects.append({
                'object_type': 'error_text',
                'text': 'No vgrid_name specified!'
            })
            return (output_objects, returnvalues.CLIENT_ERROR)

        # default vgrid is read-only

        if vgrid_name.upper() == default_vgrid.upper():
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'No requests for %s are not allowed!' % default_vgrid
            })
            return (output_objects, returnvalues.CLIENT_ERROR)

        # stop owner or member request if already an owner
        # and prevent repeated resource access requests

        if request_type == 'vgridresource':
            # NOTE: we support exactly one resource here
            unique_resource_name = visible_res_names[-1].strip()
            target_id = entity = unique_resource_name
            if vgrid_is_resource(vgrid_name, unique_resource_name,
                                 configuration):
                output_objects.append({
                    'object_type':
                    'error_text',
                    'text':
                    'You already have access to %s or a parent %s.' %
                    (vgrid_name, label)
                })
                return (output_objects, returnvalues.CLIENT_ERROR)
        else:
            target_id = entity = client_id
            if vgrid_is_owner(vgrid_name, client_id, configuration):
                output_objects.append({
                    'object_type':
                    'error_text',
                    'text':
                    'You are already an owner of %s or a parent %s!' %
                    (vgrid_name, label)
                })
                return (output_objects, returnvalues.CLIENT_ERROR)

        # only ownership requests are allowed for existing members

        if request_type == 'vgridmember':
            if vgrid_is_member(vgrid_name, client_id, configuration):
                output_objects.append({
                    'object_type':
                    'error_text',
                    'text':
                    'You are already a member of %s or a parent %s.' %
                    (vgrid_name, label)
                })
                return (output_objects, returnvalues.CLIENT_ERROR)

        # Find all VGrid owners configured to receive notifications

        target_name = vgrid_name
        (settings_status, settings_dict) = vgrid_settings(vgrid_name,
                                                          configuration,
                                                          recursive=True,
                                                          as_dict=True)
        if not settings_status:
            settings_dict = {}
        request_recipients = settings_dict.get('request_recipients',
                                               default_vgrid_settings_limit)
        # We load and use direct owners first if any - otherwise inherited
        owners_list = []
        for inherited in (False, True):
            (owners_status, owners_list) = vgrid_owners(vgrid_name,
                                                        configuration,
                                                        recursive=inherited)
            if not owners_status:
                output_objects.append({
                    'object_type':
                    'error_text',
                    'text':
                    'Failed to lookup owners for %s %s - sure it exists?' %
                    (vgrid_name, label)
                })
                return (output_objects, returnvalues.CLIENT_ERROR)
            elif owners_list:
                break
        if not owners_list:
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'Failed to lookup owners for %s %s - sure it exists?' %
                (vgrid_name, label)
            })
            return (output_objects, returnvalues.CLIENT_ERROR)
        # Now we have direct or inherited owners to notify
        target_list = owners_list[:request_recipients]

        request_dir = os.path.join(configuration.vgrid_home, vgrid_name)
        access_request = {
            'request_type': request_type,
            'entity': entity,
            'target': vgrid_name,
            'request_text': request_text
        }
        if not save_access_request(configuration, request_dir, access_request):
            output_objects.append({
                'object_type':
                'error_text',
                'text':
                'Could not save request - owners may still manually add you'
            })
            return (output_objects, returnvalues.SYSTEM_ERROR)

    else:
        output_objects.append({
            'object_type': 'error_text',
            'text': 'Invalid request type: %s' % request_type
        })
        return (output_objects, returnvalues.CLIENT_ERROR)

    # Now send request to all targets in turn
    # TODO: inform requestor if no owners have mail/IM set in their settings

    logger.debug("sending notification to recipients: %s" % target_list)

    for target in target_list:

        if not target:
            logger.warning("skipping empty notify target: %s" % target_list)
            continue

        # USER_CERT entry is destination

        notify = []
        for proto in protocols:
            notify.append('%s: SETTINGS' % proto)
        job_dict = {
            'NOTIFY': notify,
            'JOB_ID': 'NOJOBID',
            'USER_CERT': target,
            'EMAIL_SENDER': client_email
        }

        notifier = notify_user_thread(
            job_dict,
            [target_id, target_name, request_type, request_text, reply_to],
            'SENDREQUEST',
            logger,
            '',
            configuration,
        )

        # Try finishing delivery but do not block forever on one message
        notifier.join(30)
    output_objects.append({
        'object_type':
        'text',
        'text':
        'Sent %s message to %d people' % (request_type, len(target_list))
    })
    output_objects.append({
        'object_type':
        'text',
        'text':
        """Please make sure you have notifications
configured on your Setings page if you expect a reply to this message"""
    })

    return (output_objects, returnvalues.OK)
コード例 #2
0
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')
    title_entry['text'] = 'People'
    (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)

    operation = accepted['operation'][-1]
    caching = (accepted['caching'][-1].lower() in ('true', 'yes'))

    if not operation in allowed_operations:
        output_objects.append({'object_type': 'text', 'text':
                               '''Operation must be one of %s.''' %
                               ', '.join(allowed_operations)})
        return (output_objects, returnvalues.OK)

    logger.info("%s %s begin for %s" % (op_name, operation, client_id))
    pending_updates = False
    if operation in show_operations:

        # jquery support for tablesorter and confirmation on "send"
        # table initially sorted by 0 (name)

        # NOTE: We distinguish between caching on page load and forced refresh
        refresh_helper = 'ajax_people(%s, %%s)'
        refresh_call = refresh_helper % configuration.notify_protocols
        table_spec = {'table_id': 'usertable', 'sort_order': '[[0,0]]',
                      'refresh_call': refresh_call % 'false'}
        (add_import, add_init, add_ready) = man_base_js(configuration,
                                                        [table_spec],
                                                        {'width': 640})
        if operation == "show":
            add_ready += '%s;' % (refresh_call % 'true')
        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': 'People'})

        output_objects.append(
            {'object_type': 'text', 'text':
             'View and communicate with other users.'
             })

        output_objects.append(
            {'object_type': 'sectionheader', 'text': 'All users'})

        # Helper form for sends

        form_method = 'post'
        csrf_limit = get_csrf_limit(configuration)
        target_op = 'sendrequestaction'
        csrf_token = make_csrf_token(configuration, form_method, target_op,
                                     client_id, csrf_limit)
        helper = html_post_helper('sendmsg', '%s.py' % target_op,
                                  {'cert_id': '__DYNAMIC__',
                                   'protocol': '__DYNAMIC__',
                                   'request_type': 'plain',
                                   'request_text': '',
                                   csrf_field: csrf_token})
        output_objects.append({'object_type': 'html_form', 'text':
                               helper})

        output_objects.append({'object_type': 'table_pager', 'entry_name':
                               'people', 'default_entries':
                               default_pager_entries})

    users = []
    if operation in list_operations:
        logger.info("get vgrid and user map with caching %s" % caching)
        visible_user = user_visible_user_confs(configuration, client_id,
                                               caching)
        vgrid_access = user_vgrid_access(configuration, client_id,
                                         caching=caching)
        anon_map = anon_to_real_user_map(configuration)
        if not visible_user:
            output_objects.append(
                {'object_type': 'error_text', 'text': 'no users found!'})
            return (output_objects, returnvalues.SYSTEM_ERROR)

        if caching:
            modified_users, _ = check_users_modified(configuration)
            modified_vgrids, _ = check_vgrids_modified(configuration)
            if modified_users:
                logger.info("pending user cache updates: %s" % modified_users)
                pending_updates = True
            elif modified_vgrids:
                logger.info("pending vgrid cache updates: %s" %
                            modified_vgrids)
                pending_updates = True
            else:
                logger.info("no pending cache updates")

        for (visible_user_id, user_dict) in visible_user.items():
            user_id = visible_user_id
            if visible_user_id in anon_map.keys():
                # Maintain user anonymity
                pretty_id = 'Anonymous user with unique ID %s' % visible_user_id
                user_id = anon_map[visible_user_id]
            else:
                # Show user-friendly version of user ID
                hide_email = user_dict.get(CONF, {}).get('HIDE_EMAIL_ADDRESS',
                                                         True)
                pretty_id = pretty_format_user(user_id, hide_email)
            user_obj = {'object_type': 'user', 'name': visible_user_id,
                        'pretty_id': pretty_id}
            user_obj.update(user_dict)
            # NOTE: datetime is not json-serializable so we force to string
            created = user_obj.get(CONF, {}).get('CREATED_TIMESTAMP', '')
            if created:
                user_obj[CONF]['CREATED_TIMESTAMP'] = str(created)
            user_obj['userdetailslink'] = \
                {'object_type': 'link',
                 'destination':
                 'viewuser.py?cert_id=%s'
                 % quote(visible_user_id),
                 'class': 'infolink iconspace',
                 'title': 'View details for %s' %
                 visible_user_id,
                 'text': ''}
            vgrids_allow_email = user_dict[CONF].get('VGRIDS_ALLOW_EMAIL', [])
            vgrids_allow_im = user_dict[CONF].get('VGRIDS_ALLOW_IM', [])
            if any_vgrid in vgrids_allow_email:
                email_vgrids = vgrid_access
            else:
                email_vgrids = set(
                    vgrids_allow_email).intersection(vgrid_access)
            if any_vgrid in vgrids_allow_im:
                im_vgrids = vgrid_access
            else:
                im_vgrids = set(vgrids_allow_im).intersection(vgrid_access)
            for proto in configuration.notify_protocols:
                if not email_vgrids and proto == 'email':
                    continue
                if not im_vgrids and proto != 'email':
                    continue
                if user_obj[CONF].get(proto.upper(), None):
                    link = 'send%slink' % proto
                    user_obj[link] = {
                        'object_type': 'link',
                        'destination':
                        "javascript: confirmDialog(%s, '%s', '%s', %s);"
                        % ('sendmsg', 'Really send %s message to %s?'
                           % (proto, visible_user_id),
                           'request_text',
                           "{cert_id: '%s', 'protocol': '%s'}" %
                           (visible_user_id, proto)),
                        'class': "%s iconspace" % link,
                        'title': 'Send %s message to %s' %
                        (proto, visible_user_id),
                        'text': ''}
            logger.debug("append user %s" % user_obj)
            users.append(user_obj)

    if operation == "show":
        # insert dummy placeholder to build table
        user_obj = {'object_type': 'user', 'name': ''}
        users.append(user_obj)

    output_objects.append({'object_type': 'user_list',
                           'pending_updates': pending_updates,
                           'users': users})

    logger.info("%s %s end for %s" % (op_name, operation, client_id))
    return (output_objects, returnvalues.OK)
コード例 #3
0
ファイル: people.py プロジェクト: heromod/migrid
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)

    title_entry = find_entry(output_objects, 'title')
    title_entry['text'] = 'People'

    # 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: 640,
                buttons: {
                   "Cancel": function() { $( "#" + name ).dialog("close"); }
                }
              });

          // table initially sorted by 0 (name)
          var sortOrder = [[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;
          }

          $("#usertable").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'
                          : 'People'})

    output_objects.append(
        {'object_type': 'text', 'text' :
         'View and communicate with other users.'
         })

    output_objects.append({'object_type': 'sectionheader', 'text'
                          : 'All users'})

    visible_user = user_visible_user_confs(configuration, client_id)
    allow_vgrids = user_allowed_vgrids(configuration, client_id)
    anon_map = anon_to_real_user_map(configuration.user_home)
    if not visible_user:
        output_objects.append({'object_type': 'error_text', 'text'
                              : 'no users found!'})
        return (output_objects, returnvalues.SYSTEM_ERROR)

    users = []
    for (visible_user_id, user_dict) in visible_user.items():
        user_id = visible_user_id
        if visible_user_id in anon_map.keys():
            user_id = anon_map[visible_user_id]
        user_obj = {'object_type': 'user', 'name': visible_user_id}
        user_obj.update(user_dict)        
        user_obj['userdetailslink'] = \
                                    {'object_type': 'link',
                                     'destination':
                                     'viewuser.py?cert_id=%s'\
                                     % quote(visible_user_id),
                                     'class': 'infolink',
                                     'title': 'View details for %s' % \
                                     visible_user_id, 
                                     'text': ''}
        vgrids_allow_email = user_dict[CONF].get('VGRIDS_ALLOW_EMAIL', [])
        vgrids_allow_im = user_dict[CONF].get('VGRIDS_ALLOW_IM', [])
        if any_vgrid in vgrids_allow_email:
            email_vgrids = allow_vgrids
        else:
            email_vgrids = set(vgrids_allow_email).intersection(allow_vgrids)
        if any_vgrid in vgrids_allow_im:
            im_vgrids = allow_vgrids
        else:
            im_vgrids = set(vgrids_allow_im).intersection(allow_vgrids)
        for proto in configuration.notify_protocols:
            if not email_vgrids and proto == 'email':
                continue
            if not im_vgrids and proto != 'email':
                continue
            if user_obj[CONF].get(proto.upper(), None):
                js_name = 'send%s%s' % (proto, hexlify(visible_user_id))
                helper = html_post_helper(js_name, 'sendrequestaction.py',
                                          {'cert_id': visible_user_id,
                                           'request_type': 'plain',
                                           'protocol': proto,
                                           'request_text': ''})
                output_objects.append({'object_type': 'html_form', 'text':
                                       helper})
                link = 'send%slink' % proto
                user_obj[link] = {'object_type': 'link',
                                  'destination':
                                  "javascript: confirmDialog(%s, '%s', '%s');"\
                                  % (js_name, 'Really send %s message to %s?'\
                                     % (proto, visible_user_id),
                                     'request_text'),
                                  'class': link,
                                  'title': 'Send %s message to %s' % \
                                  (proto, visible_user_id), 
                                  'text': ''}
        users.append(user_obj)

    output_objects.append({'object_type': 'table_pager', 'entry_name': 'people',
                           'default_entries': default_pager_entries})
    output_objects.append({'object_type': 'user_list',
                          'users': users})

    return (output_objects, returnvalues.OK)
コード例 #4
0
ファイル: sendrequestaction.py プロジェクト: heromod/migrid
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)

    title_entry = find_entry(output_objects, 'title')
    title_entry['text'] = '%s send request' % \
                            configuration.short_title
    output_objects.append({'object_type': 'header', 'text'
                          : '%s send request' % \
                            configuration.short_title})

    target_id = client_id
    vgrid_name = accepted['vgrid_name'][-1].strip()
    visible_user_name = accepted['cert_id'][-1].strip()
    visible_res_name = accepted['unique_resource_name'][-1].strip()
    request_type = accepted['request_type'][-1].strip().lower()
    request_text = accepted['request_text'][-1].strip()
    protocols = [proto.strip() for proto in accepted['protocol']]
    use_any = False
    if any_protocol in protocols:
        use_any = True
        protocols = configuration.notify_protocols
    protocols = [proto.lower() for proto in protocols]

    valid_request_types = ['resourceowner', 'resourceaccept', 'vgridowner',
                           'vgridmember','vgridresource', 'vgridaccept',
                           'plain']
    if not request_type in valid_request_types:
        output_objects.append({
            'object_type': 'error_text', 'text'
            : '%s is not a valid request_type (valid types: %s)!'
            % (request_type.lower(),
               valid_request_types)})
        return (output_objects, returnvalues.CLIENT_ERROR)

    if not protocols:
        output_objects.append({
            'object_type': 'error_text', 'text':
            'No protocol specified!'})
        return (output_objects, returnvalues.CLIENT_ERROR)

    user_map = get_user_map(configuration)
    reply_to = user_map[client_id][USERID]

    if request_type == "plain":
        if not visible_user_name:
            output_objects.append({
                'object_type': 'error_text', 'text':
                'No user ID specified!'})
            return (output_objects, returnvalues.CLIENT_ERROR)

        user_id = visible_user_name
        anon_map = anon_to_real_user_map(configuration.user_home)
        if anon_map.has_key(visible_user_name):
            user_id = anon_map[visible_user_name]
        if not user_map.has_key(user_id):
            output_objects.append({'object_type': 'error_text',
                                   'text': 'No such user: %s' % \
                                   visible_user_name
                                   })
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_name = user_id
        user_dict = user_map[user_id]
        allow_vgrids = user_allowed_vgrids(configuration, client_id)
        vgrids_allow_email = user_dict[CONF].get('VGRIDS_ALLOW_EMAIL', [])
        vgrids_allow_im = user_dict[CONF].get('VGRIDS_ALLOW_IM', [])
        if any_vgrid in vgrids_allow_email:
            email_vgrids = allow_vgrids
        else:
            email_vgrids = set(vgrids_allow_email).intersection(allow_vgrids)
        if any_vgrid in vgrids_allow_im:
            im_vgrids = allow_vgrids
        else:
            im_vgrids = set(vgrids_allow_im).intersection(allow_vgrids)
        if use_any:
            # Do not try disabled protocols if ANY was requested
            if not email_vgrids:
                protocols = [proto for proto in protocols \
                             if proto not in email_keyword_list]
            if not im_vgrids:
                protocols = [proto for proto in protocols \
                             if proto in email_keyword_list]
        if not email_vgrids and [proto for proto in protocols \
                                 if proto in email_keyword_list]:
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'You are not allowed to send emails to %s!' % \
                visible_user_name
                })
            return (output_objects, returnvalues.CLIENT_ERROR)
        if not im_vgrids and [proto for proto in protocols \
                              if proto not in email_keyword_list]:
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'You are not allowed to send instant messages to %s!' % \
                visible_user_name
                })
            return (output_objects, returnvalues.CLIENT_ERROR)
        for proto in protocols:
            if not user_dict[CONF].get(proto.upper(), False):
                if use_any:
                    # Remove missing protocols if ANY protocol was requested
                    protocols = [i for i in protocols if i != proto]
                else:
                    output_objects.append({
                        'object_type': 'error_text', 'text'
                        : 'User %s does not accept %s messages!' % \
                        (visible_user_name, proto)
                        })
                    return (output_objects, returnvalues.CLIENT_ERROR)
        if not protocols:
            output_objects.append({
                'object_type': 'error_text', 'text':
                'User %s does not accept requested protocol(s) messages!' % \
                visible_user_name})
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_list = [user_id]
    elif request_type == "vgridaccept":
        # Always allow accept messages but only between vgrid members/owners
        user_id = visible_user_name
        if not vgrid_name:
            output_objects.append({
                'object_type': 'error_text', 'text': 'No vgrid_name specified!'})
            return (output_objects, returnvalues.CLIENT_ERROR)
        if vgrid_name.upper() == default_vgrid.upper():
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'No requests for %s are not allowed!' % \
                default_vgrid
                })
            return (output_objects, returnvalues.CLIENT_ERROR)
        if not vgrid_is_owner(vgrid_name, client_id, configuration):
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'You are not an owner of %s or a parent %s!' % \
                (vgrid_name, configuration.site_vgrid_label)})
            return (output_objects, returnvalues.CLIENT_ERROR)
        allow_vgrids = user_allowed_vgrids(configuration, client_id)
        if not vgrid_name in allow_vgrids:
            output_objects.append({
                'object_type': 'error_text', 'text':
                'Invalid %s message! (%s sv %s)' % (request_type, user_id,
                                                    allow_vgrids)})
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_id = '%s %s owners' % (vgrid_name, configuration.site_vgrid_label)
        target_name = vgrid_name
        target_list = [user_id]
    elif request_type == "resourceaccept":
        # Always allow accept messages between actual resource owners
        user_id = visible_user_name
        if not visible_res_name:
            output_objects.append({
                'object_type': 'error_text', 'text':
                'No resource ID specified!'})
            return (output_objects, returnvalues.CLIENT_ERROR)
        unique_resource_name = visible_res_name
        target_name = unique_resource_name
        res_map = get_resource_map(configuration)
        if not res_map.has_key(unique_resource_name):
            output_objects.append({'object_type': 'error_text',
                                   'text': 'No such resource: %s' % \
                                   unique_resource_name
                                   })
            return (output_objects, returnvalues.CLIENT_ERROR)
        owners_list = res_map[unique_resource_name][OWNERS]
        if not client_id in owners_list or not user_id in owners_list:
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'Invalid resource owner accept message!'})
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_id = '%s resource owners' % unique_resource_name
        target_name = unique_resource_name
        target_list = [user_id]
    elif request_type == "resourceowner":
        if not visible_res_name:
            output_objects.append({
                'object_type': 'error_text', 'text':
                'No resource ID specified!'})
            return (output_objects, returnvalues.CLIENT_ERROR)
        
        unique_resource_name = visible_res_name
        anon_map = anon_to_real_res_map(configuration.resource_home)
        if anon_map.has_key(visible_res_name):
            unique_resource_name = anon_map[visible_res_name]
        target_name = unique_resource_name
        res_map = get_resource_map(configuration)
        if not res_map.has_key(unique_resource_name):
            output_objects.append({'object_type': 'error_text',
                                   'text': 'No such resource: %s' % \
                                   visible_res_name
                                   })
            return (output_objects, returnvalues.CLIENT_ERROR)
        target_list = res_map[unique_resource_name][OWNERS]
        if client_id in target_list:
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'You are already an owner of %s!' % unique_resource_name
                })
            return (output_objects, returnvalues.CLIENT_ERROR)
    elif request_type in ["vgridmember", "vgridowner", "vgridresource"]:
        unique_resource_name = visible_res_name
        if not vgrid_name:
            output_objects.append({
                'object_type': 'error_text', 'text': 'No vgrid_name specified!'})
            return (output_objects, returnvalues.CLIENT_ERROR)

        # default vgrid is read-only
        
        if vgrid_name.upper() == default_vgrid.upper():
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'No requests for %s are not allowed!' % \
                default_vgrid
                })
            return (output_objects, returnvalues.CLIENT_ERROR)

        # stop owner or member request if already an owner

        if request_type != 'vgridresource':
            if vgrid_is_owner(vgrid_name, client_id, configuration):
                output_objects.append({
                    'object_type': 'error_text', 'text'
                    : 'You are already an owner of %s or a parent %s!' % \
                    (vgrid_name, configuration.site_vgrid_label)})
                return (output_objects, returnvalues.CLIENT_ERROR)

        # only ownership requests are allowed for existing members

        if request_type == 'vgridmember':
            if vgrid_is_member(vgrid_name, client_id, configuration):
                output_objects.append({
                    'object_type': 'error_text', 'text'
                    : 'You are already a member of %s or a parent %s.' % \
                    (vgrid_name, configuration.site_vgrid_label)})
                return (output_objects, returnvalues.CLIENT_ERROR)

        # set target to resource and prevent repeated resource access requests

        if request_type == 'vgridresource':
            target_id = unique_resource_name
            if vgrid_is_resource(vgrid_name, unique_resource_name,
                                 configuration):
                output_objects.append({
                    'object_type': 'error_text', 'text'
                    : 'You already have access to %s or a parent %s.' % \
                    (vgrid_name, configuration.site_vgrid_label)})
                return (output_objects, returnvalues.CLIENT_ERROR)

        # Find all VGrid owners

        target_name = vgrid_name
        (status, target_list) = vgrid_list(vgrid_name, 'owners', configuration)
        if not status:
            output_objects.append({
                'object_type': 'error_text', 'text'
                : 'Could not load list of current owners for %s %s!'
                % (vgrid_name, configuration.site_vgrid_label)})
            return (output_objects, returnvalues.CLIENT_ERROR)

    else:
        output_objects.append({
            'object_type': 'error_text', 'text': 'Invalid request type: %s' % \
            request_type})
        return (output_objects, returnvalues.CLIENT_ERROR)

    # Now send request to all targets in turn
    # TODO: inform requestor if no owners have mail/IM set in their settings
    
    for target in target_list:
        # USER_CERT entry is destination

        notify = []
        for proto in protocols:
            notify.append('%s: SETTINGS' % proto)
        job_dict = {'NOTIFY': notify, 'JOB_ID': 'NOJOBID', 'USER_CERT': target}

        notifier = notify_user_thread(
            job_dict,
            [target_id, target_name, request_type, request_text, reply_to],
            'SENDREQUEST',
            logger,
            '',
            configuration,
            )

        # Try finishing delivery but do not block forever on one message
        notifier.join(30)
    output_objects.append({'object_type': 'text', 'text':
                           'Sent %s message to %d people' % \
                           (request_type, len(target_list))})
    output_objects.append({'object_type': 'text', 'text':
                           """Please make sure you have notifications
configured on your Setings page if you expect a reply to this message"""})
    
    return (output_objects, returnvalues.OK)