Ejemplo n.º 1
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)
Ejemplo n.º 2
0
def get_project(project_id):
    try:
        project = Project()
        project.load(project_id)
    except DoesNotExist as err:
        raise DoesNotExist('errors: {project_id: %s}' % str(err))
    return project
Ejemplo n.º 3
0
def get_projects_by_external_id(project_external_id, username):
    """
    Returns the CLA projects requested by External ID.

    :param project_external_id: The project's External ID.
    :type project_external_id: string
    :param username: username of the user
    :type username: string
    :return: dict representation of the project object.
    :rtype: dict
    """

    # Check if user has permissions on this project
    user_permissions = UserPermissions()
    try:
        user_permissions.load(username)
    except DoesNotExist as err:
        return {'errors': {'username': '******'}}

    user_permissions_json = user_permissions.to_dict()
    authorized_projects = user_permissions_json.get('projects')

    if project_external_id not in authorized_projects:
        return {'errors': {'username': '******'}}

    try:
        project = Project()
        projects = project.get_projects_by_external_id(str(project_external_id), username)
    except DoesNotExist as err:
        return {'errors': {'project_external_id': str(err)}}
    return [project.to_dict() for project in projects]
Ejemplo n.º 4
0
def project(project_table):
    """ create project """
    with patch(PATCH_METHOD) as req:
        req.return_value = {}
        project_instance = Project()
        project_instance.set_project_id("foo_project_id")
        project_instance.set_project_external_id("foo_external_id")
        project_instance.set_project_name("foo_project_name")
        project_instance.save()
        yield project_instance
Ejemplo n.º 5
0
def get_signature_approved_email_content(signature):  # pylint: disable=invalid-name
    """Helper function to get signature approval email subject, body, and recipients."""
    if signature.get_signature_reference_type() != 'user':
        cla.log.info('Not sending signature approved emails for CCLAs')
        return
    subject = 'CLA Signature Approved'
    user = User()
    user.load(signature.get_signature_reference_id())
    project = Project()
    project.load(signature.get_signature_project_id())
    recipients = [user.get_user_id()]
    body = 'Hello %s. Your Contributor License Agreement for %s has been approved!' \
           %(user.get_user_name(), project.get_project_name())
    return subject, body, recipients
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
0
def test_delete_project_document(mock_event):
    """ Test event for deleting document from the specified project """
    project = Project()
    project.set_project_id("foo_project_id")
    project.set_project_name("foo_project_name")
    event_type = EventType.DeleteProjectDocument
    project_id = project.get_project_id()
    document_type = "individual"
    major_version = "v1"
    minor_version = "v1"
    event_data = (
                f'Project {project.get_project_name()} with {document_type} :'
                +f'document type , minor version : {minor_version}, major version : {major_version}  deleted'
    )

    Project.load = Mock()
    Project.save = Mock()
    Project.remove_project_individual_document = Mock()
    project_controller.project_acl_verify = Mock()
    cla.utils.get_project_document = Mock()

    project_controller.delete_project_document(
        project_id, document_type, major_version, minor_version
    )

    mock_event.assert_called_with(
        event_type=event_type, event_project_id=project_id, event_data=event_data, event_summary=event_data, contains_pii = False,
    )
Ejemplo n.º 9
0
 def test_handle_commit_author_whitelisted(self) -> None:
     """
     Test case where commit authors have no signatures but have been whitelisted and should
     return missing list containing a whitelisted flag
     """
     # Mock user not existing and happens to be whitelisted
     self.mock_user_get.return_value.get_user_by_github_id.return_value = None
     self.mock_user_get.return_value.get_user_by_email.return_value = None
     self.mock_signature_get.return_value.get_signatures_by_project.return_value = [Signature()]
     self.mock_utils_get.return_value.is_approved.return_value = True
     missing = []
     signed = []
     project = Project()
     project.set_project_id('fake_project_id')
     handle_commit_from_user(project, 'fake_sha', (123, 'foo', '*****@*****.**'), signed, missing)
     # We commented out this functionality for now - re-enable if we add it back
     # self.assertListEqual(missing, [('fake_sha', [123, 'foo', '*****@*****.**', True])])
     self.assertEqual(signed, [])
Ejemplo n.º 10
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,
    )
