Beispiel #1
0
def get_unsigned_projects_for_company(company_id):
    """
    Returns a list of projects that the company has not signed a CCLA for. 

    :param company_id: The company's ID.
    :type company_id: string
    :return: dict representation of the projects object.
    :rtype: [dict]
    """
    # Verify company is valid
    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    # get project ids that the company has signed the CCLAs for.
    signature = Signature()
    signed_project_ids = signature.get_projects_by_company_signed(company_id)
    # from all projects, retrieve projects that are not in the signed project ids
    unsigned_projects = [
        project.to_dict() for project in Project().all()
        if project.get_project_id() not in signed_project_ids
    ]
    return unsigned_projects
Beispiel #2
0
def update_company_whitelist_csv(content, company_id, username=None):
    """
    Adds the CSV of email addresse to this company's whitelist.

    :param content: The content posted to this endpoint (CSV data).
    :type content: string
    :param company_id: The ID of the company to add to the whitelist.
    :type company_id: UUID
    """
    company = Company()
    try:
        company.load(str(company_id))
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    company_acl_verify(username, company)

    # Ready email addresses.
    emails = content.split('\n')
    emails = [email for email in emails if '@' in email]
    current_whitelist = company.get_company_whitelist()
    new_whitelist = list(set(current_whitelist + emails))
    company.set_company_whitelist(new_whitelist)
    company.save()
    return company.to_dict()
Beispiel #3
0
def request_company_ccla(user_id, user_email, company_id, project_id):
    """
    Sends email to all company administrators in the company ACL to sign a CCLA for the given project. 
    """
    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}
    user_name = user.get_user_name()

    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    project = Project()
    try:
        project.load(project_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}
    project_name = project.get_project_name()

    # Send an email to sign the ccla for the project for every member in the company ACL
    # account_exists=True since company already exists.
    for admin in company.get_managers():
        send_email_to_admin(user_name, user_email, admin.get_user_name(),
                            admin.get_lf_email(), project_name, True)
Beispiel #4
0
def get_unsigned_projects_for_company(company_id):
    """
    Returns a list of projects that the company has not signed a CCLA for.

    :param company_id: The company's ID.
    :type company_id: string
    :return: dict representation of the projects object.
    :rtype: [dict]
    """
    # Verify company is valid
    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    # get project ids that the company has signed the CCLAs for.
    signature = Signature()
    # signed_project_ids = signature.get_projects_by_company_signed(company_id)
    signed_project_ids = signature.get_projects_by_company_signed(company_id)

    # from all projects, retrieve projects that are not in the signed project ids
    # Consider adding attributes_to_get for the projection
    # unsigned_projects = [project for project in Project().all(attributes_to_get=['project_id'])
    unsigned_projects = [project for project in Project().all() if project.get_project_id() not in signed_project_ids]

    # filter to get unsigned projects that are not of ccla type
    ccla_unsigned_projects = [project.to_dict() for project in unsigned_projects if project.get_project_ccla_enabled()]

    return ccla_unsigned_projects
Beispiel #5
0
def get_project_companies(project_id):
    """
    Get a project's associated companies (via CCLA link).

    :param project_id: The ID of the project.
    :type project_id: string
    """
    project = get_project_instance()
    try:
        project.load(str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    # Get all reference_ids of signatures that match project_id AND are of reference type 'company'.
    # Return all the companies matching those reference_ids.
    signature = Signature()
    signatures = signature.get_signatures_by_project(str(project_id),
                                                     signature_signed=True,
                                                     signature_approved=True,
                                                     signature_reference_type='company')
    company_ids = list(set([signature.get_signature_reference_id() for signature in signatures]))
    company = Company()
    all_companies = [comp.to_dict() for comp in company.all(company_ids)]
    all_companies = sorted(all_companies, key=lambda i: i['company_name'].casefold())

    return all_companies
Beispiel #6
0
def company(company_table):
    """ create project """
    with patch(PATCH_METHOD) as req:
        req.return_value = {}
        company_instance = Company()
        company_instance.set_company_id("foo_company_id")
        company_instance.set_company_name("foo_company_name")
        company_instance.set_signing_entity_name("foo_comapny_entity_name")
        company_instance.save()
        yield company_instance
Beispiel #7
0
def company_instance():
    """
    Mock Company instance
    """
    with patch(PATCH_METHOD) as req:
        req.return_value = COMPANY_TABLE_DATA
        instance = Company()
        instance.set_company_id("uuid")
        instance.set_company_name("co")
        instance.set_company_external_id("external id")
        instance.save()
        yield instance
Beispiel #8
0
def remove_permission(auth_user: AuthUser, username: str, company_id: str):
    if auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

    cla.log.info('company ({}) removed for ({}) by {}'.format(
        company_id, username, auth_user.username))

    company = Company()
    try:
        company.load(company_id)
    except Exception as err:
        print('Unable to update company permission: {}'.format(err))
        return {'error': str(err)}

    company.remove_company_acl(username)
    event_data = 'company ({}) removed for ({}) by {}'.format(
        company_id, username, auth_user.username)
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_company_id=company_id,
        event_type=EventType.RemoveCompanyPermission,
        contains_pii=True,
    )
    company.save()
