Ejemplo n.º 1
0
def get_user(user_id=None, user_email=None, user_github_id=None):
    """
    Returns the CLA user requested by ID or email.

    :param user_id: The user's ID.
    :type user_id: string
    :param user_email: The user's email address.
    :type user_email: string
    :param user_github_id: The user's github ID.
    :type user_github_id: integer
    :return: dict representation of the user object.
    :rtype: dict
    """
    if user_id is not None:
        user = get_user_instance()
        try:
            user.load(user_id)
        except DoesNotExist as err:
            return {'errors': {'user_id': str(err)}}
    elif user_email is not None:
        users = get_user_instance().get_user_by_email(str(user_email).lower())
        if users is None:
            return {'errors': {'user_email': 'User not found'}}
        # Use the first user for now - need to revisit - what if multiple are returned?
        user = users[0]
    elif user_github_id is not None:
        users = get_user_instance().get_user_by_github_id(user_github_id)
        if users is None:
            return {'errors': {'user_github_id': 'User not found'}}
        # Use the first user for now - need to revisit - what if multiple are returned?
        user = users[0]
    return user.to_dict()
Ejemplo n.º 2
0
def get_user_project_company_last_signature(user_id, project_id, company_id):
    """
    Returns the user's last signature object for a project.

    :param user_id: The ID of the user.
    :type user_id: string
    :param project_id: The project in question.
    :type project_id: string
    :param company_id: The ID of the company that this employee belongs to.
    :type company_id: string
    :return: The signature object that was last signed by the user for this project.
    :rtype: cla.models.model_interfaces.Signature
    """
    user = get_user_instance()
    try:
        user.load(str(user_id))
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}
    last_signature = user.get_latest_signature(str(project_id),
                                               company_id=str(company_id))
    if last_signature is not None:
        last_signature = last_signature.to_dict()
        latest_doc = cla.utils.get_project_latest_corporate_document(
            str(project_id))
        last_signature['latest_document_major_version'] = str(
            latest_doc.get_document_major_version())
        last_signature['latest_document_minor_version'] = str(
            latest_doc.get_document_minor_version())
        last_signature['requires_resigning'] = last_signature[
            'latest_document_major_version'] != last_signature[
                'signature_document_major_version']
    return last_signature
Ejemplo n.º 3
0
def get_users():
    """
    Returns a list of users in the CLA system.

    :return: List of users in dict format.
    :rtype: [dict]
    """
    return [user.to_dict() for user in get_user_instance().all()]
Ejemplo n.º 4
0
def user_instance():
    """
    Mock user instance
    """
    with patch(PATCH_METHOD) as req:
        req.return_value = USER_TABLE_DATA
        instance = get_user_instance()
        instance.set_user_id("foo")
        instance.set_user_external_id("bar")
        instance.save()
        yield instance
Ejemplo n.º 5
0
def get_users_company(user_company_id):
    """
    Fetches all users that are associated with the company specified.

    :param user_company_id: The ID of the company in question.
    :type user_company_id: string
    :return: A list of user data in dict format.
    :rtype: [dict]
    """
    users = get_user_instance().get_users_by_company(user_company_id)
    return [user.to_dict() for user in users]
Ejemplo n.º 6
0
    def test_user_get_user_by_username(self) -> None:
        """
        Test that we can get a user by username
        """
        # TODO - should use mock data - disable tests for now :-(
        if self.tests_enabled:
            user_instance = utils.get_user_instance()
            users = user_instance.get_user_by_username('ddeal')
            self.assertIsNotNone(users, 'User lookup by username is not None')
            self.assertEqual(len(users), 1, 'User lookup by username found 1')

            # some invalid username
            users = user_instance.get_user_by_username('foo')
            self.assertIsNone(users, 'User lookup by username is None')
Ejemplo n.º 7
0
def get_user_signatures(user_id):
    """
    Given a user ID, returns the user's signatures.

    :param user_id: The user's ID.
    :type user_id: string
    :return: list of signature data for this user.
    :rtype: [dict]
    """
    user = get_user_instance()
    try:
        user.load(user_id)
    except DoesNotExist as err:
        return {'errors': {'user_id': str(err)}}
    signatures = user.get_user_signatures()
    return [agr.to_dict() for agr in signatures]
