Exemplo n.º 1
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]
Exemplo n.º 2
0
def remove_permission(auth_user: AuthUser, username: str, company_id: str):
    fn = 'controllers.company.remove_permission'
    if auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

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

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

    company.remove_company_acl(username)
    event_data = f'Removed user {username} from Company {company.get_company_name()} permissions list.'
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_company_id=company_id,
        event_type=EventType.RemoveCompanyPermission,
        contains_pii=True,
    )
    company.save()
Exemplo n.º 3
0
def delete_project(project_id, username=None):
    """
    Deletes an project based on ID.

    :TODO: Need to also delete the documents saved with the storage provider.

    :param project_id: The ID of the project.
    :type project_id: string
    """
    project = get_project_instance()
    try:
        project.load(str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}
    project_acl_verify(username, project)
    # Create audit trail
    event_data = 'Project-{} deleted'.format(project.get_project_name())
    Event.create_event(
        event_type=EventType.DeleteProject,
        event_project_id=project_id,
        event_data=event_data,
        contains_pii=False,
    )
    project.delete()

    return {'success': True}
Exemplo n.º 4
0
def remove_permission(auth_user: AuthUser, username: str,
                      project_sfdc_id: str):
    if auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

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

    user_permission = UserPermissions()
    try:
        user_permission.load(username)
    except Exception as err:
        print('Unable to update user permission: {}'.format(err))
        return {'error': err}

    event_data = 'User {} permission removed to project {}'.format(
        username, project_sfdc_id)

    user_permission.remove_project(project_sfdc_id)
    user_permission.save()
    Event.create_event(
        event_type=EventType.RemovePermission,
        event_data=event_data,
        event_summary=event_data,
        event_project_id=project_sfdc_id,
        contains_pii=True,
    )
Exemplo n.º 5
0
def delete_company(company_id: str, username: str = None):
    """
    Deletes an company based on ID.

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

    company_acl_verify(username, company)
    company.delete()

    event_data = f'The company {company.get_company_name()} with company_id {company.get_company_id()} was deleted.'
    event_summary = f'The company {company.get_company_name()} was deleted.'
    Event.create_event(
        event_data=event_data,
        event_summary=event_summary,
        event_type=EventType.DeleteCompany,
        event_company_id=company_id,
        contains_pii=False,
    )
    return {'success': True}
Exemplo n.º 6
0
def add_permission(auth_user: AuthUser,
                   username: str,
                   company_id: str,
                   ignore_auth_user=False):
    if not ignore_auth_user and auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

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

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

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

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

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

    company.remove_company_acl(username)
    event_data = 'company ({}) removed for ({}) by {}'.format(
        company_id, username, auth_user.username)
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_company_id=company_id,
        event_type=EventType.RemoveCompanyPermission,
        contains_pii=True,
    )
    company.save()
Exemplo n.º 8
0
def delete_company(company_id, username=None):
    """
    Deletes an company based on ID.

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

    company_acl_verify(username, company)

    company.delete()

    event_data = f'Company- {company.get_company_name()} deleted'
    Event.create_event(
        event_data=event_data,
        event_type=EventType.DeleteCompany,
        event_company_id=company_id,
        contains_pii=False,
    )
    return {'success': True}
Exemplo n.º 9
0
def add_permission(auth_user: AuthUser, username: str, project_sfdc_id: str):
    if auth_user.username not in admin_list:
        return {'error': 'unauthorized'}

    cla.log.info('project ({}) added for user ({}) by {}'.format(
        project_sfdc_id, username, auth_user.username))
    user_permission = UserPermissions()
    try:
        user_permission.load(username)
    except Exception as err:
        print('user not found. creating new user: {}'.format(err))
        # create new user
        user_permission = UserPermissions(username=username)

    user_permission.add_project(project_sfdc_id)
    user_permission.save()

    event_data = 'User {} given permissions to project {}'.format(
        username, project_sfdc_id)
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_project_id=project_sfdc_id,
        event_type=EventType.AddPermission,
        contains_pii=True,
    )