Beispiel #9
0
def add_permission(auth_user: AuthUser,
                   username: str,
                   company_id: str,
                   ignore_auth_user=False):
    if not ignore_auth_user and auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

    cla.log.info('company ({}) added for user ({}) by {}'.format(
        company_id, username, auth_user.username))

    company = Company()
    try:
        company.load(company_id)
    except Exception as err:
        print('Unable to update company permission: {}'.format(err))
        return {'error': str(err)}

    company.add_company_acl(username)
    event_data = f'Permissions added to user {username} for Company {company.get_company_name()}'
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_type=EventType.AddCompanyPermission,
        event_company_id=company_id,
        contains_pii=True,
    )
    company.save()
Beispiel #10
0
def remove_permission(auth_user: AuthUser, username: str, company_id: str):
    fn = 'controllers.company.remove_permission'
    if auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

    cla.log.info(
        f'{fn} - company ({company_id}) removed for user ({username}) by {auth_user.username}'
    )

    company = Company()
    try:
        company.load(company_id)
    except Exception as err:
        cla.log.warning(f'{fn} - unable to update company permission: {err}')
        return {'error': str(err)}

    company.remove_company_acl(username)
    event_data = f'Removed user {username} from Company {company.get_company_name()} permissions list.'
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_company_id=company_id,
        event_type=EventType.RemoveCompanyPermission,
        contains_pii=True,
    )
    company.save()
Beispiel #11
0
def get_company(company_id):
    try:
        company = Company()
        company.load(company_id)
    except DoesNotExist as err:
        raise DoesNotExist('errors: {company_id: %s}' % str(err))
    return company
Beispiel #12
0
def company_acl_verify(username: str, company: Company):
    if username in company.get_company_acl():
        return True

    raise HTTPForbidden(
        'Unauthorized',
        'Provided Token credentials does not have sufficient permissions to access resource'
    )
Beispiel #13
0
def get_company(company_id):
    """
    Returns the CLA company requested by ID.

    :param company_id: The company's ID.
    :type company_id: ID
    :return: dict representation of the company object.
    :rtype: dict
    """
    company = Company()
    try:
        company.load(company_id=str(company_id))

    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    return company.to_dict()
Beispiel #14
0
def get_company(company_id: str):
    """
    Returns the CLA company requested by ID.

    :param company_id: The company's ID.
    :type company_id: ID
    :return: dict representation of the company object.
    :rtype: dict
    """
    fn = 'controllers.company.get_company'
    company = Company()
    try:
        cla.log.debug(f'{fn} - loading company by company_id: {company_id}...')
        company.load(company_id=str(company_id))
        cla.log.debug(f'{fn} - loaded company by company_id: {company_id}')
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    return company.to_dict()
Beispiel #15
0
def get_companies_by_user(username):
    """
    Returns a list of companies for a user in the CLA system.

    :return: List of companies in dict format.
    :rtype: [dict]
    """
    all_companies = [company.to_dict() for company in Company().all() if username in company.get_company_acl()]

    all_companies = sorted(all_companies, key=lambda i: i['company_name'].casefold())

    return all_companies
Beispiel #16
0
def delete_company(company_id: str, username: str = None):
    """
    Deletes an company based on ID.

    :param company_id: The ID of the company.
    :type company_id: str
    :param username: The username of the user that deleted the company
    :type username: str
    """
    company = Company()
    try:
        company.load(str(company_id))
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    company_acl_verify(username, company)
    company.delete()

    event_data = f'The company {company.get_company_name()} with company_id {company.get_company_id()} was deleted.'
    event_summary = f'The company {company.get_company_name()} was deleted.'
    Event.create_event(
        event_data=event_data,
        event_summary=event_summary,
        event_type=EventType.DeleteCompany,
        event_company_id=company_id,
        contains_pii=False,
    )
    return {'success': True}
