Example #1
0
def create(ticket_data):
    """ Ticket creation handler. """
    cf_email_address = custom_fields.get("Email Address")
    email_address = shared_sd.get_field(ticket_data, cf_email_address)
    if email_address is None:
        # It shouldn't be - it is a mandatory field ...
        shared_sd.post_comment(
            "It has not been possible to create the account as requested.",
            True)
        shared_sd.post_comment(
            "Unable to retrieve email address from CF %s" % cf_email_address,
            False)
        shared_sd.resolve_ticket("Declined")
        return

    email_address = email_address.strip().lower()
    email_address = shared_ldap.cleanup_if_gmail(email_address)

    shared_sd.set_summary("Create external user/account for %s" %
                          email_address)

    if not ok_to_proceed(email_address):
        return

    cf_first_name = custom_fields.get("First Name")
    cf_family_name = custom_fields.get("Family Name")
    first_name = shared_sd.get_field(ticket_data, cf_first_name)
    if first_name is not None:
        first_name = first_name.strip()
    surname = shared_sd.get_field(ticket_data, cf_family_name).strip()

    uid = shared_ldap.calculate_uid(first_name, surname)
    if uid is None:
        shared_sd.post_comment(
            "It has not been possible to create the account as requested.",
            True)
        shared_sd.post_comment(
            "Cannot calculated UID for '%s' '%s'" % (first_name, surname),
            False)
        shared_sd.resolve_ticket("Declined")
        return

    md5_password = None
    cf_account_type = custom_fields.get("External Account / Contact")
    account_type = shared_sd.get_field(ticket_data, cf_account_type)
    if account_type != "Contact":
        _, md5_password = linaro_shared.make_password()
    account_dn = shared_ldap.create_account(first_name, surname, email_address,
                                            md5_password)
    if account_dn is None:
        shared_sd.post_comment(
            "Sorry but something went wrong while creating the entry", True)
        shared_sd.transition_request_to("Waiting for support")
        shared_sd.assign_issue_to(None)
        return

    if account_type != "Contact":
        send_new_account_email(first_name, surname, email_address, account_dn)

    shared_sd.resolve_ticket()
Example #2
0
def process_public_comment(ticket_data, last_comment, keyword):
    """ Logic to process a public comment """
    shared_sd.assign_issue_to(shared.globals.CONFIGURATION["bot_name"])
    # If the original reporter IS a group owner, we will only accept comments
    # from the same person and those comments will be add/remove commands.
    #
    # Otherwise, deassign and let IT work on what was said.
    _, result = get_group_details(ticket_data)
    # Make sure that the group still exists because this is all asynchronous
    # and anything could have happened!
    if not group_sanity_check(result):
        return True
    if ("owner" in result[0]
            and shared_ldap.reporter_is_group_owner(result[0].owner.values)
            and keyword in ("add", "remove")):
        distinguished = result[0].entry_dn
        grp_name = shared_ldap.extract_id_from_dn(distinguished)
        changes = last_comment["body"].split("\n")
        batch_process_membership_changes(grp_name, changes, False)
        return True
    return False
def create(ticket_data):
    """ Create handler. """
    # There aren't any fields in the form for us to process. This
    # is a simple case of checking that the requestor is a member of
    # staff and then adding them to the group that controls SSH access
    # to the system.
    email_address = shared_sd.reporter_email_address(ticket_data)
    account_dn = shared_ldap.find_from_email(email_address)
    valid_account = shared_ldap.is_dn_in_group("employees", account_dn) or \
        shared_ldap.is_dn_in_group("assignees", account_dn)
    if not valid_account:
        shared_sd.post_comment(
            "You must be a Linaro employee or assignee to use the "
            "hackbox2 service.",
            True)
        shared_sd.resolve_ticket(resolution_state="Won't Do")
        return
    if shared_ldap.is_dn_in_group("hackbox-users", account_dn):
        shared_sd.post_comment(
            "You appear to already have access.",
            True)
        shared_sd.resolve_ticket()
        return
    if shared_ldap.add_to_group("hackbox-users", account_dn):
        shared_sd.post_comment(
            "Access has been granted. Please ensure you read "
            "https://collaborate.linaro.org/display/IKB/Hackbox2 "
            "and associated documentation so that you fully understand "
            "what this service is, how to use it and what the limitations "
            "are.",
            True)
        shared_sd.resolve_ticket()
    else:
        shared_sd.post_comment(
            "A problem occurred while adding you to the permission list. "
            "It will be necessary to get IT Services to investigate.",
            True)
        # Deassign the ticket
        shared_sd.assign_issue_to(None)
        shared_sd.transition_request_to("Waiting for Support")
