
# Sostituire le associazioni di attributi di una connessione

`PUT /v1/connections/{connection_id}/attribute-mappings` · permesso `connections:write`

Sostituisce l'intera lista di associazioni di attributi di una connessione aziendale. L'ordine delle regole non conta; la risposta è ordinata per destinazione. `If-Match` è obbligatorio: senza di esso la richiesta fallisce con `428`; se la lista è cambiata dalla tua ultima lettura (o il valore non corrisponde), la richiesta fallisce con `412` e non viene scritto nulla. Inviare la stessa lista non scrive nulla. La modifica si applica dall'accesso successivo e non invalida l'ultimo test di connessione superato. La scrittura viene registrata nell'audit come `connection.attribute_mappings_replaced` (destinazioni aggiunte, rimosse e modificate); i valori degli attributi degli accessi non vengono mai scritti nel registro di audit.

## Richiesta

| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| `connection_id` | percorso | sì | ID della connessione aziendale (`conn_…`). |
| `If-Match` | intestazione | sì | L'`ETag` dell'ultima lettura. Mancante: `428`; obsoleto: `412`. |
| `attribute_mappings` | array | sì | La nuova lista completa, con al massimo 28 regole. |
| `attribute_mappings[].target` | stringa | sì | `email` (obbligatorio in ogni lista), `given_name`, `family_name`, `name`, `locale`, `zoneinfo`, `phone`, `groups` oppure `user_metadata.<key>` (chiave `[a-z0-9_]{1,40}`; non sono ammessi i nomi di claim OIDC registrati né il prefisso `idp_`; al massimo 20 chiavi). Una regola per destinazione. Un'associazione non può scrivere `app_metadata`. |
| `attribute_mappings[].source_name` | stringa | sì | Da 1 a 512 byte, senza caratteri di controllo o bidirezionali, senza spazi iniziali o finali. |
| `attribute_mappings[].source_name_format` | stringa \| null | no | `NameFormat` SAML (URI assoluto). Un nome sorgente può essere letto con un solo formato. |
| `attribute_mappings[].overwrite` | stringa | sì | `always`, `if_empty` oppure `never`. |
| `attribute_mappings[].profile` | stringa | no | Nome del profilo predefinito; `generic` se omesso. |

## Risposta

`200 OK` con l'elenco memorizzato (vedi [Recuperare le associazioni di attributi](get.md)) e il nuovo `ETag`.

## Errori

| HTTP | code | Quando |
|---|---|---|
| 404 | `not_found` | La connessione non esiste in questo ambiente o non è una connessione aziendale. |
| 409 | `conflict` | Il protocollo della connessione non prevede associazioni di attributi (LDAP). |
| 412 | `precondition_failed` | `If-Match` non corrisponde alla versione corrente, oppure l'elenco è stato modificato nel frattempo. |
| 422 | `validation_failed` | Una regola viola le regole sopra indicate. Ogni regola non valida è un elemento di `errors[]` che punta a `/attribute_mappings/<index>/<field>`, oppure a `/attribute_mappings` per le regole di elenco (`email_required`, `too_many_metadata_keys`). |
| 428 | `precondition_required` | L'intestazione `If-Match` è mancante. |
| 400 | `unknown_field` | Il corpo contiene un campo sconosciuto. |
| 401 | `unauthenticated` | La credenziale è assente, non valida o revocata. |
| 403 | `insufficient_permissions` | La credenziale non ha il permesso richiesto. |
| 429 | `rate_limited` | È stato superato il limite di frequenza; riprova dopo il periodo indicato da `Retry-After`. |
| 503 | `service_unavailable` | Una dipendenza è temporaneamente non disponibile; riprova dopo il periodo indicato da `Retry-After`. |

## Esempio

```bash
curl -X PUT "https://api.eu.keenauth.com/v1/connections/conn_01j9xp6q0r1s5t7v9w1x3y5z7b/attribute-mappings" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H 'If-Match: "6f1c…"' \
  -d '{"attribute_mappings":[{"target":"email","source_name":"email","overwrite":"always"},{"target":"user_metadata.department","source_name":"department","overwrite":"if_empty"}]}'
```

```bash
keenauth connections attribute-mappings put conn_01j9xp6q0r1s5t7v9w1x3y5z7b --data @mappings.json --if-match '"6f1c…"'
```