Beispiel #17
0
def delete_company(company_id, username=None):
    """
    Deletes an company based on ID.

    :param company_id: The ID of the company.
    :type company_id: ID
    """
    company = Company()
    try:
        company.load(str(company_id))
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    company_acl_verify(username, company)

    company.delete()

    event_data = f'Company- {company.get_company_name()} deleted'
    Event.create_event(
        event_data=event_data,
        event_type=EventType.DeleteCompany,
        event_company_id=company_id,
        contains_pii=False,
    )
    return {'success': True}
Beispiel #18
0
def request_company_ccla(user_id, user_email, company_id, project_id):
    """
    Sends email to all company administrators in the company ACL to sign a CCLA for the given project.
    """
    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}
    user_name = user.get_user_name()

    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    project = Project()
    try:
        project.load(project_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}
    project_name = project.get_project_name()

    # Send an email to sign the ccla for the project for every member in the company ACL
    # account_exists=True since company already exists.
    for admin in company.get_managers():
        send_email_to_admin(user_name, user_email, admin.get_user_name(),
                            admin.get_lf_email(), project_name, True)

    # Audit event
    event_data = f'Sent email to sign ccla for {project.get_project_name() }'
    Event.create_event(
        event_data=event_data,
        event_type=EventType.RequestCCLA,
        event_user_id=user_id,
        event_company_id=company_id,
        contains_pii=False,
    )
Beispiel #19
0
def remove_permission(auth_user: AuthUser, username: str, company_id: str):
    if auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

    cla.log.info('company ({}) removed for ({}) by {}'.format(company_id, username, auth_user.username))

    company = Company()
    try:
        company.load(company_id)
    except Exception as err:
        print('Unable to update company permission: {}'.format(err))
        return {'error': str(err)}

    company.remove_company_acl(username)
    company.save()
Beispiel #20
0
def get_companies_by_user(username: str):
    """
    Returns a list of companies for a user in the CLA system.

    :return: List of companies in dict format.
    :rtype: [dict]
    """
    fn = 'controllers.company.get_companies_by_user'
    cla.log.debug(f'{fn} - loading companies by user: {username}...')
    all_companies = [company.to_dict() for company in Company().all() if username in company.get_company_acl()]
    cla.log.debug(f'{fn} - load companies by user: {username}')
    all_companies = sorted(all_companies, key=lambda i: i['company_name'].casefold())

    return all_companies
Beispiel #21
0
def test_create_default_company_values():
    company = Company(company_name="Google", )

    values = create_default_company_values(
        company=company,
        signatory_name="Signatory1",
        signatory_email="*****@*****.**",
        manager_name="Manager1",
        manager_email="*****@*****.**",
        schedule_a="Schedule")

    assert "corporation_name" in values
    assert "corporation" in values

    company = Company(company_name="Google", signing_entity_name="Google1")

    values = create_default_company_values(
        company=company,
        signatory_name="Signatory1",
        signatory_email="*****@*****.**",
        manager_name="Manager1",
        manager_email="*****@*****.**",
        schedule_a="Schedule")

    assert "corporation_name" in values
    assert "corporation" in values

    values = create_default_company_values(
        company=None,
        signatory_name="Signatory1",
        signatory_email="*****@*****.**",
        manager_name="Manager1",
        manager_email="*****@*****.**",
        schedule_a="Schedule")

    assert "corporation_name" not in values
    assert "corporation" not in values
Beispiel #22
0
def get_companies():
    """
    Returns a list of companies in the CLA system.

    :return: List of companies in dict format.
    :rtype: [dict]
    """
    fn = 'controllers.company.get_companies'

    cla.log.debug(f'{fn} - loading all companies...')
    all_companies = [company.to_dict() for company in Company().all()]
    cla.log.debug(f'{fn} - loaded all companies')
    all_companies = sorted(all_companies, key=lambda i: i['company_name'].casefold())

    return all_companies
Beispiel #23
0
def delete_company(company_id, username=None):
    """
    Deletes an company based on ID.

    :param company_id: The ID of the company.
    :type company_id: ID
    """
    company = Company()
    try:
        company.load(str(company_id))
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    company_acl_verify(username, company)

    company.delete()
    return {'success': True}