Exemplo n.º 10
0
def add_cla_manager(auth_user, signature_id, lfid):
    """
    Adds the LFID to the signature ACL and returns a new list of CLA Managers.

    :param username: username of the user
    :type username: string
    :param signature_id: The ID of the project
    :type signature_id: UUID
    :param lfid: the lfid (manager username) to be added to the project acl
    :type lfid: string
    """

    # Find project
    signature = Signature()
    try:
        signature.load(str(signature_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    # Get Signature ACL
    signature_acl = signature.get_signature_acl()

    if auth_user.username not in signature_acl:
        return {'errors': {'user_id': 'You are not authorized to see the managers.'}}

    company.add_permission(auth_user, lfid, signature.get_signature_reference_id(), ignore_auth_user=True)
    # Get Company and Project instances
    try:
        project = get_project(signature.get_signature_project_id())
    except DoesNotExist as err:
        return err
    try:
        company_instance = get_company(signature.get_signature_reference_id())
    except DoesNotExist as err:
        return err

    # get cla managers for email content
    managers = get_cla_managers(auth_user.username, signature_id)

    # Add lfid to acl
    signature.add_signature_acl(lfid)
    signature.save()

    # send email to newly added CLA manager
    try:
        subject, body, recipients = add_cla_manager_email_content(lfid, project, company_instance, managers)
        get_email_service().send(subject, body, recipients)
    except Exception as err:
        return {'errors': {'Failed to send email for lfid: %s , %s ' % (lfid, err)}}

    event_data = f'{lfid} added as cla manager to Signature ACL for {signature.get_signature_id()}'
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_type=EventType.AddCLAManager,
        contains_pii=True,
    )

    return get_managers_dict(signature_acl)
Exemplo n.º 11
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_summary=event_data,
        event_project_id=project_id,
        contains_pii=True,
    )

    return managers_dict
