Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
`baton-coupa` [![Go Reference](https://pkg.go.dev/badge/github.com/conductorone/baton-coupa.svg)](https://pkg.go.dev/github.com/conductorone/baton-coupa) ![ci](https://github.com/conductorone/baton-coupa/actions/workflows/ci.yaml/badge.svg) ![verify](https://github.com/conductorone/baton-coupa/actions/workflows/verify.yaml/badge.svg)

`baton-coupa` is a connector for built using the [Baton SDK](https://github.com/conductorone/baton-sdk).
`baton-coupa` is a connector for Coupa built using the [Baton SDK](https://github.com/conductorone/baton-sdk). It communicates with the Coupa API to sync data about users, user groups, roles, per-module licenses, account groups and content groups, and supports provisioning of group, role, license, account-group and content-group membership as well as Coupa user accounts.

Check out [Baton](https://github.com/conductorone/baton) to learn more the project in general.

Expand All @@ -23,14 +23,20 @@ baton resources
## docker

```
docker run --rm -v $(pwd):/out -e BATON_DOMAIN_URL=domain_url -e BATON_API_KEY=apiKey -e BATON_USERNAME=username ghcr.io/conductorone/baton-coupa:latest -f "/out/sync.c1z"
docker run --rm -v $(pwd):/out -e BATON_COUPA_DOMAIN=acme.coupacloud.com -e BATON_COUPA_CLIENT_ID=clientId -e BATON_COUPA_CLIENT_SECRET=clientSecret ghcr.io/conductorone/baton-coupa:latest -f "/out/sync.c1z"
docker run --rm -v $(pwd):/out ghcr.io/conductorone/baton:latest -f "/out/sync.c1z" resources
```

## source

The `baton` CLI cannot be installed with `go install` — its module carries `replace`
directives, which `go install` rejects. Build it from a checkout, or take a prebuilt binary
from the [baton-sdk releases](https://github.com/ConductorOne/baton-sdk/releases).

```
go install github.com/conductorone/baton/cmd/baton@main
git clone --depth 1 https://github.com/ConductorOne/baton-sdk.git
cd baton-sdk && go build -o "$(go env GOPATH)/bin/baton" ./cmd/baton && cd -

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: go build -o will not create missing parent directories, so on a fresh Go install where $(go env GOPATH)/bin does not yet exist this line fails with "no such file or directory". Adding mkdir -p "$(go env GOPATH)/bin" before the build (or building with go build -o baton ./cmd/baton and letting the reader place it) makes the snippet copy-pasteable.


go install github.com/conductorone/baton-coupa/cmd/baton-coupa@main

baton-coupa
Expand All @@ -49,6 +55,11 @@ baton resources
- Account Groups
- Content Groups

Account Groups sync is opt-in: enable the resource type when configuring the connector in C1,
and add the `core.accounting.read` scope to your Coupa OAuth client.

Grant, revoke and account creation require the `--provisioning` flag (`BATON_PROVISIONING`).

# Actions

`baton-coupa` supports the following actions on user accounts:
Expand All @@ -59,14 +70,14 @@ Enables a disabled user account in Coupa.
**Action Name:** `enable_user`

**Arguments:**
- `user_id` (required, string): The ID of the user to enable
- `user_id` (required, string): The Coupa user's numeric ID the `id` field on `/api/users`, passed as a string (for example `"42"`). A login or an email address is rejected.

**Returns:**
- `success` (boolean): `true` if the user was successfully enabled

**Example:**
```bash
baton-coupa --invoke-action enable_user --invoke-action-args='{"user_id":"USER_ID"}'
baton-coupa --invoke-action enable_user --invoke-action-args='{"user_id":"42"}'
```

## Disable User
Expand All @@ -75,14 +86,14 @@ Disables an active user account in Coupa.
**Action Name:** `disable_user`

**Arguments:**
- `user_id` (required, string): The ID of the user to disable
- `user_id` (required, string): The Coupa user's numeric ID the `id` field on `/api/users`, passed as a string (for example `"42"`). A login or an email address is rejected.

**Returns:**
- `success` (boolean): `true` if the user was successfully disabled

**Example:**
```bash
baton-coupa --invoke-action disable_user --invoke-action-args='{"user_id":"USER_ID"}'
baton-coupa --invoke-action disable_user --invoke-action-args='{"user_id":"42"}'
```

# Contributing, Support and Issues
Expand Down
18 changes: 11 additions & 7 deletions docs/connector.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ sidebarTitle: "Coupa"
| Resource | Sync | Provision |
| :--- | :--- | :--- |
| Accounts | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The Accounts row still shows no Provision support, but userBuilder implements CreateAccount and CreateAccountCapabilityDetails (pkg/connector/users.go:207, :299), and the README change in this PR now advertises "account creation". Since this PR is aligning docs with code and edits this table, consider adding the provision check to the Accounts row so the two pages agree.

| Account Groups | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-check" iconType="solid" color="#c937ae"/> |
| Account Groups ¹ | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-check" iconType="solid" color="#c937ae"/> |
| Content Groups | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-check" iconType="solid" color="#c937ae"/> |
| Groups | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-check" iconType="solid" color="#c937ae"/> |
| Roles | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-check" iconType="solid" color="#c937ae"/> |
| Licenses | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-check" iconType="solid" color="#c937ae"/> |

¹ Account Groups sync is opt-in. To enable it, select **Account Groups** in the resource types to sync when configuring the connector in C1, and ensure the `core.accounting.read` OAuth scope is added to your Coupa OAuth client.

The **Licenses** resource surfaces each user's Coupa license assignments — such as Analytics, Purchasing, Sourcing, CLM Advanced, Navi AI Agent, and Intake — as license profiles, so they can be reviewed and provisioned through C1 License Management.

### Connector actions
Expand All @@ -29,8 +31,8 @@ Connector actions are custom capabilities that extend C1 automations with app-sp

| Action name | Additional fields | Description |
|-------------|-------------------|-------------|
| enable_user | `user_id` (string, required) | Enables a disabled user account in Coupa, allowing them to access the system |
| disable_user | `user_id` (string, required) | Disables an active user account in Coupa, preventing them from accessing the system |
| enable_user | `user_id` (string, required) — the Coupa user's numeric ID, the `id` field on `/api/users` | Enables a disabled user account in Coupa, allowing them to access the system |
| disable_user | `user_id` (string, required) — the Coupa user's numeric ID, the `id` field on `/api/users` | Disables an active user account in Coupa, preventing them from accessing the system |

## Gather Coupa credentials

Expand Down Expand Up @@ -69,7 +71,6 @@ A user with **Admin** access in Coupa must perform this task.
- Select scopes:

**You'll need these scopes to give C1 READ access (syncing access data):**
- core.accounting.read
- core.business_entity.read
- core.common.read
- core.user_group.read
Expand All @@ -79,12 +80,12 @@ A user with **Admin** access in Coupa must perform this task.
- openid
- profile

**You'll need these scopes to give C1 READ/WRITE access (syncing access data and provisioning access):**
**If you also want to sync Account Groups, add:**
- core.accounting.read

**You'll need these scopes to give C1 READ/WRITE access (syncing access data and provisioning access):**
- core.business_entity.read
- core.business_entity.write
- core.common.read
- core.common.write
- core.user_group.read
- core.user_group.write
- core.user.read
Expand All @@ -93,6 +94,9 @@ A user with **Admin** access in Coupa must perform this task.
- login
- openid
- profile

**If you also want to sync and provision Account Groups, add:**
- core.accounting.read
</Step>
<Step>
At the bottom of the page click **Save**.
Expand Down
Loading