Beispiel #24
0
def request_company_admin_access(user_id, company_id):
    """
    Send Email to company admins to inform that that a user is requesting to be a CLA Manager for their company.
    """

    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}
    user_name = user.get_user_name()

    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    subject = 'CLA: Request for Access to Corporate Console'

    # Send emails to every CLA manager
    for admin in company.get_managers():
        body = '''Hello {admin_name},

The following user is requesting CLA Manager access for your organization: {company_name}

    {user_name} <{user_email}>

Navigate to the EasyCLA Corporate Console using the link below and add this user to your Organization's Company Access Control List. Please notify the user once they are added so that they may log in to the EasyCLA Corporate Console with their LFID.

{corporate_console_url}

- EasyCLA System
'''.format(admin_name=admin.get_user_name(),
           user_name=user_name,
           company_name=company.get_company_name(),
           user_email=user_email,
           corporate_console_url='https://{}'.format(
               cla.conf['CORPORATE_BASE_URL']))
        recipient = admin.get_lf_email()
        email_service = get_email_service()
        email_service.send(subject, body, recipient)
Beispiel #25
0
def create_company(auth_user: AuthUser,
                   company_name: str = None,
                   signing_entity_name: str = None,
                   company_manager_id: str = None,
                   company_manager_user_name: str = None,
                   company_manager_user_email: str = None,
                   user_id: str = None,
                   response=None):
    """
    Creates an company and returns the newly created company in dict format.

    :param auth_user: The authenticated user
    :type auth_user: object
    :param company_name: The company name.
    :type company_name: string
    :param signing_entity_name: The company's signing entity name.
    :type signing_entity_name: string
    :param company_manager_id: The ID of the company manager user.
    :type company_manager_id: string
    :param company_manager_user_name: The user name of the company manager user.
    :type company_manager_user_name: string
    :param company_manager_user_email: The user email of the company manager user.
    :type company_manager_user_email: string
    :return: dict representation of the company object.
    :rtype: dict
    """
    fn = 'controllers.company.create_company'
    manager = cla.controllers.user.get_or_create_user(auth_user)

    for company in get_companies():
        if company.get("company_name") == company_name:
            cla.log.error({"error": "Company already exists"})
            response.status = HTTP_409
            return {
                "status_code": HTTP_409,
                "data": {
                    "error": "Company already exists.",
                    "company_id": company.get("company_id")
                }
            }

    cla.log.debug(
        f'{fn} - creating company with name: {company_name} with signing entity name: {signing_entity_name}'
    )
    company = Company()
    company.set_company_id(str(uuid.uuid4()))
    company.set_company_name(company_name)
    company.set_signing_entity_name(signing_entity_name)
    company.set_company_manager_id(manager.get_user_id())
    company.set_company_acl(manager.get_lf_username())
    company.save()
    cla.log.debug(
        f'{fn} - created company with name: {company_name} with company_id: {company.get_company_id()}'
    )

    # Create audit trail for company
    event_data = f'User {auth_user.username} created company {company.get_company_name()} ' \
                 f'with company_id: {company.get_company_id()}.'
    event_summary = f'User {auth_user.username} created company {company.get_company_name()}.'
    Event.create_event(
        event_type=EventType.CreateCompany,
        event_company_id=company.get_company_id(),
        event_data=event_data,
        event_summary=event_summary,
        event_user_id=user_id,
        contains_pii=False,
    )

    return {"status_code": HTTP_200, "data": company.to_dict()}