Ejemplo n.º 8
0
def test_create_event():
    """
    Test endpoint that creates event instance
    """
    url = "/v1/events"
    event_project_id = str(uuid.uuid4())
    event_company_id = str(uuid.uuid4())
    user_id = str(uuid.uuid4())

    payload = {
        "event_type": "cla",
        "event_company_id": event_company_id,
        "event_project_id": event_project_id,
        "user_id": user_id,
        "event_data": json.dumps({"foo": "bar"}),
    }

    response = hug.test.post(routes, url, payload)
    assert response.status == HTTP_400

    user = get_user_instance()
    user.set_user_id(user_id)
    user.save()
    company = get_company_instance()
    company.set_company_id(event_company_id)
    company.set_company_name("foobar")
    company.save()
    project = get_project_instance()
    project.set_project_name("project")
    project.set_project_external_id(str(uuid.uuid4()))
    project.set_project_id(event_project_id)
    project.save()
    response = hug.test.post(routes, url, payload)
    assert response.status == HTTP_200
    assert response.data["data"]["event_type"] == "cla"
    assert response.data["data"]["event_company_id"] == event_company_id
    assert response.data["data"]["event_project_id"] == event_project_id
    assert response.data["data"]["user_id"] == user_id
    assert response.data["data"]["event_data"] == json.dumps({"foo": "bar"})
Ejemplo n.º 9
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.º 10
0
Convenience script to create a ICLA and CCLA signature in the CLA system.
"""
import uuid
import sys
sys.path.append('../')

import cla
from cla.utils import get_signature_instance, get_user_instance, get_project_instance, \
                      get_company_instance

PROJECT_EXTERNAL_ID1 = 'a090t0000008DEiAAM'
PROJECT_EXTERNAL_ID2 = 'a090t0000008E7iAAE'
COMPANY_EXTERNAL_ID = 'company-external-id'
USER_GITHUB_ID = 123

user = get_user_instance().get_user_by_github_id(USER_GITHUB_ID)
project1 = get_project_instance().get_projects_by_external_id(PROJECT_EXTERNAL_ID1)[0]
project2 = get_project_instance().get_projects_by_external_id(PROJECT_EXTERNAL_ID2)[0]
company = get_company_instance().get_company_by_external_id(COMPANY_EXTERNAL_ID)

# Test ICLA Agreement.
sig_id = str(uuid.uuid4())
cla.log.info('Creating ICLA signature for user %s and project %s: %s' \
             %(user.get_user_name(), project1.get_project_external_id(), sig_id))
signature = get_signature_instance()
signature.set_signature_id(sig_id)
signature.set_signature_project_id(project1.get_project_id())
signature.set_signature_signed(True)
signature.set_signature_approved(True)
signature.set_signature_type('cla')
signature.set_signature_reference_id(user.get_user_id())
Ejemplo n.º 11
0
# Copyright The Linux Foundation and each contributor to CommunityBridge.
# SPDX-License-Identifier: MIT
"""
Convenience script to create companies.

Based on the database storage configuration found in config.py and config_instance.py.
"""

MANAGER_GITHUB_ID = 123

import sys
sys.path.append('../')

import cla
import uuid
from cla.utils import get_company_instance, get_user_instance

# User
manager = get_user_instance().get_user_by_github_id(MANAGER_GITHUB_ID)
cla.log.info('Creating new company with manager ID: %s', manager.get_user_id())
company = get_company_instance()
company.set_company_id(str(uuid.uuid4()))
company.set_company_external_id('company-external-id')
company.set_company_manager_id(manager.get_user_id())
company.set_company_name('Test Company')
company.set_company_whitelist([])
company.set_company_whitelist_patterns(['*@listed.org'])
company.save()
Ejemplo n.º 12
0
ENVELOPE_ID = sys.argv[2]
INSTALLATION_ID = 49309  # Assumed to be testing on the CLA-Test repository

import cla
from cla.utils import get_signature_instance, get_user_instance, get_signing_service, \
                      get_active_signature_metadata, delete_active_signature_metadata
from cla.models.docusign_models import update_repository_provider

cla.log.info('Completing the signature: %s' % SIGNATURE_ID)
signature = get_signature_instance()
signature.load(SIGNATURE_ID)
signature.set_signature_signed(True)
signature.save()
if signature.get_signature_reference_type() != 'user':
    cla.log.error('Trying to handle CCLA as a ICLA - not implemented yet')
    raise NotImplementedError()
user = get_user_instance()
user.load(signature.get_signature_reference_id())
# Remove the active signature metadata.
metadata = get_active_signature_metadata(user.get_user_id())
delete_active_signature_metadata(user.get_user_id())
# Send email with signed document.
cla.log.info('Sending signed document to user - see Mailhog')
docusign = get_signing_service()
docusign.send_signed_document(ENVELOPE_ID, user)
# Update the repository provider with this change.
cla.log.info('Updating GitHub PR...')
update_repository_provider(INSTALLATION_ID, metadata['repository_id'],
                           metadata['pull_request_id'])
cla.log.info('Done')
Ejemplo n.º 13
0
# Copyright The Linux Foundation and each contributor to CommunityBridge.
# SPDX-License-Identifier: MIT
"""
Convenience script to send a DocuSign document to the user's email address.

