# Source Control REST API

Source Control REST API can be used to:

1. Create, update, and delete source control entries for the root organization, sub-organizations, and applications. This is implemented with two separate endpoints one for all organizations (including the root), and a second one for applications. The API signatures between the two are similar and differences will be noted below.

2. Automatically assign a role (e.g., _developer_) to all contributors of a GitHub repository. This removes the need for manual user role assignment. See [Automatic Role Assignment](https://help.sonatype.com/en/source-control-rest-api.html#automatic-role-assignment--github- "Automatic Role Assignment (GitHub)").

3. Map existing SCM user credentials (GitHub) to local or LDAP _Lifecycle_ users.

This has been extended to include SAML users. The Source Control REST API can be used to map existing SCM user credentials (GitHub) to local, LDAP, SAML users (for on-premises IQ Server) and OAuth (for Cloud/SaaS IQ Server).

**Warning**

The `enablePullRequests` and `enableStatusChecks` fields in the JSON payload were deprecated in IQ Server Release 124:

`- enablePullRequests` was replaced with `pullRequestCommentingEnabled`

`- enableStatusChecks` was replaced with `statusChecksEnabled`

If you use an IQ Server version prior to 124, you'll have to replace the deprecated field names in the examples below.

## Create a source control entry

Permissions Required: `Edit IQ Elements`

To create a source control entry use the following endpoint. To create one for an organization use `organization` in the path, and for an application use `application` in the path.

```
POST /api/v2/sourceControl/{organization|application}/{ownerId}
```

With the following JSON body

```
{
    "token": "{scm access token}",
    "provider": "github",
    "repositoryUrl": "https://example.com/my-org/my-repo",
    "baseBranch": "master",
    "remediationPullRequestsEnabled": true,
    "pullRequestCommentingEnabled": true,
    "sourceControlEvaluationsEnabled": true
}
```

- The `ownerId` parameter is required. For the `/api/v2/sourceControl/organization/` endpoint it must be a valid organization ID (use "`ROOT_ORGANIZATION_ID`" for the root organization). For the `/api/v2/sourceControl/application/` endpoint it must be a valid application ID.

- The `repositoryUrl` can only be specified for applications. Valid HTTP(S) and SSH URLs are accepted.

- The `token` field is optional. It must be defined at one of the root organization, organization or application level. Each level inherits from the parent level and when present, will override any values set in the parents. See the [Source Control Configuration](https://help.sonatype.com/en/source-control-configuration.html#create-access-token "Create Access Token") page for information on what permissions or scopes are required on the token.

- The `username` field is optional and only allowed to be set on SCMs that require it. Currently, this is required for Bitbucket Server, Bitbucket Cloud and Azure DevOps.

- The `provider` field is required for the root organization and cannot be specified for other organizations or applications. Allowed values are `azure`, `github`, `gitlab`, and `bitbucket`.

- The `baseBranch` field is required for the root organization. Organizations and applications inherit from the root unless overridden.

- The `remediationPullRequestsEnabled` field is optional. Set to `true` to enable the Automated Pull Requests feature.

- The `pullRequestCommentingEnabled` field is optional. Set to `true` to enable the Pull Request Commenting feature.

- The `sourceControlEvaluationsEnabled` field is optional. Set to `true` to enable Nexus IQ triggered source control evaluations, which are the foundation of the Continuous Risk Profile feature.

**Note**

Two formats are supported for SSH URLs: `ssh://user@server/project-path.git` and `user@server:project-path.git`.

On save all SSH URLs are converted to the HTTPS format. If an SSH URL is provided, subsequent retrievals will return the converted URL.

## Get a source control entry

Permissions Required: `View IQ Elements`

To get a source control entry use the following endpoint. To get for an organization use `organization` in the path, and for an application use `application` in the path.

```
GET /api/v2/sourceControl/{organization|application}/{ownerId}
```

The response can contain the following fields

```
{
    "id": "83af9dafc06946f9a82833eceb8425ed",
    "ownerId": "7e68069cbb228a05bbf89a2c2992a8bce45b1027",
    "repositoryUrl": null,
    "token": "#~FAKE~SECRET~KEY~#",
    "provider": null,
    "baseBranch": "master",
    "remediationPullRequestsEnabled": null,
    "pullRequestCommentingEnabled": null,
    "sourceControlEvaluationsEnabled": null,
    "statusChecksEnabled": null
}
```

- Fields that do not contain a value are `null`. For organizations and applications, this indicates inheriting the configuration from the parent. Applications will inherit values from the parent organization and organizations will inherit from the root organization.

- The `ownerId` field is required. For the `/api/v2/sourceControl/organization/` endpoint it will be an organization ID. For the `/api/v2/sourceControl/application/` endpoint it will be an application ID.

- The `repositoryUrl` will only show for applications and will always be `null` for organizations.

- The `token` field is obfuscated if populated.

- The `id` and `statusChecksEnabled` fields are internal fields.

## Replace a source control entry

Permissions Required: `Edit IQ Elements`

To replace a source control entry use the following endpoint. To replace one for an organization use `organization` in the path, and for an application use `application` in the path.

```
PUT /api/v2/sourceControl/{organization|application}/{ownerId}
```

- The `ownerId` parameter is required. For the `/api/v2/sourceControl/organization/` endpoint it will be an organization ID. For the `/api/v2/sourceControl/application/` endpoint it will be an application ID.

With the same JSON body as for `POST`.

## Enable non-Golden automated pull requests

Non-Golden automated pull requests can be enabled using the Source Control REST API. This option is not available in the UI.

First, retrieve the existing source control configuration:

```
GET /api/v2/sourceControl/{organization|application}/{ownerId}
```

Permissions Required: **View IQ Elements**

Then, submit the full existing configuration with `nonGoldenPullRequestsEnabled` set to `true`:

```
PUT /api/v2/sourceControl/{organization|application}/{ownerId}
```

Permissions Required: **Edit IQ Elements**

```
{
  "token": "{scm access token}",
  "provider": "github",
  "repositoryUrl": "https://example.com/my-org/my-repo",
  "baseBranch": "master",
  "remediationPullRequestsEnabled": true,
  "pullRequestCommentingEnabled": true,
  "sourceControlEvaluationsEnabled": true,
  "nonGoldenPullRequestsEnabled": true
}
```

**Note**

The PUT request must include the existing source control configuration from the GET response, with `nonGoldenPullRequestsEnabled` added or updated. Do not send a partial request body.

When `nonGoldenPullRequestsEnabled` is set to `true`, automated pull requests can be created for non-Golden remediation versions when a Golden Version is not available.

## Delete a source control entry

Permissions Required: `Edit IQ Elements`

To delete a source control entry use the following endpoint. To delete one for an organization use `organization` in the path, and for an application use `application` in the path.

```
DELETE /api/v2/sourceControl/{organization|application}/{ownerId}
```

The response is an empty payload with a `204` (Success - no content) status.

## Automatic Role Assignment (GitHub)

Automatic Role Assignment lets you automatically grant Lifecycle roles to GitHub contributors.

**Note**

This capability is currently offered for GitHub repositories only.

This feature currently supports matching for local, LDAP, SAML (release 192 for on-premises IQ Server) and OAuth (for Cloud/SaaS IQ Server) user accounts.

### Prerequisites for Automatic Role Assignment

To use automatic role assignment, you must meet the following prerequisites:

- You must have configured source control for the application in IQ.
- You must add an authentication token to the SCM configuration for that source control; the token must include at least one of the following GitHub OAuth scopes:

- `user:email`
  - `read:user`

- The user performing the role assignment must have _Edit Access Control_ permission for the given application.

#### Automatic Role Assignment Process

Automatic Role Assignment works as follows:

1. Execute a `POST` command using the Automatic Role Assignment API. Include the user mappings in the request payload as in the following example; alternatively, you can configure user mappings on the parent organization using the [Configure User Mappings API](https://help.sonatype.com/en/source-control-rest-api.html#configure-user-mappings--github- "Configure User Mappings (GitHub)"):

```
curl -u admin:admin123 \
     -X POST -H "Content-Type: application/json" \
     --data-raw '{"role":"developer","mappings":[{"from":"SCM_EMAIL","to":"IQ_EMAIL"},{"from":"SCM_FULLNAME","to":"IQ_FULLNAME"},{"from":"SCM_USERNAME","to":"IQ_USERNAME"},{"from":"GITLOG_FULLNAME","to":"IQ_FULLNAME"},{"from":"GITLOG_EMAIL","to":"IQ_EMAIL"}]}' \
     http://localhost:8070/api/v2/sourceControl/automaticRoleAssignment/my-public-app-id
```

2. If you provide **multiple mappings**, Lifecycle will try the mappings in order and stop evaluating once it finds a mapping that yields at least one match (i.e., if the first mapping does not match, it moves on to the next mapping).

3. If you provide the user mapping configuration payload in the Automatic Role Assignment request, Lifecycle will use the provided mapping.

4. If you **do not** provide the user mapping configuration payload in the Automatic Role Assignment request, Lifecycle will look for and use a [configured user mapping](https://help.sonatype.com/en/source-control-rest-api.html#configure-user-mappings--github- "Configure User Mappings (GitHub)").

5. If a user mapping configuration is neither provided in the role assignment request nor pre-configured, the request will fail.

6. Lifecycle will assign the role specified in the user mapping to any repository contributor who meets the user mapping criteria.

7. A successful response provides a list of all users found in GitHub who were successfully granted the specified role on the application as well as the mapping used to match users.

```
{
"successfulMapping": {"from":"SCM_EMAIL","to":"IQ_EMAIL"},{"from":"SCM_FULLNAME","to":"IQ_FULLNAME"},{"from":"SCM_USERNAME","to":"IQ_USERNAME"},{"from":"GITLOG_FULLNAME","to":"IQ_FULLNAME"},{"from":"GITLOG_EMAIL","to":"IQ_EMAIL"}null,
"matchedUsers": [\
     "githubUser1",\
     "githubUser2",\
     "githubUser3",\
     "githubUser4",\
     "githubUser5",\
     "githubUser6",\
     "githubUser7"\
]
}
```

## Configure User Mappings (GitHub)

User mappings define how Lifecycle attempts to match GitHub contributor information to existing local, LDAP or SAML (release 192) Lifecycle users.

Each mapping consists of the following:

- A `from` field (GitHub data)
- A `to` field (Lifecycle user attribute)

When you provide multiple user mappings, Lifecycle tries the mappings in order and stops evaluating once it finds a mapping that yields at least one match (i.e., if the first mapping does not match, it moves on to the next mapping).

If you specify duplicate user mappings, you will see an error message like the one below:

```
There was a duplicate mapping GITLOG_FULLNAME:IQ_FULLNAME . Mappings should be unique
```

**Leverage Easy SCM Onboarding and User Mappings**

Configure user mappings before importing applications with [Easy SCM Onboarding](https://help.sonatype.com/en/easy-scm-onboarding.html "Easy SCM Onboarding") to allow Lifecycle to automatically assign roles to your GitHub users during the onboarding process. Note that this same automatic assignment does not occur if you import applications with the Application API instead of using Easy SCM Onboarding.

### Apply User Mappings to an Organization in Lifecycle

Apply user mappings to an organization in Lifecycle using the POST method.

The user mappings will be inherited by all organizations and applications under the specified `organizationId`.

```
POST /api/v2/sourceControl/automaticRoleAssignment/userMappings/{organizationId}
```

Request body as JSON:

```
{
  "role": "developer",
  "mappings":  [\
    {\
      "from": "SCM_EMAIL",\
      "to": "IQ_EMAIL"\
    },\
  ]
}
```

Here is a complete example:

```
curl -u admin:admin123 \
  -X POST -H "Content-Type: application/json" \
  --data-raw '{"role":"developer","mappings":[{"from":"SCM_EMAIL","to":"IQ_EMAIL"},{"from":"SCM_FULLNAME","to":"IQ_FULLNAME"},{"from":"SCM_USERNAME","to":"IQ_USERNAME"},{"from":"GITLOG_FULLNAME","to":"IQ_FULLNAME"},{"from":"GITLOG_EMAIL","to":"IQ_EMAIL"}]}' \
  http://localhost:8070/api/v2/sourceControl/automaticRoleAssignment/userMappings/39cdb8dc95444802944545e3a6d8de8d
```

Lifecycle will attempt to match GitHub contributor emails to local/LDAP/SAML (release 192) user emails.

**Mapping GitHub Email Ids**

Some users in GitHub may have their email Ids set to private or use personal email instead of the organization email. For such cases, we recommend using GITLOG_EMAIL to map the user's email Id, instead of using SCM_EMAIL.

The table below explains each parameter:

| Input parameter | Required | Description |
| --- | --- | --- |
| `organizationId` | Yes | Must be a valid organization that exists in your Lifecycle instance.<br>use `ROOT_ORGANIZATION_ID` for the root organization.<br>If a user mapping for the organization already exists, it will be replaced with the new mappings.<br>The user mapping will be inherited by all organizations and applications under the specified organizationId. |
| `role` | Yes | Indicates the name of the role in lowercase, without white spaces.<br>For example, System Administrator should be entered as `systemadministrator` |
| `mappings` | Yes | Is an array of objects consisting of `from` and `to` fields. Refer to user mappings for details.<br>Allowed `from` values (GitHub data) are as follows:<br>- `SCM_USERNAME`<br>  <br>- `SCM_EMAIL` (only supports matching if contributor emails are public)<br>  <br>- `SCM_FULLNAME`<br>  <br>- `GITLOG_EMAIL`<br>  <br>- `GITLOG_FULLNAME`<br>  <br>Allowed `to` values (Lifecycle user attributes) are as follows:<br>- `IQ_USERNAME`<br>  <br>- `IQ_EMAIL`<br>  <br>- `IQ_FULLNAME` |

You can also use any combination of the allowed values for the `from` and `to` fields such as in the example below:

```
{
  "from": "SCM_USERNAME",
  "to": "IQ_EMAIL"
},
{
  "from": "GITLOG_FULLNAME",
  "to": "IQ_USERNAME"
}
```

Here are some additional suggested user mappings:

```
{
  "from": "GITLOG_EMAIL",
  "to": "IQ_EMAIL"
},
{
  "from": "GITLOG_FULLNAME",
  "to": "IQ_FULLNAME"
},
{
  "from": "SCM_USERNAME",
  "to": "IQ_USERNAME"
},
{
  "from": "SCM_EMAIL",
  "to": "IQ_EMAIL"
},
{
  "from": "SCM_FULLNAME",
  "to": "IQ_FULLNAME"
}
```

### Retrieve Existing User Mappings (GitHub)

Use the GET method to retrieve the SCM user mappings by specifying the `organization` or `application`.

```
GET /api/v2/sourceControl/automaticRoleAssignment/userMappings/{ownerType}/{ownerId}
```

The table below defines each input parameter:

| Input parameter | Required | Description |
| --- | --- | --- |
| `ownerType` | Yes | The type of owner. Accepted values are `organization` or `application`. |
| `ownerId` | Yes | The internal id of the specified `ownerType`. |

The response provides the user mapping information:

```
{
  "organizationId": "80599b788da849a796c96e245770179f",
  "inherited": true,
  "userMapping": {
    "role": "developer",
    "mappings": [\
      {"from": "GITHUB_EMAIL", "to": "IQ_USERNAME" },\
      {"from": "GITLOG_EMAIL", "to": "IQ_EMAIL" },\
      {"from": "GITHUB_FULLNAME", "to": "IQ_FULLNAME" }\
    ]
  }
}
```

Each response field is explained in the table below:

| Response field | Description |
| --- | --- |
| `organizationId` | Indicates the organization id for which the user mappings were created. |
| `inherited` | Value is always `true` if the specified `ownerType` is `application`. |
| `userMapping` | Is an object containing `role` and `mappings`<br>`role` indicates the role assigned to users during automatic role assignment.<br>`mappings` contains all user mappings. |

### Delete Existing User Mappings (GitHub)

Use the DELETE method to delete existing SCM user mappings by specifying the `OrganizationId` for which the user mappings were created.

```
DELETE /api/v2/sourceControl/automaticRoleAssignment/userMappings/{organizationId}
```

The input parameter `organizationId` is required.
