Beispiel #1
0
def test_add_project_manager(mock_event, project):
    """ Tests event logging where LFID is added to the project ACL """
    event_type = EventType.AddProjectManager
    username = '******'
    lfid = 'manager'
    Project.load = Mock()
    Project.get_project_name = Mock(return_value=project.get_project_name())
    Project.save = Mock()
    user = User()
    user.set_user_name('foo')
    Project.get_managers_by_project_acl = Mock(return_value=[user])
    Project.add_project_acl = Mock()
    Project.get_project_acl = Mock(return_value=('foo'))

    project_controller.add_project_manager(
        username,
        project.get_project_id(),
        lfid
    )
    event_data = '{} added {} to project {}'.format(username,lfid,project.get_project_name())

    mock_event.assert_called_with(
        event_type=event_type,
        event_data=event_data,
        event_summary=event_data,
        event_project_id=project.get_project_id(),
        contains_pii=True,
    )
Beispiel #2
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 #3
0
def user_signed_project_signature(user: User, project_id: str, latest_major_version=True):
    """
    Helper function to check if a user has signed a project signature tied to a repository.
    Will consider both ICLA and employee signatures.

    :param user: The user object to check for.
    :type user: cla.models.model_interfaces.User
    :param project_id: The project to check for.
    :type project_id: string
    :param latest_major_version: True means only the latest document major version will be considered.
    :type latest_major_version: bool
    :return: Whether or not the user has an signature that's signed and approved
        for this project.
    :rtype: boolean
    """

    # Check if we have an ICLA for this user
    cla.log.debug(f'checking to see if user has signed an ICLA, user: {user}, project: {project_id}')

    signature = user.get_latest_signature(project_id)
    icla_pass = False
    if signature is not None:
        icla_pass = user_icla_check(user, project_id, signature, latest_major_version)
    else:
        cla.log.debug(f'ICLA signature NOT found for User: {user} on project: {project_id}')

    # If we passed the ICLA check - good, return true, no need to check CCLA
    if icla_pass:
        cla.log.debug(f'ICLA signature check passed for User: {user} on project: {project_id} - skipping CCLA check')
        return True
    else:
        cla.log.debug(f'ICLA signature check failed for User: {user} on project: {project_id} - will now check CCLA')

    # Check if we have an CCLA for this user
    company_id = user.get_user_company_id()
    cla.log.debug('checking to see if user has signed an CCLA, '
                  f'user: {user}, project_id: {project_id}, company_id: {company_id}')

    ccla_pass = False
    if company_id is not None:
        cla.log.debug('user has company_id set - getting latest signature for '
                      f'user: {user}, project_id: {project_id}, company_id: {company_id}')
        signature = user.get_latest_signature(project_id, company_id=company_id)

        # Don't check the version for employee signatures.
        if signature is not None:
            ccla_pass = user_ccla_check(user, project_id, signature)
    else:
        cla.log.debug(f'User: {user} is NOT associated with a company - unable to check for a CCLA.')

    if ccla_pass:
        cla.log.debug(f'CCLA signature check passed for User: {user} on project: {project_id}')
        return True
    else:
        cla.log.debug(f'CCLA signature check failed for User: {user} on project: {project_id}')

    cla.log.debug(f'User: {user} failed both ICLA and CCLA checks')
    return False
Beispiel #4
0
def user(user_table):
    """ create user """
    with patch(PATCH_METHOD) as req:
        req.return_value = {}
        user_instance = User()
        user_instance.set_user_id("user_foo_id")
        user_instance.set_user_email("*****@*****.**")
        user_instance.set_user_name("foo_username")
        user_instance.save()
        yield user_instance
Beispiel #5
0
def user_instance():
    """
    Mock user instance
    """
    with patch(PATCH_METHOD) as req:
        req.return_value = USER_TABLE_DATA
        instance = User()
        instance.set_user_id("foo")
        instance.set_user_name("username")
        instance.set_user_external_id("bar")
        instance.save()
        yield instance
Beispiel #6
0
    def test_user_get_user_by_github_username(self) -> None:
        """
        Test that we can get a user by github username
        """
        # TODO - should use mock data - disable tests for now :-(
        if self.tests_enabled:
            users = User().get_user_by_github_username('dealako')
            self.assertIsNotNone(users, 'User lookup by github username is not None')
            self.assertEqual(len(users), 1, 'User lookup by github username found 1')

            # some invalid username
            users = User().get_user_by_github_username('foooooo')
            self.assertIsNone(users, 'User lookup by github username is None')