Example #4
0
def create(ticket_data):
    """ Triggered when the issue is created """
    cf_approvers = custom_fields.get("Approvers")
    group_email_address, result = get_group_details(ticket_data)

    shared_sd.set_summary("Add/Remove group members for %s" %
                          group_email_address)
    shared_sd.assign_issue_to(shared.globals.CONFIGURATION["bot_name"])
    if not group_sanity_check(result):
        return

    group_obj = result[0]
    if "owner" not in group_obj:
        if shared_ldap.is_user_in_group("its", shared.globals.REPORTER):
            shared_sd.transition_request_to("In progress")
            return

        shared_sd.post_comment(
            "This group has no owners. Asking IT Services to review your"
            " request.", True)
        it_members = shared_ldap.get_group_membership(
            "cn=its,ou=mailing,ou=groups,dc=linaro,dc=org")
        shared_sd.assign_approvers(it_members, cf_approvers)
        return

    if IT_BOT in group_obj.owner.values:
        shared_sd.post_comment(
            "Sorry but the membership of this group is maintained"
            " automatically.", True)
        shared_sd.resolve_ticket(WONT_DO)
        return

    if shared_ldap.reporter_is_group_owner(group_obj.owner.values):
        shared_sd.transition_request_to("In progress")
        return

    shared_sd.post_comment(
        "As you are not an owner of this group, the owners will be asked"
        " to approve or decline your request.", True)
    shared_sd.assign_approvers(group_obj.owner.values, cf_approvers)
Example #5
0
def process_public_comment(ticket_data, last_comment, keyword):
    """Logic to process a public comment."""
    shared_sd.assign_issue_to(shared.globals.CONFIGURATION["bot_name"])
    # If the original reporter IS a group owner, we will only accept comments
    # from the same person and those comments will be add/remove commands.
    #
    # Otherwise, deassign and let IT work on what was said.
    #
    # Get the definitive email address for the group and the owner(s).
    cf_group_email_address = custom_fields.get(GROUP_EMAIL_ADDRESS)
    group_email_address = shared_sd.get_field(
        ticket_data, cf_group_email_address).strip().lower()
    group_email_address, result = shared_ldap.find_group(
        group_email_address, ['owner'])
    # Make sure that the group still exists because this is all asynchronous
    # and anything could have happened!
    if len(result) == 0:
        shared_sd.post_comment(
            "Sorry but the group's email address can't be found in Linaro "
            "Login.", True)
        shared_sd.resolve_ticket(WONT_DO)
        return True
    if len(result) != 1:
        shared_sd.post_comment(
            "Sorry but, somehow, the group's email address appears more than "
            "once in Linaro Login.", True)
        shared_sd.resolve_ticket(WONT_DO)
        return True

    if (result[0].owner.values != [] and
            shared_ldap.reporter_is_group_owner(result[0].owner.values) and
            keyword in ("add", "remove")):
        grp_name = shared_ldap.extract_id_from_dn(result[0].entry_dn)
        changes = last_comment["body"].split("\n")
        batch_process_ownership_changes(grp_name, changes)
        post_owners_of_group_as_comment(result[0].entry_dn)
        return True

    return False
Example #6
0
def create(ticket_data):
    """ Triggered when the issue is created """
    shared_sd.assign_issue_to(shared.globals.CONFIGURATION["bot_name"])
    # Keep the linter happy
    _ = ticket_data
    # Need to get all of the groups, with their owners
    all_groups = shared_ldap.find_matching_objects(
        "(objectClass=groupOfUniqueNames)",
        ["owner", "displayName", "cn", "uniqueMember"]
    )
    owned_groups = []
    for group in all_groups:
        owners = group.owner.values
        if shared_ldap.reporter_is_group_owner(owners):
            owned_groups.append(group)
    if owned_groups == []:
        shared_sd.post_comment(
            "You do not appear to be the owner of any "
            "groups on Linaro Login.", True
        )
        shared_sd.resolve_ticket()
        return

    owned_groups = sorted(owned_groups, key=group_name_lower)
    response = (
        "Below are the groups you can manage.\n\n"
        "There are automated Service Desk requests for [changing the "
        "membership of a group|https://servicedesk.linaro.org/servicedesk"
        "/customer/portal/3/create/139] and [changing the owners of a "
        "group|https://servicedesk.linaro.org/servicedesk/customer/portal"
        "/3/create/140].\n\n"
    )
    for group in owned_groups:
        empty = check_if_group_has_members(group)
        response += "* %s%s\n" % (group_name(group), empty)
    shared_sd.post_comment(response, True)
    shared_sd.resolve_ticket()
