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
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ For more detailed information or the sources of truths, please refer to the indi
- 8.3 [Views System](#83-views-system)
- 8.4 [Rate Limiting](#84-rate-limiting)
- 8.5 [Attribute-Based Access Control (ABAC)](#85-attribute-based-access-control-abac)
- 8.6 [User Attributes and Personal Data](#86-user-attributes-and-personal-data)
- 8.6 [User Attributes and Personal Data Fields](#86-user-attributes-and-personal-data-fields)
- 8.7 [Security Best Practices](#87-security-best-practices)
9. [Use Cases](#use-cases)
10. [Monitoring, Logging, and Troubleshooting](#monitoring-logging-and-troubleshooting)
Expand Down Expand Up @@ -3034,11 +3034,11 @@ isAdmin || isBusinessHours
- CanCreateAbacRule, CanGetAbacRule, CanUpdateAbacRule, CanDeleteAbacRule
- CanExecuteAbacRule, CanGetAbacRuleSchema, CanValidateAbacRule

### 8.6 User Attributes and Personal Data
### 8.6 User Attributes and Personal Data Fields

**Status:** New in v6.0.0

**Purpose:** Manage user-associated data with clear separation between ABAC-accessible attributes and private personal data.
**Purpose:** Manage user-associated data with clear separation between ABAC-accessible attributes and private personal data fields.

**User Attributes** (Non-Personal):

Expand All @@ -3052,22 +3052,22 @@ PUT /obp/v6.0.0/users/USER_ID/attributes/USER_ATTRIBUTE_ID # Update
DELETE /obp/v6.0.0/users/USER_ID/attributes/USER_ATTRIBUTE_ID # Delete
```

**Personal Data** (User-Managed):
**Personal Data Fields** (User-Managed):

Personal data is managed by users themselves without requiring special roles. For privacy, personal data is NOT available in ABAC rules.
Personal Data Fields are managed by users themselves without requiring special roles. For privacy, Personal Data Fields are NOT available in ABAC rules.

```bash
POST /obp/v6.0.0/my/personal-data # Create
GET /obp/v6.0.0/my/personal-data # List
GET /obp/v6.0.0/my/personal-data/USER_ATTRIBUTE_ID # Get
PUT /obp/v6.0.0/my/personal-data/USER_ATTRIBUTE_ID # Update
DELETE /obp/v6.0.0/my/personal-data/USER_ATTRIBUTE_ID # Delete
POST /obp/v6.0.0/my/personal-data-fields # Create
GET /obp/v6.0.0/my/personal-data-fields # List
GET /obp/v6.0.0/my/personal-data-fields/USER_ATTRIBUTE_ID # Get
PUT /obp/v6.0.0/my/personal-data-fields/USER_ATTRIBUTE_ID # Update
DELETE /obp/v6.0.0/my/personal-data-fields/USER_ATTRIBUTE_ID # Delete
```

**Key Distinction:**

| Feature | User Attributes | Personal Data |
|---------|-----------------|---------------|
| Feature | User Attributes | Personal Data Fields |
|---------|-----------------|----------------------|
| Who manages | Administrators | Users themselves |
| Roles required | Yes | No |
| Available in ABAC | Yes | No (privacy) |
Expand Down
78 changes: 39 additions & 39 deletions obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7948,7 +7948,7 @@ trait APIMethods600 {
|User Attributes are non-personal attributes (IsPersonal=false) that can be used in ABAC rules.
|They require a role to set, similar to Customer Attributes, Account Attributes, etc.
|
|For personal attributes that users manage themselves, see the /my/personal-user-attributes endpoints.
|For personal attributes that users manage themselves, see the /my/personal-data-fields endpoints.
|
|The type field must be one of "STRING", "INTEGER", "DOUBLE" or "DATE_WITH_DAY"
|
Expand Down Expand Up @@ -8200,19 +8200,19 @@ trait APIMethods600 {
}

// ============================================================================================================
// PERSONAL DATA - User manages their own personal data
// PERSONAL DATA FIELDS - User manages their own personal data fields
// ============================================================================================================

staticResourceDocs += ResourceDoc(
createMyPersonalUserAttribute,
createPersonalDataField,
implementedInApiVersion,
nameOf(createMyPersonalUserAttribute),
nameOf(createPersonalDataField),
"POST",
"/my/personal-data",
"Create My Personal Data",
s"""Create Personal Data for the currently authenticated user.
"/my/personal-data-fields",
"Create Personal Data Field",
s"""Create a Personal Data Field for the currently authenticated user.
|
|Personal Data (IsPersonal=true) is managed by the user themselves and does not require special roles.
|Personal Data Fields (IsPersonal=true) are managed by the user themselves and do not require special roles.
|This data is not available in ABAC rules for privacy reasons.
|
|For non-personal attributes that can be used in ABAC rules, see the /users/USER_ID/attributes endpoints.
Expand All @@ -8236,8 +8236,8 @@ trait APIMethods600 {
Some(List())
)

lazy val createMyPersonalUserAttribute: OBPEndpoint = {
case "my" :: "personal-data" :: Nil JsonPost json -> _ => {
lazy val createPersonalDataField: OBPEndpoint = {
case "my" :: "personal-data-fields" :: Nil JsonPost json -> _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- authenticatedAccess(cc)
Expand Down Expand Up @@ -8265,15 +8265,15 @@ trait APIMethods600 {
}

staticResourceDocs += ResourceDoc(
getMyPersonalUserAttributes,
getPersonalDataFields,
implementedInApiVersion,
nameOf(getMyPersonalUserAttributes),
nameOf(getPersonalDataFields),
"GET",
"/my/personal-data",
"Get My Personal Data",
s"""Get Personal Data for the currently authenticated user.
"/my/personal-data-fields",
"Get Personal Data Fields",
s"""Get Personal Data Fields for the currently authenticated user.
|
|Returns personal data (IsPersonal=true) that is managed by the user.
|Returns Personal Data Fields (IsPersonal=true) that are managed by the user.
|
|${userAuthenticationMessage(true)}
|""".stripMargin,
Expand All @@ -8289,8 +8289,8 @@ trait APIMethods600 {
Some(List())
)

lazy val getMyPersonalUserAttributes: OBPEndpoint = {
case "my" :: "personal-data" :: Nil JsonGet _ => {
lazy val getPersonalDataFields: OBPEndpoint = {
case "my" :: "personal-data-fields" :: Nil JsonGet _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- authenticatedAccess(cc)
Expand All @@ -8302,13 +8302,13 @@ trait APIMethods600 {
}

staticResourceDocs += ResourceDoc(
getMyPersonalUserAttributeById,
getPersonalDataFieldById,
implementedInApiVersion,
nameOf(getMyPersonalUserAttributeById),
nameOf(getPersonalDataFieldById),
"GET",
"/my/personal-data/USER_ATTRIBUTE_ID",
"Get My Personal Data By Id",
s"""Get Personal Data by USER_ATTRIBUTE_ID for the currently authenticated user.
"/my/personal-data-fields/USER_ATTRIBUTE_ID",
"Get Personal Data Field By Id",
s"""Get a Personal Data Field by USER_ATTRIBUTE_ID for the currently authenticated user.
|
|${userAuthenticationMessage(true)}
|""".stripMargin,
Expand All @@ -8323,8 +8323,8 @@ trait APIMethods600 {
Some(List())
)

lazy val getMyPersonalUserAttributeById: OBPEndpoint = {
case "my" :: "personal-data" :: userAttributeId :: Nil JsonGet _ => {
lazy val getPersonalDataFieldById: OBPEndpoint = {
case "my" :: "personal-data-fields" :: userAttributeId :: Nil JsonGet _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- authenticatedAccess(cc)
Expand All @@ -8341,13 +8341,13 @@ trait APIMethods600 {
}

staticResourceDocs += ResourceDoc(
updateMyPersonalUserAttribute,
updatePersonalDataField,
implementedInApiVersion,
nameOf(updateMyPersonalUserAttribute),
nameOf(updatePersonalDataField),
"PUT",
"/my/personal-data/USER_ATTRIBUTE_ID",
"Update My Personal Data",
s"""Update Personal Data by USER_ATTRIBUTE_ID for the currently authenticated user.
"/my/personal-data-fields/USER_ATTRIBUTE_ID",
"Update Personal Data Field",
s"""Update a Personal Data Field by USER_ATTRIBUTE_ID for the currently authenticated user.
|
|${userAuthenticationMessage(true)}
|""".stripMargin,
Expand All @@ -8367,8 +8367,8 @@ trait APIMethods600 {
Some(List())
)

lazy val updateMyPersonalUserAttribute: OBPEndpoint = {
case "my" :: "personal-data" :: userAttributeId :: Nil JsonPut json -> _ => {
lazy val updatePersonalDataField: OBPEndpoint = {
case "my" :: "personal-data-fields" :: userAttributeId :: Nil JsonPut json -> _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- authenticatedAccess(cc)
Expand Down Expand Up @@ -8402,13 +8402,13 @@ trait APIMethods600 {
}

staticResourceDocs += ResourceDoc(
deleteMyPersonalUserAttribute,
deletePersonalDataField,
implementedInApiVersion,
nameOf(deleteMyPersonalUserAttribute),
nameOf(deletePersonalDataField),
"DELETE",
"/my/personal-data/USER_ATTRIBUTE_ID",
"Delete My Personal Data",
s"""Delete Personal Data by USER_ATTRIBUTE_ID for the currently authenticated user.
"/my/personal-data-fields/USER_ATTRIBUTE_ID",
"Delete Personal Data Field",
s"""Delete a Personal Data Field by USER_ATTRIBUTE_ID for the currently authenticated user.
|
|${userAuthenticationMessage(true)}
|""".stripMargin,
Expand All @@ -8423,8 +8423,8 @@ trait APIMethods600 {
Some(List())
)

lazy val deleteMyPersonalUserAttribute: OBPEndpoint = {
case "my" :: "personal-data" :: userAttributeId :: Nil JsonDelete _ => {
lazy val deletePersonalDataField: OBPEndpoint = {
case "my" :: "personal-data-fields" :: userAttributeId :: Nil JsonDelete _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- authenticatedAccess(cc)
Expand Down
8 changes: 8 additions & 0 deletions obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ object OBPAPI6_0_0 extends OBPRestHelper
nameOf(Implementations4_0_0.grantUserAccessToView) ::
nameOf(Implementations4_0_0.revokeUserAccessToView) ::
nameOf(Implementations4_0_0.revokeGrantUserAccessToViews) ::// this endpoint is forbidden in V600, we do not support multi views in one endpoint from V600.
// v4.0.0 personal user attribute endpoints replaced by /my/personal-data-fields in v6.0.0
nameOf(Implementations4_0_0.getMyPersonalUserAttributes) ::
nameOf(Implementations4_0_0.createMyPersonalUserAttribute) ::
nameOf(Implementations4_0_0.updateMyPersonalUserAttribute) ::
// v5.1.0 non-personal user attribute endpoints replaced by /users/USER_ID/attributes in v6.0.0
nameOf(Implementations5_1_0.createNonPersonalUserAttribute) ::
nameOf(Implementations5_1_0.getNonPersonalUserAttributes) ::
nameOf(Implementations5_1_0.deleteNonPersonalUserAttribute) ::
Nil

// if old version ResourceDoc objects have the same name endpoint with new version, omit old version ResourceDoc.
Expand Down