Beispiel #7
0
    def test_user_get_user_by_github_id(self) -> None:
        """
        Test that we can get a user by github id
        """
        # TODO - should use mock data - disable tests for now :-(
        if self.tests_enabled:
            users = User().get_user_by_github_id(519609)
            self.assertIsNotNone(users, 'User lookup by github id is not None')
            self.assertEqual(len(users), 2, 'User lookup by github id found 2')

            # some invalid number
            users = User().get_user_by_github_id(9999999)
            self.assertIsNone(users, 'User lookup by github id is None')
Beispiel #8
0
    def test_user_get_user_by_email(self) -> None:
        """
        Test that we can get a user by email
        """
        # TODO - should use mock data - disable tests for now :-(
        if self.tests_enabled:
            users = User().get_user_by_email('*****@*****.**')
            self.assertIsNotNone(users, 'User lookup by email is not None')
            self.assertEqual(len(users), 1, 'User lookup by email found 1')

            # some invalid email
            users = User().get_user_by_email('*****@*****.**')
            self.assertIsNone(users, 'User lookup by email is None')
Beispiel #9
0
def create_bot_signature(bot_user: User, signature: Signature) -> Optional[Signature]:
    cla.log.debug(f'create_bot_signature - locating Bot Signature for: {bot_user.get_user_name()}...')
    project: Project = cla.utils.get_project_instance()
    try:
        project.load(signature.get_signature_project_id())
    except DoesNotExist as err:
        cla.log.warning(f'create_bot_signature - unable to load project by id: {signature.get_signature_project_id()}'
                        f' Unable to create bot: {bot_user}')
        return None

    the_company: Company = cla.utils.get_company_instance()
    try:
        the_company.load(signature.get_signature_reference_id())
    except DoesNotExist as err:
        cla.log.warning(f'create_bot_signature - unable to load company by id: {signature.get_signature_reference_id()}'
                        f' Unable to create bot: {bot_user}')
        return None

    bot_sig: Signature = cla.utils.get_signature_instance()

    # First, before we create a new one, grab a list of employee signatures for this company/project
    existing_sigs: List[Signature] = bot_sig.get_employee_signatures_by_company_project_model(
        company_id=bot_user.get_user_company_id(), project_id=signature.get_signature_project_id())

    # Check to see if we have an existing signature for this user/company/project combo
    for sig in existing_sigs:
        if sig.get_signature_reference_id() == bot_user.get_user_id():
            cla.log.debug('create_bot_signature - found existing bot signature '
                          f'for user: {bot_user} '
                          f'with company: {the_company} '
                          f'for project: {project}')
            return sig

    # Didn't find an existing signature, let's create a new one
    cla.log.debug(f'create_bot_signature - creating Bot Signature: {bot_user.get_user_name()}...')
    bot_sig.set_signature_id(str(uuid.uuid4()))
    bot_sig.set_signature_project_id(signature.get_signature_project_id())
    bot_sig.set_signature_reference_id(bot_user.get_user_id())
    bot_sig.set_signature_document_major_version(signature.get_signature_document_major_version())
    bot_sig.set_signature_document_minor_version(signature.get_signature_document_minor_version())
    bot_sig.set_signature_approved(True)
    bot_sig.set_signature_signed(True)
    bot_sig.set_signature_type('cla')
    bot_sig.set_signature_reference_type('user')
    bot_sig.set_signature_user_ccla_company_id(bot_user.get_user_company_id())
    bot_sig.set_note(f'{datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")} Added as part of '
                     f'{project.get_project_name()}, approval list by '
                     f'{the_company.get_company_name()}')
    bot_sig.save()
    cla.log.debug(f'create_bot_signature - created Bot Signature: {bot_sig}')
    return bot_sig
Beispiel #10
0
def invite_company_admin(user_id, user_email, admin_name, admin_email,
                         project_name):
    """
    Sends email to the specified company administrator to sign up through the Corporate console and add the requested user to the whitelist. 
    """
    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}

    # Send email to the admin. set account_exists=False since the admin needs to sign up through the Corporate Console.
    send_email_to_admin(user.get_user_name(), user_email, admin_name,
                        admin_email, project_name, False)