Exemplo n.º 12
0
def create_company(auth_user: AuthUser,
                   company_name: str = None,
                   company_manager_id=None,
                   company_manager_user_name=None,
                   company_manager_user_email=None,
                   user_id=None,
                   response=None):
    """
    Creates an company and returns the newly created company in dict format.

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

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

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

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

    return {"status_code": HTTP_200, "data": company.to_dict()}
Exemplo n.º 13
0
def handle_installation_repositories_removed_event(action: str, body: dict):
    func_name = 'github.activity.handle_installation_repositories_removed_event'
    # Who triggered the event
    user_login = body['sender']['login']
    cla.log.debug(
        f'{func_name} - processing github [installation_repositories] '
        f'activity {action} callback created by GitHub user {user_login}.')
    repository_removed = body['repositories_removed']
    repositories = []
    for repo in repository_removed:
        repository_external_id = repo['id']
        ghrepo = Repository().get_repository_by_external_id(
            repository_external_id, 'github')
        if ghrepo is not None:
            repositories.append(ghrepo)

    # Notify the Project Managers that the following list of repositories were removed
    notify_project_managers(repositories)

    # The following list of repositories were deleted/removed from GitHub - we need to remove
    # the repo entry from our repos table
    for repo in repositories:

        project_model = get_project_instance()
        try:
            project_model.load(project_id=repo.get_repository_project_id())
        except DoesNotExist as err:
            cla.log.warning(
                f'{func_name} - unable to load project (cla_group) by '
                f'project_id: {repo.get_repository_project_id()}, error: {err}'
            )

        msg = (
            f'Disabling repository {repo.get_repository_name()} '
            f'from GitHub organization : {repo.get_repository_organization_name()} '
            f'with URL: {repo.get_repository_url()} '
            'from the CLA configuration.')
        cla.log.debug(msg)
        # Disable the repo and add a note
        repo.set_enabled(False)
        repo.add_note(f'{datetime.now()}  - Disabling repository due to '
                      'GitHub installation_repositories delete event '
                      f'for CLA Group {project_model.get_project_name()}')
        repo.save()

        # Log the event
        Event.create_event(
            event_type=EventType.RepositoryDisable,
            event_project_id=repo.get_repository_project_id(),
            event_project_name=project_model.get_project_name(),
            event_company_id=None,
            event_data=msg,
            event_summary=msg,
            event_user_id=user_login,
            contains_pii=False,
        )
Exemplo n.º 14
0
def create_company(auth_user,
                   company_name=None,
                   company_manager_id=None,
                   company_manager_user_name=None,
                   company_manager_user_email=None,
                   user_id=None,
                   response=None):
    """
    Creates an company and returns the newly created company in dict format.

    :param company_name: The company name.
    :type company_name: string
    :param company_manager_id: The ID of the company manager user.
    :type company_manager_id: string
    :param company_manager_user_name: The user name of the company manager user.
    :type company_manager_user_name: string
    :param company_manager_user_email: The user email of the company manager user.
    :type company_manager_user_email: string
    :return: dict representation of the company object.
    :rtype: dict
    """

    manager = cla.controllers.user.get_or_create_user(auth_user)

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

    company = Company()
    company.set_company_id(str(uuid.uuid4()))
    company.set_company_name(company_name)
    company.set_company_manager_id(manager.get_user_id())
    company.set_company_acl(manager.get_lf_username())

    company.save()

    # Create audit trail for company
    event_data = 'Company-{} created'.format(company.get_company_name())
    Event.create_event(
        event_type=EventType.CreateCompany,
        event_company_id=company.get_company_id(),
        event_data=event_data,
        event_user_id=user_id,
        contains_pii=False,
    )

    return {"status_code": HTTP_200, "data": company.to_dict()}
Exemplo n.º 15
0
def update_project(project_id,
                   project_name=None,
                   project_icla_enabled=None,
                   project_ccla_enabled=None,
                   project_ccla_requires_icla_signature=None,
                   username=None):
    """
    Updates a project and returns the newly updated project in dict format.
    A value of None means the field should not be updated.

    :param project_id: ID of the project to update.
    :type project_id: string
    :param project_name: New project name.
    :type project_name: string | None
    :param project_icla_enabled: Whether or not the project supports ICLAs.
    :type project_icla_enabled: bool | None
    :param project_ccla_enabled: Whether or not the project supports CCLAs.
    :type project_ccla_enabled: bool | None
    :param project_ccla_requires_icla_signature: Whether or not the project requires ICLA with CCLA.
    :type project_ccla_requires_icla_signature: bool | None
    :return: dict representation of the project object.
    :rtype: dict
    """
    project = get_project_instance()
    try:
        project.load(str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}
    project_acl_verify(username, project)
    updated_string = " "
    if project_name is not None:
        project.set_project_name(project_name)
        updated_string += f"project_name changed to {project_name} \n"
    if project_icla_enabled is not None:
        project.set_project_icla_enabled(project_icla_enabled)
        updated_string += f"project_icla_enabled changed to {project_icla_enabled} \n"
    if project_ccla_enabled is not None:
        project.set_project_ccla_enabled(project_ccla_enabled)
        updated_string += f"project_ccla_enabled changed to {project_ccla_enabled} \n"
    if project_ccla_requires_icla_signature is not None:
        project.set_project_ccla_requires_icla_signature(
            project_ccla_requires_icla_signature)
        updated_string += f"project_ccla_requires_icla_signature changed to {project_ccla_requires_icla_signature} \n"
    project.save()

    # Create audit trail
    event_data = f'Project- {project_id} Updates: ' + updated_string
    Event.create_event(
        event_type=EventType.UpdateProject,
        event_project_id=project.get_project_id(),
        event_data=event_data,
        event_summary=event_data,
        contains_pii=False,
    )
    return project.to_dict()
Exemplo n.º 16
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]

    event_data = '{} added {} to project {}'.format(username, lfid,
                                                    project.get_project_name())
    Event.create_event(
        event_type=EventType.AddProjectManager,
        event_data=event_data,
        event_summary=event_data,
        event_project_id=project_id,
        contains_pii=True,
    )

    return managers_dict
Exemplo n.º 17
0
def remove_cla_manager(username, signature_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
    signature = Signature()
    try:
        signature.load(str(signature_id))
    except DoesNotExist as err:
        return {'errors': {'signature_id': str(err)}}

    # Validate user is the manager of the project
    signature_acl = signature.get_signature_acl()
    if username not in signature_acl:
        return {
            'errors': {
                'user': "******"
            }
        }

    # Avoid to have an empty acl
    if len(signature_acl) == 1 and username == lfid:
        return {
            'errors': {
                'user':
                "******"
            }
        }

    # Remove LFID from the acl
    signature.remove_signature_acl(lfid)
    signature.save()

    event_data = f'User with lfid {lfid} removed from project ACL with signature {signature.get_signature_id()}'

    Event.create_event(
        event_data=event_data,
        event_type=EventType.RemoveCLAManager,
        contains_pii=True,
    )

    # Return modified managers
    return get_managers_dict(signature_acl)
Exemplo n.º 18
0
def update_company(
        company_id: str,  # pylint: disable=too-many-arguments
        company_name: str = None,
        company_manager_id: str = None,
        username: str = None):
    """
    Updates an company and returns the newly updated company in dict format.
    A value of None means the field should not be updated.

    :param company_id: ID of the company to update.
    :type company_id: str
    :param company_name: New company name.
    :type company_name: string | None
    :param company_manager_id: The ID of the company manager user.
    :type company_manager_id: str
    :param username: The username of the existing company manager user who performs the company update.
    :type username: str
    :return: dict representation of the company object.
    :rtype: dict
    """
    company = Company()
    try:
        company.load(str(company_id))
    except DoesNotExist as err:
        return {'errors': {'company_id': str(err)}}

    company_acl_verify(username, company)
    update_str = ""

    if company_name is not None:
        company.set_company_name(company_name)
        update_str += f"The company name was updated to {company_name}. "
    if company_manager_id is not None:
        val = hug.types.uuid(company_manager_id)
        company.set_company_manager_id(str(val))
        update_str += f"The company company manager id was updated to {val}"

    company.save()

    # Audit update event
    event_data = update_str
    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_type=EventType.UpdateCompany,
        event_company_id=company_id,
        contains_pii=False,
    )
    return company.to_dict()
Exemplo n.º 19
0
def delete_project_document(project_id,
                            document_type,
                            major_version,
                            minor_version,
                            username=None):
    """
    Deletes the document from the specified project.

    :param project_id: The ID of the project in question.
    :type project_id: string
    :param document_type: The type of document to remove (individual or corporate).
    :type document_type: string
    :param major_version: The document major version number to remove.
    :type major_version: integer
    :param minor_version: The document minor version number to remove.
    :type minor_version: integer
    """
    project = get_project_instance()
    try:
        project.load(str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}
    project_acl_verify(username, project)
    document = cla.utils.get_project_document(project, document_type,
                                              major_version, minor_version)
    if document is None:
        return {'errors': {'document': 'Document version not found'}}
    if document_type == 'individual':
        project.remove_project_individual_document(document)
    else:
        project.remove_project_corporate_document(document)
    project.save()

    event_data = (
        f'Project {project.get_project_name()} with {document_type} :' +
        f'document type , minor version : {minor_version}, major version : {major_version}  deleted'
    )

    Event.create_event(
        event_data=event_data,
        event_summary=event_data,
        event_project_id=project_id,
        event_type=EventType.DeleteProjectDocument,
        contains_pii=False,
    )
    return {'success': True}
Exemplo n.º 20
0
def add_cla_manager(auth_user, signature_id, lfid):
    """
    Adds the LFID to the signature ACL and returns a new list of CLA Managers.

    :param username: username of the user
    :type username: string
    :param signature_id: The ID of the project
    :type signature_id: UUID
    :param lfid: the lfid (manager username) to be added to the project acl
    :type lfid: string
    """
    # Find project
    signature = Signature()
    try:
        signature.load(str(signature_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}

    # Get Signature ACL
    signature_acl = signature.get_signature_acl()

    if auth_user.username not in signature_acl:
        return {
            'errors': {
                'user_id': 'You are not authorized to see the managers.'
            }
        }

    company.add_permission(auth_user,
                           lfid,
                           signature.get_signature_reference_id(),
                           ignore_auth_user=True)

    # Add lfid to acl
    signature.add_signature_acl(lfid)
    signature.save()

    event_data = f'{lfid} added as cla manager to Signature ACL for {signature.get_signature_id()}'
    Event.create_event(
        event_data=event_data,
        event_type=EventType.AddCLAManager,
        contains_pii=True,
    )

    return get_managers_dict(signature_acl)
Exemplo 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,
    )
Exemplo n.º 22
0
def test_event_project_id(project):
    """ Test event with event_project_id """
    Event.save = Mock()
    Project.load = Mock()
    event_data = 'project id loaded'
    response = Event.create_event(
        event_data=event_data,
        event_type=event_types.EventType.DeleteProject,
        event_project_id=project.get_project_id()
    )
    assert 'data' in response
Exemplo n.º 23
0
def test_event_user_id(user_instance):
    """ Test event_user_id """
    Event.save = Mock()
    User.load = Mock()
    event_data = "test user id"
    response = Event.create_event(
        event_type=event_types.EventType.CreateProject,
        event_data=event_data,
        event_user_id=user_instance.get_user_id()
    )
    assert 'data' in response
Exemplo n.º 24
0
def create_project(project_external_id, project_name, project_icla_enabled,
                   project_ccla_enabled, project_ccla_requires_icla_signature,
                   project_acl_username):
    """
    Creates a project and returns the newly created project in dict format.

    :param project_external_id: The project's external ID.
    :type project_external_id: string
    :param project_name: The project's name.
    :type project_name: string
    :param project_icla_enabled: Whether or not the project supports ICLAs.
    :type project_icla_enabled: bool
    :param project_ccla_enabled: Whether or not the project supports CCLAs.
    :type project_ccla_enabled: bool
    :param project_ccla_requires_icla_signature: Whether or not the project requires ICLA with CCLA.
    :type project_ccla_requires_icla_signature: bool
    :return: dict representation of the project object.
    :rtype: dict
    """
    project = get_project_instance()
    project.set_project_id(str(uuid.uuid4()))
    project.set_project_external_id(str(project_external_id))
    project.set_project_name(project_name)
    project.set_project_icla_enabled(project_icla_enabled)
    project.set_project_ccla_enabled(project_ccla_enabled)
    project.set_project_ccla_requires_icla_signature(
        project_ccla_requires_icla_signature)
    project.set_project_acl(project_acl_username)
    project.save()

    # Create audit trail
    event_data = 'Project-{} created'.format(project_name)
    Event.create_event(
        event_type=EventType.CreateProject,
        event_project_id=project.get_project_id(),
        event_data=event_data,
        event_summary=event_data,
        contains_pii=False,
    )

    return project.to_dict()
Exemplo n.º 25
0
def test_event_company_id(company):
    """ Test creation of event instance """
    #Case for creating Company
    Event.save = Mock()
    Company.load = Mock()
    event_data = 'test company created'
    response = Event.create_event(
        event_type=event_types.EventType.DeleteCompany,
        event_data=event_data,
        event_company_id=company.get_company_id()
    )
    assert 'data' in response
Exemplo n.º 26
0
def delete_signature(signature_id):
    """
    Deletes an signature based on UUID.

    :param signature_id: The UUID of the signature.
    :type signature_id: UUID
    """
    signature = Signature()
    try:  # Try to load the signature to delete.
        signature.load(str(signature_id))
    except DoesNotExist as err:
        # Should we bother sending back an error?
        return {'errors': {'signature_id': str(err)}}
    signature.delete()
    event_data = f'Deleted signature {signature_id}'
    Event.create_event(
        event_data=event_data,
        event_type=EventType.DeleteSignature,
        contains_pii=False,
    )

    return {'success': True}
Exemplo n.º 27
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,
    )
Exemplo n.º 28
0
def post_project_document_template(project_id,
                                   document_type,
                                   document_name,
                                   document_preamble,
                                   document_legal_entity_name,
                                   template_name,
                                   new_major_version=None,
                                   username=None):
    """
    Will create a new document for the project specified, using the existing template.

    :param project_id: The ID of the project to add this document to.
    :type project_id: string
    :param document_type: The type of document (individual or corporate).
    :type document_type: string
    :param document_name: The name of this new document.
    :type document_name: string
    :param document_preamble: The document preamble.
    :type document_preamble: string
    :param document_legal_entity_name: The legal entity name on the document.
    :type document_legal_entity_name: string
    :param template_name: The name of the template object to use.
    :type template_name: string
    :param new_major_version: Whether or not to bump up the major version.
    :type new_major_version: boolean
    """
    project = get_project_instance()
    try:
        project.load(str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}
    project_acl_verify(username, project)
    document = get_document_instance()
    document.set_document_name(document_name)
    document.set_document_preamble(document_preamble)
    document.set_document_legal_entity_name(document_legal_entity_name)
    if document_type == 'individual':
        major, minor = cla.utils.get_last_version(project.get_project_individual_documents())
        if new_major_version:
            document.set_document_major_version(major + 1)
            document.set_document_minor_version(0)
        else:
            document.set_document_minor_version(minor + 1)
        project.add_project_individual_document(document)
    else:
        major, minor = cla.utils.get_last_version(project.get_project_corporate_documents())
        if new_major_version:
            document.set_document_major_version(major + 1)
            document.set_document_minor_version(0)
        else:
            document.set_document_minor_version(minor + 1)
        project.add_project_corporate_document(document)
    # Need to take the template, inject the preamble and legal entity name, and add the tabs.
    tmplt = getattr(cla.resources.contract_templates, template_name)
    template = tmplt(document_type=document_type.capitalize(),
                     major_version=document.get_document_major_version(),
                     minor_version=document.get_document_minor_version())
    content = template.get_html_contract(document_legal_entity_name, document_preamble)
    pdf_generator = get_pdf_service()
    pdf_content = pdf_generator.generate(content)
    document.set_document_content_type('storage+pdf')
    document.set_document_content(pdf_content, b64_encoded=False)
    document.set_raw_document_tabs(template.get_tabs())
    project.save()

    # Create audit trail
    event_data = 'Project Document created for project {} created with template {}'.format(
        project.get_project_name(), template_name)
    Event.create_event(
        event_type=EventType.CreateProjectDocumentTemplate,
        event_project_id=project.get_project_id(),
        event_data=event_data,
        contains_pii=False,
    )
    return project.to_dict()
Exemplo n.º 29
0
def post_project_document(project_id,
                          document_type,
                          document_name,
                          document_content_type,
                          document_content,
                          document_preamble,
                          document_legal_entity_name,
                          new_major_version=None,
                          username=None):
    """
    Will create a new document for the project specified.

    :param project_id: The ID of the project to add this document to.
    :type project_id: string
    :param document_type: The type of document (individual or corporate).
    :type document_type: string
    :param document_name: The name of this new document.
    :type document_name: string
    :param document_content_type: The content type of this document ('pdf', 'url+pdf',
        'storage+pdf', etc).
    :type document_content_type: string
    :param document_content: The content of the document (or URL to content if content type
        starts with 'url+'.
    :type document_content: string or binary data
    :param document_preamble: The document preamble.
    :type document_preamble: string
    :param document_legal_entity_name: The legal entity name on the document.
    :type document_legal_entity_name: string
    :param new_major_version: Whether or not to bump up the major version.
    :type new_major_version: boolean
    """
    project = get_project_instance()
    try:
        project.load(str(project_id))
    except DoesNotExist as err:
        return {'errors': {'project_id': str(err)}}
    project_acl_verify(username, project)
    document = get_document_instance()
    document.set_document_name(document_name)
    document.set_document_content_type(document_content_type)
    document.set_document_content(document_content)
    document.set_document_preamble(document_preamble)
    document.set_document_legal_entity_name(document_legal_entity_name)
    if document_type == 'individual':
        major, minor = cla.utils.get_last_version(project.get_project_individual_documents())
        if new_major_version:
            document.set_document_major_version(major + 1)
            document.set_document_minor_version(0)
        else:
            if major == 0:
                major = 1
            document.set_document_major_version(major)
            document.set_document_minor_version(minor + 1)
        project.add_project_individual_document(document)
    else:
        major, minor = cla.utils.get_last_version(project.get_project_corporate_documents())
        if new_major_version:
            document.set_document_major_version(major + 1)
            document.set_document_minor_version(0)
        else:
            if major == 0:
                major = 1
            document.set_document_major_version(major)
            document.set_document_minor_version(minor + 1)
        project.add_project_corporate_document(document)
    project.save()

    # Create audit trail
    event_data = 'Created new document for Project-{} '.format(project.get_project_name())
    Event.create_event(
        event_type=EventType.CreateProjectDocument,
        event_project_id=project.get_project_id(),
        event_data=event_data,
        contains_pii=False,
    )
    return project.to_dict()
Exemplo n.º 30
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,
    )