Beispiel #26
0
def request_company_whitelist(user_id: str,
                              company_id: str,
                              user_name: str,
                              user_email: str,
                              project_id: str,
                              message: str = None,
                              recipient_name: str = None,
                              recipient_email: str = None):
    """
    Sends email to the specified company manager notifying them that a user has requested to be
    added to their approval list.

    :param user_id: The ID of the user requesting to be added to the company's approval list.
    :type user_id: string
    :param company_id: The ID of the company that the request is going to.
    :type company_id: string
    :param user_name: The name hat this user wants to be approved
    :type user_name: string
    :param user_email: The email address that this user wants to be approved. Must exist in the
        user's list of emails.
    :type user_email: string
    :param project_id: The ID of the project that the request is going to.
    :type project_id: string
    :param message: A custom message to add to the email sent out to the manager.
    :type message: string
    :param recipient_name: An optional recipient name for requesting the company approval list
    :type recipient_name: string
    :param recipient_email: An optional recipient email for requesting the company approval list
    :type recipient_email: string
    """
    if project_id is None:
        return {
            'errors': {
                'project_id': 'Project ID is missing from the request'
            }
        }
    if company_id is None:
        return {
            'errors': {
                'company_id': 'Company ID is missing from the request'
            }
        }
    if user_id is None:
        return {'errors': {'user_id': 'User ID is missing from the request'}}
    if user_name is None:
        return {
            'errors': {
                'user_name': 'User Name is missing from the request'
            }
        }
    if user_email is None:
        return {
            'errors': {
                'user_email': 'User Email is missing from the request'
            }
        }
    if recipient_name is None:
        return {
            'errors': {
                'recipient_name': 'Recipient Name is missing from the request'
            }
        }
    if recipient_email is None:
        return {
            'errors': {
                'recipient_email':
                'Recipient Email is missing from the request'
            }
        }
    if message is None:
        return {'errors': {'message': 'Message is missing from the request'}}

    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}

    if user_email not in user.get_user_emails():
        return {
            'errors': {
                'user_email':
                'User\'s email must match one of the user\'s existing emails in their profile'
            }
        }

    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    project = Project()
    try:
        project.load(project_id)
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    company_name = company.get_company_name()
    project_name = project.get_project_name()

    msg = ''
    if message is not None:
        msg += f'<p>{user_name} included the following message in the request:</p>'
        msg += f'<p>{message}</p>'

    subject = f'EasyCLA: Request to Authorize {user_name} for {project_name}'
    body = f'''
<p>Hello {recipient_name},</p>
<p>This is a notification email from EasyCLA regarding the project {project_name}.</p>
<p>{user_name} ({user_email}) has requested to be added to the Allow List as an authorized contributor from
{company_name} to the project {project_name}. You are receiving this message as a CLA Manager from {company} for
{project_name}.</p>
{msg}
<p>If you want to add them to the Allow List, please
<a href="https://{cla.conf['CORPORATE_BASE_URL']}#/company/{company_id}" target="_blank">log into the EasyCLA Corporate
Console</a>, where you can approve this user's request by selecting the 'Manage Approved List' and adding the
contributor's email, the contributor's entire email domain, their GitHub ID or the entire GitHub Organization for the
repository. This will permit them to begin contributing to {project_name} on behalf of {company}.</p>
<p>If you are not certain whether to add them to the Allow List, please reach out to them directly to discuss.</p>
{get_email_help_content(project.get_version() == 'v2')}
{get_email_sign_off_content()}
'''

    cla.log.debug(f'request_company_approval_list - sending email '
                  f'to recipient {recipient_name}/{recipient_email} '
                  f'for user {user_name}/{user_email} '
                  f'for project {project_name} '
                  f'assigned to company {company_name}')
    email_service = get_email_service()
    email_service.send(subject, body, recipient_email)

    # Create event
    event_data = (
        f'CLA: contributor {user_name} requests to be Approved for the '
        f'project: {project_name} '
        f'organization: {company_name} '
        f'as {user_name} <{user_email}>')
    Event.create_event(
        event_user_id=user_id,
        event_project_id=project_id,
        event_company_id=company_id,
        event_type=EventType.RequestCompanyWL,
        event_data=event_data,
        contains_pii=True,
    )
Beispiel #27
0
def request_company_ccla(user_id, user_email, company_id, project_id):
    """
    Sends email to all company administrators in the company ACL to sign a CCLA for the given project.
    """
    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}
    user_name = user.get_user_name()

    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}
    company_name = company.get_company_name()

    project = Project()
    try:
        project.load(project_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}
    project_name = project.get_project_name()

    # Send an email to sign the ccla for the project for every member in the company ACL
    # account_exists=True since company already exists.
    for admin in company.get_managers():
        send_email_to_cla_manager(project, user_name, user_email,
                                  admin.get_user_name(), admin.get_lf_email(),
                                  project_name, company_name, True)

    # Audit event
    event_data = f'Sent email to sign ccla for {project.get_project_name()}'
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_type=EventType.RequestCCLA,
        event_user_id=user_id,
        event_company_id=company_id,
        contains_pii=False,
    )

    msg = (f'user github_id {user.get_user_github_id()}'
           f'user github_username {user.get_user_github_username()}'
           f'user email {user_email}'
           f'for project {project_name}'
           f'for company {company_name}')
    cla.log.debug(f'creating CCLA approval request table entry for {msg}')
    # Add an entry into the CCLA request table
    ccla_whitelist_request = CCLAWhitelistRequest()
    ccla_whitelist_request.set_request_id(str(uuid.uuid4()))
    ccla_whitelist_request.set_company_name(company_name)
    ccla_whitelist_request.set_project_name(project_name)
    ccla_whitelist_request.set_user_github_id(user.get_user_github_id())
    ccla_whitelist_request.set_user_github_username(
        user.get_user_github_username())
    ccla_whitelist_request.set_user_emails({user_email})
    ccla_whitelist_request.set_request_status("pending")
    ccla_whitelist_request.save()
    cla.log.debug(f'created CCLA approval request table entry for {msg}')