Beispiel #11
0
def test_request_company_ccla(mock_event, create_event_user, user, project,
                              company):
    """ Test request company ccla event """
    User.load = Mock()
    User.get_user_name = Mock(return_value=user.get_user_name())
    email = user.get_user_email()
    Company.load = Mock()
    Project.load = Mock()
    Project.get_project_name = Mock(return_value=project.get_project_name())
    manager = User(lf_username="******", user_email="*****@*****.**")
    Company.get_managers = Mock(return_value=[
        manager,
    ])
    event_data = f"Sent email to sign ccla for {project.get_project_name() }"
    user_controller.request_company_ccla(user.get_user_id(), email,
                                         company.get_company_id(),
                                         project.get_project_id())
    mock_event.assert_called_once_with(
        event_data=event_data,
        event_summary=event_data,
        event_type=EventType.RequestCCLA,
        event_user_id=user.get_user_id(),
        event_company_id=company.get_company_id(),
        contains_pii=False,
    )
Beispiel #12
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,
    )
Beispiel #13
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 #14
0
def invite_company_admin(user_id, user_email, admin_name, admin_email,
                         project_name):
    """
    Sends email to the specified CLA Manager to sign up through the Corporate console and add the requested user to the whitelist.
    """
    user = User()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}

    # Send email to the admin. set account_exists=False since the admin needs to sign up through the Corporate Console.
    send_email_to_admin(user.get_user_name(), user_email, admin_name,
                        admin_email, project_name, False)

    event_data = f'{user_id} with {user_email} sends to {admin_name}/{admin_email} for project: {project_name}'
    Event.create_event(
        event_user_id=user_id,
        event_project_name=project_name,
        event_data=event_data,
        event_type=EventType.InviteAdmin,
        contains_pii=True,
    )
Beispiel #15
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
Beispiel #16
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
Beispiel #17
0
def get_managers_dict(signature_acl):
    # Helper function to get a list of all cla managers from a CCLA Signature ACL
    # Generate managers dict
    managers_dict = []
    for lfid in signature_acl:
        user = User()
        user = user.get_user_by_username(str(lfid))
        if user is not None:
            # 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
Beispiel #18
0
def update_github_username(github_user: dict, user: User):
    """
    When provided a GitHub user model from the GitHub service, updates the CLA
    user record with the github username.
    :param github_user:  the github user model as a dict from GitHub
    :param user:  the user DB object
    :return: None
    """
    # set the github username if available
    if 'login' in github_user:
        if user.get_user_github_username() is None:
            cla.log.debug(f'Updating user record - adding github username: {github_user["login"]}')
            user.set_user_github_username(github_user['login'])
        if user.get_user_github_username() != github_user['login']:
            cla.log.warning(f'Note: github user with id: {github_user["id"]}'
                            f' has a mismatched username (gh: {github_user["id"]} '
                            f'vs db user record: {user.get_user_github_username}) - '
                            f'setting the value to: {github_user["login"]}')
            user.set_user_github_username(github_user['login'])
Beispiel #19
0
def user():
    yield User()
def mock_get_user_by_github_username(username):
    u1 = User()
    u1.set_user_email('*****@*****.**')
    return [u1]
def mock_get_managers():
    u1 = User()
    u1.set_lf_email('*****@*****.**')
    u2 = User()
    u2.set_lf_email('*****@*****.**')
    return [u1, u2]
Beispiel #22
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,
    )
Beispiel #23
0
def get_or_create_user(auth_user):
    user = User()

    # Returns None or List[User] objects - could be more than one
    users = user.get_user_by_username(str(auth_user.username))

    if users is None:
        user.set_user_id(str(uuid.uuid4()))
        user.set_user_name(auth_user.name)
        user.set_lf_email(auth_user.email.lower())
        user.set_lf_username(auth_user.username)
        user.set_lf_sub(auth_user.sub)

        user.save()

        event_data = f'CLA user added for {auth_user.username}'
        Event.create_event(
            event_data=event_data,
            event_type=EventType.CreateUser,
            contains_pii=True,
        )

        return user

    # Just return the first matching record
    return users[0]
Beispiel #24
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 #25
0
def get_user_emails(lfid):
    """ Helper function that gets user emails of given lf_username """
    user = User()
    users = user.get_user_by_username(lfid)
    return [user.get_user_email() for user in users]
Beispiel #26
0
def get_or_create_user(auth_user):
    user = User()

    existing_user = user.get_user_by_username(str(auth_user.username))

    if existing_user is None:
        user.set_user_id(str(uuid.uuid4()))
        user.set_user_name(auth_user.name)
        user.set_lf_email(auth_user.email.lower())
        user.set_lf_username(auth_user.username)
        user.set_lf_sub(auth_user.sub)

        user.save()

        return user

    return existing_user
Beispiel #27
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,
    )
Beispiel #28
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)
Beispiel #29
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 #30
0
def fmt_user(user: User):
    return '{} ({}) {}'.format(user.get_user_name(), user.get_user_id(),
                               user.get_lf_email())