Ejemplo n.º 11
0
def get_project_configuration_orgs_and_repos(auth_user: AuthUser, project_id):
    # Load Project
    project = Project()
    try:
        project.load(project_id=str(project_id))
    except DoesNotExist as err:
        return {'valid': False, 'errors': {'errors': {'project_id': str(err)}}}

    # Get SFDC project identifier
    sfid = project.get_project_external_id()

    # Validate user is authorized for this project
    can_access = check_user_authorization(auth_user, sfid)
    if not can_access['valid']:
        return can_access['errors']

    # Obtain information for this project
    orgs_and_repos = get_github_repositories_by_org(project)
    repositories = get_sfdc_project_repositories(project)
    return {'orgs_and_repos': orgs_and_repos, 'repositories': repositories}
Ejemplo n.º 12
0
def add_project_manager(username, project_id, lfid):
    """
    Adds the LFID to the project ACL
    :param username: username of the user
    :type username: string
    :param project_id: The ID of the project
    :type project_id: UUID
    :param lfid: the lfid (manager username) to be added to the project acl
    :type lfid: string
    """
    # Find project
    project = Project()
    try:
        project.load(project_id=str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    # Validate user is the manager of the project
    if username not in project.get_project_acl():
        return {
            'errors': {
                'user': "******"
            }
        }
    # TODO: Validate if lfid is valid

    # Add lfid to project acl
    project.add_project_acl(lfid)
    project.save()

    # Get managers
    managers = project.get_managers()

    # Generate managers dict
    managers_dict = [{
        'name': manager.get_user_name(),
        'email': manager.get_user_email(),
        'lfid': manager.get_lf_username()
    } for manager in managers]

    return managers_dict
Ejemplo n.º 13
0
def get_project_repositories(auth_user: AuthUser, project_id):
    """
    Get a project's repositories.

    :param project_id: The ID of the project.
    :type project_id: string
    """

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

    # Get SFDC project identifier
    sfid = project.get_project_external_id()

    # Validate user is authorized for this project
    can_access = check_user_authorization(auth_user, sfid)
    if not can_access['valid']:
        return can_access['errors']

    # Obtain repositories
    repositories = project.get_project_repositories()
    return [repository.to_dict() for repository in repositories]
Ejemplo n.º 14
0
def get_project_managers(username, project_id, enable_auth):
    """
    Returns the CLA project managers from the project's ID
    :param username: The LF username
    :type username: string
    :param project_id: The project's ID.
    :type project_id: string
    :return: dict representation of the project managers.
    :rtype: dict
    """
    project = Project()
    try:
        project.load(project_id=str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    if enable_auth is True and username not in project.get_project_acl():
        return {
            'errors': {
                'user_id': 'You are not authorized to see the managers.'
            }
        }

    # Generate managers dict
    managers_dict = []
    for lfid in project.get_project_acl():
        user = User()
        users = user.get_user_by_username(str(lfid))
        if users is not None:
            if len(users) > 1:
                cla.log.warning(
                    f'More than one user record was returned ({len(users)}) from user '
                    f'username: {lfid} query')
            user = users[0]
            # Manager found, fill with it's information
            managers_dict.append({
                'name': user.get_user_name(),
                'email': user.get_user_email(),
                'lfid': user.get_lf_username()
            })
        else:
            # Manager not in database yet, only set the lfid
            managers_dict.append({'lfid': str(lfid)})

    return managers_dict
Ejemplo n.º 15
0
def get_project_repositories_group_by_organization(auth_user: AuthUser,
                                                   project_id):
    """
    Get a project's repositories.

    :param project_id: The ID of the project.
    :type project_id: string
    """

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

    # Get SFDC project identifier
    sfid = project.get_project_external_id()

    # Validate user is authorized for this project
    can_access = check_user_authorization(auth_user, sfid)
    if not can_access['valid']:
        return can_access['errors']

    # Obtain repositories
    repositories = project.get_project_repositories()
    repositories = [repository.to_dict() for repository in repositories]

    # Group them by organization
    organizations_dict = {}
    for repository in repositories:
        org_name = repository['repository_organization_name']
        if org_name in organizations_dict:
            organizations_dict[org_name].append(repository)
        else:
            organizations_dict[org_name] = [repository]

    organizations = []
    for key, value in organizations_dict.items():
        organizations.append({'name': key, 'repositories': value})

    return organizations
Ejemplo n.º 16
0
def remove_project_manager(username, project_id, lfid):
    """
    Removes the LFID from the project ACL
    :param username: username of the user
    :type username: string
    :param project_id: The ID of the project
    :type project_id: UUID
    :param lfid: the lfid (manager username) to be removed to the project acl
    :type lfid: string
    """
    # Find project
    project = Project()
    try:
        project.load(project_id=str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    # Validate user is the manager of the project
    if username not in project.get_project_acl():
        return {'errors': {'user': "******"}}
    # TODO: Validate if lfid is valid

    # Avoid to have an empty acl
    if len(project.get_project_acl()) == 1 and username == lfid:
        return {'errors': {'user': "******"}}
    # Add lfid to project acl
    project.remove_project_acl(lfid)
    project.save()

    # Get managers
    managers = project.get_managers()

    # Generate managers dict
    managers_dict = [{
        'name': manager.get_user_name(),
        'email': manager.get_user_email(),
        'lfid': manager.get_lf_username()
    } for manager in managers]

    # log event
    event_data = f'{lfid} removed from project {project.get_project_id()}'
    Event.create_event(
        event_type=EventType.RemoveProjectManager,
        event_data=event_data,
        event_project_id=project_id,
        contains_pii=True,
    )

    return managers_dict
Ejemplo n.º 17
0
def create_signature(
        signature_project_id,  # pylint: disable=too-many-arguments
        signature_reference_id,
        signature_reference_type,
        signature_type='cla',
        signature_approved=False,
        signature_signed=False,
        signature_return_url=None,
        signature_sign_url=None,
        signature_user_ccla_company_id=None,
        signature_acl=None):
    """
    Creates an signature and returns the newly created signature in dict format.

    :param signature_project_id: The project ID for this new signature.
    :type signature_project_id: string
    :param signature_reference_id: The user or company ID for this signature.
    :type signature_reference_id: string
    :param signature_reference_type: The type of reference ('user' or 'company')
    :type signature_reference_type: string
    :param signature_type: The signature type ('cla' or 'dco')
    :type signature_type: string
    :param signature_signed: Whether or not the signature has been signed.
    :type signature_signed: boolean
    :param signature_approved: Whether or not the signature has been approved.
    :type signature_approved: boolean
    :param signature_return_url: The URL the user will be redirected to after signing.
    :type signature_return_url: string
    :param signature_sign_url: The URL the user must visit to sign the signature.
    :type signature_sign_url: string
    :param signature_user_ccla_company_id: The company ID if creating an employee signature.
    :type signature_user_ccla_company_id: string
    :return: A dict of a newly created signature.
    :rtype: dict
    """
    signature = Signature()
    signature.set_signature_id(str(uuid.uuid4()))
    project = Project()
    try:
        project.load(project_id=str(signature_project_id))
    except DoesNotExist as err:
        return {'errors': {'signature_project_id': str(err)}}
    signature.set_signature_project_id(str(signature_project_id))
    if signature_reference_type == 'user':
        user = User()
        try:
            user.load(signature_reference_id)
        except DoesNotExist as err:
            return {'errors': {'signature_reference_id': str(err)}}
        try:
            document = project.get_project_individual_document()
        except DoesNotExist as err:
            return {'errors': {'signature_project_id': str(err)}}
    else:
        company = Company()
        try:
            company.load(signature_reference_id)
        except DoesNotExist as err:
            return {'errors': {'signature_reference_id': str(err)}}
        try:
            document = project.get_project_corporate_document()
        except DoesNotExist as err:
            return {'errors': {'signature_project_id': str(err)}}

    # Set username to this signature ACL
    if signature_acl is not None:
        signature.set_signature_acl(signature_acl)

    signature.set_signature_document_minor_version(
        document.get_document_minor_version())
    signature.set_signature_document_major_version(
        document.get_document_major_version())
    signature.set_signature_reference_id(str(signature_reference_id))
    signature.set_signature_reference_type(signature_reference_type)
    signature.set_signature_type(signature_type)
    signature.set_signature_signed(signature_signed)
    signature.set_signature_approved(signature_approved)
    signature.set_signature_return_url(signature_return_url)
    signature.set_signature_sign_url(signature_sign_url)
    if signature_user_ccla_company_id is not None:
        signature.set_signature_user_ccla_company_id(
            str(signature_user_ccla_company_id))
    signature.save()
    return signature.to_dict()
Ejemplo n.º 18
0
def test_get_full_sign_url():
    p = Project()
    p.set_version("v1")
    url = get_full_sign_url("github", "1234", 456, 1, p.get_version())
    assert "?version=1" in url

    p = Project()
    p.set_version("v2")
    url = get_full_sign_url("github", "1234", 456, 1, p.get_version())
    assert "?version=2" in url

    p = Project()
    url = get_full_sign_url("github", "1234", 456, 1, p.get_version())
    assert "?version=1" in url
Ejemplo n.º 19
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,
    )
Ejemplo n.º 20
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)
            }
        }

    # 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_type=EventType.InviteAdmin,
        contains_pii=True,
    )