def create(ticket_data):
    """ Create handler. """
    # Start by making sure that the requester is in IT or HR.
    email_address = shared_sd.reporter_email_address(ticket_data)
    account_dn = shared_ldap.find_from_email(email_address)
    valid_account = shared_ldap.is_dn_in_group("hr", account_dn) or \
        shared_ldap.is_dn_in_group("it-services", account_dn)
    if not valid_account:
        shared_sd.post_comment(
            "You must be in HR or IT Services to use this request.", True)
        shared_sd.resolve_ticket(resolution_state="Won't Do")
        return

    outcome = RESULT_STATE.Done
    cf_addresses = custom_fields.get("Email Address(s) of Users")
    addresses = shared_sd.get_field(ticket_data, cf_addresses).split("\r\n")
    for address in addresses:
        # Clean up by trimming white space.
        clean = address.strip().lower()
        if clean != "":
            result = transition_user_account(clean)
            if (result == RESULT_STATE.IT
                    or (result == RESULT_STATE.Customer
                        and outcome == RESULT_STATE.Done)):
                outcome = result
    # Did all of the accounts transition?
    if outcome == RESULT_STATE.Done:
        shared_sd.resolve_ticket()
    elif outcome == RESULT_STATE.Customer:
        shared_sd.post_comment(
            "Sorry but it has not been possible to fully process your request. "
            "Hopefully the above comments are helpful. Further replies to this "
            "ticket will be handled by IT Services staff rather than the automation bot.",
            True)
        shared_sd.assign_issue_to(None)
    else:
        shared_sd.transition_request_to("Waiting for Support")
Example #8
0
def create(ticket_data):
    """Triggered when the issue is created."""
    cf_group_email_address = custom_fields.get(GROUP_EMAIL_ADDRESS)
    group_email_address = shared_sd.get_field(
        ticket_data, cf_group_email_address).strip().lower()
    group_email_address, result = shared_ldap.find_group(
        group_email_address, ['owner'])

    shared_sd.set_summary(
        "View/Change group ownership for %s" % group_email_address)
    shared_sd.assign_issue_to(shared.globals.CONFIGURATION["bot_name"])

    if len(result) == 0:
        shared_sd.post_comment(
            "Sorry but the group's email address can't be found in Linaro "
            "Login.", True)
        shared_sd.resolve_ticket(WONT_DO)
        return
    if len(result) != 1:
        shared_sd.post_comment(
            "Sorry but, somehow, the group's email address appears more than "
            "once in Linaro Login.", True)
        shared_sd.resolve_ticket(WONT_DO)
        return
    # See if the bot owns this group
    owners = result[0].owner.values
    if (len(owners) == 1 and owners[0] == IT_BOT):
        shared_sd.post_comment(
            (
                "This group is maintained through automation. It is not "
                "possible to change the owners of this group or raise "
                "tickets to directly change the membership. If you want "
                "to understand how this group is maintained automatically, "
                "please raise a general IT Services support ticket."
            ),
            True
        )
        shared_sd.resolve_ticket()
        return

    # Do we have any changes to process? If not, post the current owners to
    # the ticket.
    cf_group_owners = custom_fields.get("Group Owners")
    ownerchanges = shared_sd.get_field(ticket_data, cf_group_owners)
    if ownerchanges is None:
        post_owners_of_group_as_comment(result[0].entry_dn)
        if shared_ldap.reporter_is_group_owner(result[0].owner.values):
            shared_sd.post_comment(
                ("As you are an owner of this group, you can make changes to "
                 "the ownership by posting new comments to this ticket with "
                 "the following format:\r\n"
                 "*add* <email address>\r\n"
                 "*remove* <email address>\r\n"
                 "One command per line but you can have multiple changes in a "
                 "single comment. If you do not get the syntax right, the "
                 "automation will not be able to understand your request and "
                 "processing will stop.\r\n"), True)
            shared_sd.transition_request_to("Waiting for customer")
        else:
            shared_sd.post_comment(
                "As you are not an owner of this group, if you want to make "
                "changes to the ownership, you will need to open a "
                "[new ticket|https://servicedesk.linaro.org/servicedesk/"
                "customer/portal/3/create/140].", True)
            shared_sd.resolve_ticket()
        return

    # There are changes ... but is the requester a group owner?
    cf_approvers = custom_fields.get("Approvers")
    if result[0].owner.values == []:
        # No owners at all. IT is always allowed to make changes
        if shared_ldap.is_user_in_group("its", shared.globals.REPORTER):
            shared_sd.transition_request_to("In progress")
        else:
            shared_sd.post_comment(
                "This group has no owners. Asking IT Services to review "
                "your request.", True)
            it_members = shared_ldap.get_group_membership(
                "cn=its,ou=mailing,ou=groups,dc=linaro,dc=org")
            shared_sd.assign_approvers(it_members, cf_approvers)
            shared_sd.transition_request_to("Needs approval")
    elif shared_ldap.reporter_is_group_owner(result[0].owner.values):
        shared_sd.transition_request_to("In progress")
    else:
        shared_sd.post_comment(
            "As you are not an owner of this group, the owners will be "
            "asked to approve or decline your request.", True)
        shared_sd.assign_approvers(result[0].owner.values, cf_approvers)
        shared_sd.transition_request_to("Needs approval")