Beispiel #28
0
def invite_cla_manager(contributor_id, contributor_name, contributor_email,
                       cla_manager_name, cla_manager_email, project_name,
                       company_name):
    """
    Sends email to the specified CLA Manager to sign up through the Corporate
    console and adds the requested user to the Approved List request queue.

    :param contributor_id: The id of the user inviting the CLA Manager
    :param contributor_name: The name of the user inviting the CLA Manager
    :param contributor_email: The email address that this user wants to be added to the Approved List. Must exist in the user's list of emails.
    :param cla_manager_name: The name of the CLA manager
    :param cla_manager_email: The email address of the CLA manager
    :param project_name: The name of the project
    :param company_name: The name of the organization/company
    """
    user = User()
    try:
        user.load(contributor_id)
    except DoesNotExist as err:
        msg = f'unable to load user by id: {contributor_id} for inviting company admin - error: {err}'
        cla.log.warning(msg)
        return {
            'errors': {
                'user_id': contributor_id,
                'message': msg,
                'error': str(err)
            }
        }

    project = Project()
    try:
        project.load_project_by_name(project_name)
    except DoesNotExist as err:
        msg = f'unable to load project by name: {project_name} for inviting company admin - error: {err}'
        cla.log.warning(msg)
        return {
            'errors': {
                'project_name': project_name,
                'message': msg,
                'error': str(err)
            }
        }
    company = Company()
    try:
        company.load_company_by_name(company_name)
    except DoesNotExist as err:
        msg = f'unable to load company by name: {company_name} - error: {err}'
        cla.log.warning(msg)
        company.set_company_id(str(uuid.uuid4()))
        company.set_company_name(company_name)
        company.save()

    # Add user lfusername if exists
    username = None
    if user.get_lf_username():
        username = user.get_lf_username()
    elif user.get_user_name():
        username = user.get_user_name()
    if username:
        company.add_company_acl(username)
        company.save()

    # create company invite
    company_invite = CompanyInvite()
    company_invite.set_company_invite_id(str(uuid.uuid4()))
    company_invite.set_requested_company_id(company.get_company_id())
    company_invite.set_user_id(user.get_user_id())
    company_invite.save()

    # We'll use the user's provided contributor name - if not provided use what we have in the DB
    if contributor_name is None:
        contributor_name = user.get_user_name()

    log_msg = (
        f'sent email to CLA Manager: {cla_manager_name} with email {cla_manager_email} '
        f'for project {project_name} and company {company_name} '
        f'to user {contributor_name} with email {contributor_email}')
    # Send email to the admin. set account_exists=False since the admin needs to sign up through the Corporate Console.
    cla.log.info(log_msg)
    send_email_to_cla_manager(project, contributor_name, contributor_email,
                              cla_manager_name, cla_manager_email,
                              company_name, False)

    # update ccla_whitelist_request
    ccla_whitelist_request = CCLAWhitelistRequest()
    ccla_whitelist_request.set_request_id(str(uuid.uuid4()))
    ccla_whitelist_request.set_company_name(company_name)
    ccla_whitelist_request.set_project_name(project_name)
    ccla_whitelist_request.set_user_github_id(contributor_id)
    ccla_whitelist_request.set_user_github_username(contributor_name)
    ccla_whitelist_request.set_user_emails(set([contributor_email]))
    ccla_whitelist_request.set_request_status("pending")
    ccla_whitelist_request.save()

    Event.create_event(
        event_user_id=contributor_id,
        event_project_name=project_name,
        event_data=log_msg,
        event_summary=log_msg,
        event_type=EventType.InviteAdmin,
        contains_pii=True,
    )