Ejemplo n.º 21
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}')
Ejemplo n.º 22
0
def request_company_whitelist(user_id,
                              company_id,
                              user_email,
                              project_id,
                              message=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 messsage: A custom message to add to the email sent out to the manager.
    :type message: string
    """
    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()

    subject = '''CLA: %s is requesting to be whitelisted for %s project ''' % (
        user_name, project_name)

    body = '''%s is requesting to be whitelisted as a contributor for your organization (%s):

    %s <%s>

The message that was attached to the request:

    %s

You can whitelist %s in the CLA 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 %s to clarify.
Please follow up with the user as necessary.

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

 %s  

- Linux Foundation CLA System
''' % (user_name, company_name, user_name, user_email, message, user_name,
       user_name, 'https://{}'.format(cla.conf['CORPORATE_BASE_URL']))

    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 manager exists for this company - can not send email'
            }
        }
    recipient = manager.get_user_email()
    email_service = get_email_service()
    email_service.send(subject, body, recipient)
Ejemplo n.º 23
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,
    )
Ejemplo n.º 24
0
def fmt_project(project: Project):
    return "{} ({})".format(project.get_project_name(),
                            project.get_project_id())
Ejemplo n.º 25
0
def mock_project(project_id):
    self = Project()
    return self
Ejemplo n.º 26
0
def create_repository(auth_user: AuthUser, # pylint: disable=too-many-arguments
                      repository_project_id,
                      repository_name,
                      repository_organization_name, 
                      repository_type,
                      repository_url,
                      repository_external_id=None):
    """
    Creates a repository and returns the newly created repository in dict format.

    :param repository_project_id: The ID of the repository project.
    :type repository_project_id: string
    :param repository_name: The new repository name.
    :type repository_name: string
    :param repository_type: The new repository type ('github', 'gerrit', etc).
    :type repository_organization_name: string
    :param repository_organization_name: The repository organization name
    :type repository_type: string
    :param repository_url: The new repository URL.
    :type repository_url: string
    :param repository_external_id: The ID of the repository from the repository provider.
    :type repository_external_id: string
    :return: dict representation of the new repository object.
    :rtype: dict
    """

    # Check that organization exists 
    github_organization = GitHubOrg()
    try:
        github_organization.load(str(repository_organization_name))
    except DoesNotExist as err:
        return {'errors': {'organization_name': str(err)}}

    # Check that project is valid. 
    project = Project()
    try:
        project.load(str(repository_project_id))
    except DoesNotExist as err:
        return {'errors': {'repository_project_id': str(err)}}

    # Get SFDC project identifier
    sfdc_id = project.get_project_external_id()

    # Validate user is authorized for this project
    can_access = cla.controllers.project.check_user_authorization(auth_user, sfdc_id)
    if not can_access['valid']:
      return can_access['errors']

    # Validate if exist already repository linked to a contract group
    if repository_external_id is not None:
        # Seach for the repository
        linked_repository = Repository().get_repository_by_external_id(repository_external_id, repository_type)
        # If found return an error
        if linked_repository is not None:
            return {'errors': {'repository_external_id': 'This repository is alredy configured for a contract group.'}}

    repository = Repository()
    repository.set_repository_id(str(uuid.uuid4()))
    repository.set_repository_project_id(str(repository_project_id))
    repository.set_repository_sfdc_id(str(sfdc_id))
    repository.set_repository_name(repository_name)
    repository.set_repository_organization_name(repository_organization_name)
    repository.set_repository_type(repository_type)
    repository.set_repository_url(repository_url)
    if repository_external_id is not None:
        repository.set_repository_external_id(repository_external_id)
    repository.save()
    return repository.to_dict()