Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update gitignore #4484

Merged
merged 13 commits into from
Dec 4, 2024
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,7 @@ dist/*
api-postman/*

cla-backend/run-python-test-example-*.py

# LG
out
*.secret
130 changes: 130 additions & 0 deletions aws_env.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Setting up AWS environment

You need to have MFA enabled for your AWS user, your `~/.aws/config` shoudl look like this:
```
[profile lfproduct-dev]
role_arn = arn:aws:iam::395594542180:role/product-contractors-role
source_profile = lfproduct
region = us-east-1
output = json

[profile lfproduct-test]
role_arn = arn:aws:iam::726224182707:role/product-contractors-role
source_profile = lfproduct
region = us-east-1
output = json

[profile lfproduct-staging]
role_arn = arn:aws:iam::844390194980:role/product-contractors-role
source_profile = lfproduct
region = us-east-1
output = json

[profile lfproduct-prod]
role_arn = arn:aws:iam::716487311010:role/product-contractors-role
source_profile = lfproduct
region = us-east-1
output = json

[default]
region = us-east-1
output = json
```

It defines 4 profiles to use: `dev`, `staging`, `test` and `prod`.

You will be using one of them.


Your `~/.aws/credentials` file shoudl initially look like this (replace `redacted`):
```
[lfproduct-long-term]
aws_secret_access_key = [access_key_redacted]
aws_access_key_id = [key_id_redacted]
aws_mfa_device = arn:aws:iam::[arn_number_redacted]:mfa/[your_aws_user_redacted]

[default]
aws_access_key_id = [key_id_redacted]
aws_secret_access_key = [access_key_redacted]
```

Now every 36 hours or less you need to refresh your MFA key by calling: `aws-mfa --force --duration 129600 --profile lfproduct`.

When called it adds or replaces the following section (`[lfproduct]` which is used as a source profile for `dev`, `test`, `staging` or `prod` in aws config) in `~/.aws/credentials`:
```
[lfproduct]
assumed_role = False
aws_access_key_id = [key_id_redacted]
aws_secret_access_key = [secret_access_key_redacted]
aws_session_token = [session_token_redacted]
aws_security_token = [session_token_redacted]
expiration = 2024-11-28 16:54:59 [now + 36 hours]

```


Once you have all of this, you must set a correct set of environment variables to run either `python` or `golang` backends.

To do so you need to get credentials for a specific profile `lfproduct-`: `dev`, `test`, `staging`, `prod`. To see full one-time set of credentials you can call:
- for `dev`: `` aws sts assume-role --role-arn arn:aws:iam::395594542180:role/product-contractors-role --profile lfproduct --role-session-name lfproduct-dev-session ``.
- for `prod`: `` aws sts assume-role --role-arn arn:aws:iam::716487311010:role/product-contractors-role --profile lfproduct --role-session-name lfproduct-prod-session ``.

Note - just replace the iam::[number] depending on environment type (`[stage]`) and update `lfproduct-[stage]-name`.

You can set up a script like `setenv.sh` which will set all required variables, example for `dev`:
```
#!/bin/bash

rm -rf /tmp/aws
cp -R /root/.aws /tmp/.aws

data="$(aws sts assume-role --role-arn arn:aws:iam::395594542180:role/product-contractors-role --profile lfproduct --role-session-name lfproduct-dev-session)"
export AWS_ACCESS_KEY_ID="$(echo "${data}" | jq -r '.Credentials.AccessKeyId')"
export AWS_SECRET_ACCESS_KEY="$(echo "${data}" | jq -r '.Credentials.SecretAccessKey')"
export AWS_SESSION_TOKEN="$(echo "${data}" | jq -r '.Credentials.SessionToken')"
export AWS_SECURITY_TOKEN="$(echo "${data}" | jq -r '.Credentials.SessionToken')"

export AWS_SDK_LOAD_CONFIG=true
export AWS_PROFILE='lfproduct-dev'
export AWS_REGION='us-east-1'
export AWS_DEFAULT_REGION='us-east-1'
export DYNAMODB_AWS_REGION='us-east-1'
export REGION='us-east-1'

export PRODUCT_DOMAIN='dev.lfcla.com'
export ROOT_DOMAIN='lfcla.dev.platform.linuxfoundation.org'
export PORT='5000'
export STAGE='dev'
# export STAGE='local'
export GH_ORG_VALIDATION=false
export DISABLE_LOCAL_PERMISSION_CHECKS=true
export COMPANY_USER_VALIDATION=false
export CLA_SIGNATURE_FILES_BUCKET=cla-signature-files-dev
```

Call it via `` . ./setenv.sh `` or `` source setenv.sh `` to execute in the current shell.

You can reset environment variables by exiting the shell session or calling the following `unsetenv.sh` in the current shell via: `` . ./unsetenv.sh `` or `` source unsetenv.sh ``:
```
#!/bin/bash
rm -rf /tmp/.aws
unset AWS_PROFILE
unset AWS_REGION
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset PRODUCT_DOMAIN
unset ROOT_DOMAIN
unset PORT
unset STAGE
unset AWS_SESSION_TOKEN
unset AWS_SECURITY_TOKEN
unset GH_ORG_VALIDATION
unset DISABLE_LOCAL_PERMISSION_CHECKS
unset COMPANY_USER_VALIDATION
unset CLA_SIGNATURE_FILES_BUCKET
unset DYNAMODB_AWS_REGION
unset REGION
unset AWS_ROLE_ARN
unset AWS_TOKEN_SERIAL
unset AWS_SDK_LOAD_CONFIG
```
47 changes: 45 additions & 2 deletions dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,46 @@ locally and simply point to the DEV environment. The `STAGE` environment
variable controls where we point. Make sure you export/provide/setup the AWS
properties in order to connect.


When running on Linux it looks like `.venv` sets $HOME to /tmp, and then python backend is looking for the AWS config file in `~/.aws/config`
This means it ends up in `/tmp/.aws/config`. You can use the following scritp to activate your environment (`setenv.secret`) via: `source setenv.secret`:
```
#!/bin/bash
rm -rf /tmp/aws
cp -R ~/.aws /tmp/.aws
export AWS_SDK_LOAD_CONFIG=1
export AWS_PROFILE='lfproduct-dev'
export AWS_REGION='us-east-1'
data="$(aws sts assume-role --role-arn arn:aws:iam::395594542180:role/product-contractors-role --profile lfproduct --role-session-name lfproduct-dev-session)"
export AWS_ACCESS_KEY_ID="$(echo "${data}" | jq -r '.Credentials.AccessKeyId')"
export AWS_SECRET_ACCESS_KEY="$(echo "${data}" | jq -r '.Credentials.SecretAccessKey')"
export AWS_SESSION_TOKEN="$(echo "${data}" | jq -r '.Credentials.SessionToken')"
export AWS_SECURITY_TOKEN="$(echo "${data}" | jq -r '.Credentials.SessionToken')"
export PRODUCT_DOMAIN='dev.lfcla.com'
export ROOT_DOMAIN='lfcla.dev.platform.linuxfoundation.org'
export PORT='5000'
export STAGE='dev'
```

And the following one to unset the environment:
```
#!/bin/bash
rm -rf /tmp/.aws
unset AWS_SDK_LOAD_CONFIG=1
unset AWS_PROFILE
unset AWS_REGION
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
unset AWS_SECURITY_TOKEN
unset PRODUCT_DOMAIN
unset ROOT_DOMAIN
unset PORT
unset STAGE
```

Please refer to [aws_env.md](aws_env.md) for more details.

## Run the Python Backend

```bash
Expand Down Expand Up @@ -162,6 +202,9 @@ open http://localhost:5000/v2/health
open http://localhost:5000/v2/user/<some_uuid_from_users_table>
```

To expose service running on the localhost to the outside world use: `` ./utils/ngrok.sh ``.
And then tets via: `` API_URL='https://[redacted].ngrok-free.app' ./scripts/health.sh `` from another host (anywhere in the world).

## Building and Running the Go Backend

Current Endpoints:
Expand Down Expand Up @@ -331,9 +374,9 @@ First build and setup the environment. Then simply run it:

```bash
# Mac
./cla-mac
./bin/cla-mac
# or linux
./cla
./bin/cla
```

You should see the typical diagnostic details on startup indicating that it
Expand Down
34 changes: 34 additions & 0 deletions setenv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

rm -rf /tmp/aws
cp -R /root/.aws /tmp/.aws

dev_arn="$(cat ./product-contractors-role.dev.secret)"
data="$(aws sts assume-role --role-arn ${dev_arn} --profile lfproduct --role-session-name lfproduct-dev-session)"
export AWS_ACCESS_KEY_ID="$(echo "${data}" | jq -r '.Credentials.AccessKeyId')"
export AWS_SECRET_ACCESS_KEY="$(echo "${data}" | jq -r '.Credentials.SecretAccessKey')"
export AWS_SESSION_TOKEN="$(echo "${data}" | jq -r '.Credentials.SessionToken')"
export AWS_SECURITY_TOKEN="$(echo "${data}" | jq -r '.Credentials.SessionToken')"
export GITHUB_OAUTH_TOKEN="$(cat /etc/github/oauth)"
export DOCUSIGN_INTEGRATOR_KEY="$(cat ./DOCUSIGN_INTEGRATOR_KEY.secret)"
export DOCUSIGN_USER_ID="$(cat ./DOCUSIGN_USER_ID.secret)"
export DOCUSIGN_AUTH_SERVER="$(cat ./DOCUSIGN_AUTH_SERVER.secret)"
export DOCUSIGN_ROOT_URL="$(cat ./DOCUSIGN_ROOT_URL.secret)"
export DOCUSIGN_ACCOUNT_ID="$(cat ./DOCUSIGN_ACCOUNT_ID.secret)"

export AWS_SDK_LOAD_CONFIG=true
export AWS_PROFILE='lfproduct-dev'
export AWS_REGION='us-east-1'
export AWS_DEFAULT_REGION='us-east-1'
export DYNAMODB_AWS_REGION='us-east-1'
export REGION='us-east-1'

export PRODUCT_DOMAIN='dev.lfcla.com'
export ROOT_DOMAIN='lfcla.dev.platform.linuxfoundation.org'
export PORT='5000'
export STAGE='dev'
# export STAGE='local'
export GH_ORG_VALIDATION=false
export DISABLE_LOCAL_PERMISSION_CHECKS=true
export COMPANY_USER_VALIDATION=false
export CLA_SIGNATURE_FILES_BUCKET=cla-signature-files-dev
62 changes: 62 additions & 0 deletions sign-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
EasyCLA Sign Flow: Sequence Overview

1. *User Creates a Pull Request (PR)*
◦ A contributor initiates a PR in the repository hosted on GitHub, Gerrit, or GitLab.
2. *Repository Triggers Activity Endpoint*
• The repository platform sends a request to EasyCLA’s Python endpoint:
◦ v2/repository-provider/{provider}/activity
3. *EasyCLA Checks User Authorization*
◦ EasyCLA internally verifies if the users involved in the PR are authorized to contribute to the repository.
4. *Update Repository with User Status*
◦ EasyCLA communicates back to the repository provider, updating the status of each user as either *signed* or *not signed*.
5. *User Initiates Sign Process*
◦ If a user is marked as *not signed*, they are prompted to begin the signing process and are redirected to the EasyCLA Contributor Console.
6. *Contributor Chooses Sign Type*
• Upon reaching the Contributor Console, the user selects one of two options:
▪︎ *Individual Contributor*
◦ *Corporate Contributor*
7. *Individual Contributor Flow*
• *a. Initiate Individual Signature Request*
• The system invokes the Go-based endpoint:
▪︎ v4/request-individual-signature
◦ This action creates a new signature record with `signed = false` and initiates the signing process.
• *a1. Redirect to DocuSign*
◦ The API handles the integration with DocuSign, preparing a callback and redirect URL, and redirects the user to DocuSign for signing.
• *a2. Completion of Signing*
• Once the user completes the signing on DocuSign, a callback is triggered to:
▪︎ v4/signed/individual/{installation_id}/{github_repository_id}/{change_request_id}
◦ This endpoint updates the signature record’s `signed` flag to `true`, completing the process.
8. *Corporate Contributor Flow*
• *b. Initiate Corporate Signature Process*
9. *Redirect to Company Search*
▪︎ The user is redirected to a company search interface within the Contributor Console.
10. *Search for Company*
• Upon selecting a company, the system calls the Go-based search endpoint:
• v3/organization/search?companyName=Info&amp;include-signing-entity-name=false
▪︎ This retrieves the relevant company information.
11. *Check and Prepare Employee Signature*
• The system invokes the Python endpoint:
• v2/check-prepare-employee-signature
• This checks whether the company follows a Corporate CLA (CCLA) or an Entity CLA (ECLA) flow.
• *i. If Company Has a CCLA:*
◦ The system verifies if the user is authorized.
◦ If *not authorized*, it prompts the user to contact the existing CLA manager for authorization.
• The Go-based endpoint sends a notification to CLA managers:
◦ v4/notify-cla-managers
• An email is sent to the CLA managers, and the process ends.
• *ii. If Company Does Not Have a CCLA:*
◦ The system checks if the user is a CLA manager.
• *A. User is a CLA Manager:*
• Assigns CLA manager designee permissions via:
◦ v4/company/{companySFID}/user/{userLFID}/claGroupID/{claGroupID}/is-cla-manager-designee
• Verifies the assigned role:
◦ v4/company/{companySFID}/user/{userLFID}/claGroupID/{claGroupID}/is-cla-manager-designee
• If the role is confirmed, it calls the endpoint to request a corporate signature:
◦ v4/request-corporate-signature
◦ This creates the signature record, completing the process.
• *B. User is Not a CLA Manager:*
• Fetches company administrators using:
◦ v4/company/{companySFID}/admin
• Sends an invitation to become a company admin via:
◦ /user/{userID}/invite-company-admin
◦ An email is sent to the user to invite them as a company admin, concluding the process.
27 changes: 27 additions & 0 deletions unsetenv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash
rm -rf /tmp/.aws
unset AWS_PROFILE
unset AWS_REGION
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset PRODUCT_DOMAIN
unset ROOT_DOMAIN
unset PORT
unset STAGE
unset AWS_SESSION_TOKEN
unset AWS_SECURITY_TOKEN
unset GH_ORG_VALIDATION
unset DISABLE_LOCAL_PERMISSION_CHECKS
unset COMPANY_USER_VALIDATION
unset CLA_SIGNATURE_FILES_BUCKET
unset DYNAMODB_AWS_REGION
unset REGION
unset AWS_ROLE_ARN
unset AWS_TOKEN_SERIAL
unset AWS_SDK_LOAD_CONFIG
unset GITHUB_OAUTH_TOKEN
unset DOCUSIGN_INTEGRATOR_KEY
unset DOCUSIGN_USER_ID
unset DOCUSIGN_AUTH_SERVER
unset DOCUSIGN_ROOT_URL
unset DOCUSIGN_ACCOUNT_ID
2 changes: 2 additions & 0 deletions utils/describe_table.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
aws --profile lfproduct-dev dynamodb describe-table --table-name cla-dev-signatures
2 changes: 2 additions & 0 deletions utils/example_pytest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
pytest -vvv -s cla/tests/unit/test_docusign_models.py -p no:warnings -k test_request_individual_signature
7 changes: 7 additions & 0 deletions utils/health_python_v2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
# API_URL=https://[xyz].ngrok-free.app (defaults to localhost:5000)
if [ -z "$API_URL" ]
then
export API_URL="http://localhost:5000"
fi
curl -s "${API_URL}/v2/health" | jq -r '.'
2 changes: 2 additions & 0 deletions utils/lookup_company.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
aws --profile lfproduct-dev dynamodb query --table-name cla-dev-companies --index-name company-name-index --key-condition-expression "company_name = :name" --expression-attribute-values '{":name":{"S":"Google LLC"}}'
2 changes: 2 additions & 0 deletions utils/lookup_project.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
aws --profile lfproduct-dev dynamodb query --table-name cla-dev-projects --index-name project-name-lower-search-index --key-condition-expression "project_name_lower = :name" --expression-attribute-values '{":name":{"S":"child group earths"}}'
2 changes: 2 additions & 0 deletions utils/lookup_user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
aws --profile lfproduct-dev dynamodb query --table-name cla-dev-users --index-name github-username-index --key-condition-expression "user_github_username = :name" --expression-attribute-values '{":name":{"S":"lukaszgryglicki"}}'
2 changes: 2 additions & 0 deletions utils/ngrok.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
ngrok http http://localhost:5000
Loading
Loading