Beispiel #29
0
def get_manager_companies(manager_id):
    companies = Company().get_companies_by_manager(manager_id)
    return companies
Beispiel #30
0
def request_company_whitelist(user_id: str,
                              company_id: str,
                              user_email: str,
                              project_id: str,
                              message: str = None,
                              recipient_name: str = None,
                              recipient_email: str = None):
    """
    Sends email to the specified company manager notifying them that a user has requested to be
    added to their whitelist.

    :param user_id: The ID of the user requesting to be added to the company's whitelist.
    :type user_id: string
    :param company_id: The ID of the company that the request is going to.
    :type company_id: string
    :param user_email: The email address that this user wants to be whitelisted. Must exist in the
        user's list of emails.
    :type user_email: string
    :param project_id: The ID of the project that the request is going to.
    :type project_id: string
    :param message: A custom message to add to the email sent out to the manager.
    :type message: string
    :param recipient_name: An optional recipient name for requesting the company whitelist
    :type recipient_name: string
    :param recipient_email: An optional recipient email for requesting the company whitelist
    :type recipient_email: string
    """
    if project_id is None:
        return {
            'errors': {
                'project_id': 'Project ID is missing from the request'
            }
        }
    if company_id is None:
        return {
            'errors': {
                'company_id': 'Company ID is missing from the request'
            }
        }
    if user_id is None:
        return {'errors': {'user_id': 'User ID is missing from the request'}}
    if user_email is None:
        return {
            'errors': {
                'user_email': 'User Email is missing from the request'
            }
        }
    if message is None:
        return {'errors': {'message': 'Message is missing from the request'}}

    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}

    emails = user.get_user_emails()
    if user_email not in emails:
        return {
            'errors': {
                'user_email': 'Must provide one of the user\'s existing emails'
            }
        }

    company = Company()
    try:
        company.load(company_id)
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    project = Project()
    try:
        project.load(project_id)
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    user_name = user.get_user_name()
    company_name = company.get_company_name()
    project_name = project.get_project_name()

    # If provided, we will use the parameter for the recipient name and email - if not provided, then we will use the
    # default company manager's email
    if not recipient_name and not recipient_email:
        cla.log.debug(
            'request_company_whitelist - recipient name and email missing from request - '
            'using the company manager as the recipient')
        manager_id = company.get_company_manager_id()
        manager = get_user_instance()
        try:
            manager.load(manager_id)
        except DoesNotExist as err:
            return {
                'errors': {
                    'company_id':
                    'No CLA Manager exists for this company - can not send email'
                }
            }

        recipient_name = manager.get_user_name()
        if manager.get_lf_email() is not None:
            recipient_email = manager.get_lf_email()
        else:
            emails = manager.get_user_emails()
            if len(emails) > 0:
                recipient_email = emails[0]
            else:
                return {
                    'errors': {
                        'manager_email':
                        'Manager email is missing - unable to send to recipient'
                    }
                }

    subject = (
        f'CLA: {user_name} is requesting to be whitelisted for {project_name} project '
        f'as a {company_name} employee')

    body = f'''Hello {recipient_name},

{user_name} is requesting to be whitelisted as a contributor for your organization ({company_name}):

    {user_name} <{user_email}>

The message that was attached to the request:

    {message}

You can whitelist {user_name} in the EasyCLA Corporate console. If the email above is the personal email of one of your employees, please request that they add their organization email to their GitHub profile and try signing the CLA again. If you are unsure about this request, it may be prudent to get in touch with {user_name} to clarify.
Please follow up with the user as necessary.

Click on the following link to navigate to the EasyCLA Corporate Console.

 https://{cla.conf['CORPORATE_BASE_URL']}

- EasyCLA System
'''

    cla.log.debug(f'request_company_whitelist - sending email '
                  f'to recipient {recipient_name}/{recipient_email} '
                  f'for project {project_name} '
                  f'assigned to company {company_name}')
    email_service = get_email_service()
    email_service.send(subject, body, recipient_email)

    # Create event
    event_data = f'CLA: {user.get_user_name()} requests to be whitelisted for the organization {company.get_company_name}'\
                 f'{user.get_user_name()} <{user.get_user_email()}>'
    Event.create_event(
        event_user_id=user_id,
        event_project_id=project_id,
        event_company_id=company_id,
        event_type=EventType.RequestCompanyWL,
        event_data=event_data,
        contains_pii=True,
    )