The user_id specified must exist in the database.
The docusign_document_id specified must exist in DocuSign.
"""

import sys

sys.path.append('../')

import cla
from cla.utils import get_signing_service, get_user_instance

docusign_document_id = 'dcd9a52b-bed8-4c6f-9a71-ce00252a4e5d'

user = get_user_instance().get_user_by_github_id(123)
cla.log.info('Sending DocuSign document (%s) to user\'s email: %s',
             docusign_document_id, user.get_user_email())
get_signing_service().send_signed_document(docusign_document_id, user)
cla.log.info('Done')
Ejemplo n.º 14
0
project.save()

## Create Github Org
GITHUB_ORGANIZATION_NAME = 'linuxfoundation'
GITHUB_INSTALLATION_ID = 72228  # NOT THE APP ID - find it in the webhook request JSON or URL when viewing installed apps.
cla.log.info('Creating GitHub Organization: %s' % GITHUB_ORGANIZATION_NAME)
github_org = get_github_organization_instance()
github_org.set_organization_name(GITHUB_ORGANIZATION_NAME)
github_org.set_organization_project_id(project.get_project_id())
# This will be different everytime the CLA app is installed.
github_org.set_organization_installation_id(GITHUB_INSTALLATION_ID)
github_org.save()

## User (For Company Management)
cla.log.info('Creating company manager user')
manager = get_user_instance()
manager.set_user_id(str(uuid.uuid4()))
manager.set_user_name('First User')
manager.set_user_email('*****@*****.**')
manager.set_user_email('*****@*****.**')
manager.set_user_github_id(123)
manager.save()

## Company
cla.log.info('Creating new company with manager ID: %s', manager.get_user_id())
company = get_company_instance()
company.set_company_id(str(uuid.uuid4()))
company.set_company_external_id('company-external-id')
company.set_company_manager_id(manager.get_user_id())
company.set_company_name('Test Company')
company.set_company_whitelist([])
Ejemplo n.º 15
0
# Copyright The Linux Foundation and each contributor to CommunityBridge.
# SPDX-License-Identifier: MIT

"""
Convenience script to create a user and agreement in the CLA system.
"""
import sys
sys.path.append('../')

import uuid
import cla
from cla.utils import get_user_instance

# Test User.
cla.log.info('Creating first user')
user1 = get_user_instance()
user1.set_user_id(str(uuid.uuid4()))
user1.set_user_name('First User')
user1.set_user_email('*****@*****.**')
user1.set_user_email('*****@*****.**')
user1.set_user_github_id(123)
user1.save()
cla.log.info('Creating second user')
user2 = get_user_instance()
user2.set_user_id(str(uuid.uuid4()))
user2.set_user_name('Second User')
user2.set_user_email('*****@*****.**')
user2.set_user_github_id(234)
user2.save()
cla.log.info('Creating third user')
user3 = get_user_instance()
Ejemplo n.º 16
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.º 17
0
def main(
    aws_region,
    rds_database,
    rds_host,
    rds_username,
    rds_password,
    rds_port,
    dry_run,
):
    """
    This script runs data migration from dynamodb to postgresql
    """

    if os.environ.get("STAGE") is None:
        logger.warning(
            "Please set the 'STAGE' environment varaible - typically one of: {dev, staging, prod}"
        )
        return

    stage = os.environ.get("STAGE")

    if dry_run:
        exit_cmd = input(
            "This is a dry run. "
            "You are running the script for the '{}' environment. "
            'Press <ENTER> to continue ("exit" to exit): '.format(stage))
    else:
        exit_cmd = input(
            "This is NOT a dry run. "
            "You are running the script for the '{}' environment. "
            'Press <ENTER> to continue ("exit" to exit): '.format(stage))
    if exit_cmd == "exit":
        return

    start_time = datetime.now()
    lock = threading.Lock()
    threads = []
    count = 0
    for _ in range(IMPORT_THREADS):
        connection = psycopg2.connect(
            database=rds_database,
            host=rds_host,
            user=rds_username,
            password=rds_password,
            port=rds_port,
        )
        cursor = connection.cursor()
        worker = Thread(target=import_to_pg,
                        args=(connection, cursor, tables_queues, dry_run))
        worker.start()
        threads.append(worker)

    # TODO: cla models for signature,company-invitations and user-permissions
    try:
        user = utils.get_user_instance()
        company = utils.get_company_instance()
        project = utils.get_project_instance()
        repository = utils.get_repository_instance()
        github_orgs = utils.get_github_organization_instance()
        gerrit = utils.get_gerrit_instance()
        #signature = utils.get_signature_instance()
        update_queue(user.all())
        update_queue(company.all())
        update_queue(project.all())
        #update_queue(signature.all())
        update_queue(repository.all())
        update_queue(gerrit.all())
        update_queue(github_orgs.all())
        # block until all tasks are done
        tables_queues.join()
    except Exception as err:
        logger.error(err)

    # End workers
    for _ in range(IMPORT_THREADS):
        tables_queues.put(None)
    for thread in threads:
        thread.join()

    duration = datetime.now() - start_time
    logger.info(
        "Data migration to the pg database run for a duration of {} ".format(
            duration))