openapi: 3.0.0
info:
  version: 1.0.2
  title: 'User Sharing API Definition'
  description: |-
    This API provides organization administrators with the ability to manage user access across child organizations. It supports operations to share users with specific or all child organizations, retrieve shared access details, and remove shared access as needed. The API also includes features for paginated retrieval of organizations and roles associated with shared users.
  contact:
    name: WSO2
    url: 'http://wso2.com/products/identity-server/'
    email: iam-dev@wso2.org
  license:
    name: Apache 2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
servers:
  - url: 'https://{server-url}/t/{tenant-domain}/api/server/v1'
    variables:
      tenant-domain:
        default: "carbon.super"
      server-url:
        default: "localhost:9443"
paths:
  /users/share:
    post:
      tags:
        - User Sharing
      summary: Share a user across specific organizations
      description: |
        This API shares one or more users across specified organizations, assigning roles based on the provided policy. The policy defines the sharing scope for each organization, including whether access extends to child organizations.
        
        <b>Scope(Permission) required:</b> `internal_user_share`
      operationId: processUserSharing
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserShareRequestBody'
            example:
              userCriteria:
                userIds:
                  - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
                  - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"
              organizations:
                - orgId: "b028ca17-8f89-449c-ae27-fa955e66465d"
                  policy: "SELECTED_ORG_ONLY"
                  roles:
                    - displayName: "role_2"
                      audience:
                        display: "My Org 1"
                        type: "organization"
                - orgId: "a17b28ca-9f89-449c-ae27-fa955e66465f"
                  policy: "SELECTED_ORG_ONLY"
                  roles: []
        required: true
      responses:
        '202':
          description: Sharing process triggered successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProcessSuccessResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /users/share-with-all:
    post:
      tags:
        - User Sharing
      summary: Share a user with all organizations
      description: |
        This API shares users across all organizations, applying the provided roles to each organization. The policy determines the scope of sharing, including whether it applies to all current organizations or future organizations as well.
        
        <b>Scope(Permission) required:</b> `internal_user_share`
      operationId: processUserSharingAll
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserShareWithAllRequestBody'
            example:
              userCriteria:
                userIds:
                  - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
                  - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"
              policy: "ALL_EXISTING_ORGS_ONLY"
              roles:
                - displayName: "role_1"
                  audience:
                    display: "My Org 1"
                    type: "organization"
                - displayName: "role_2"
                  audience:
                    display: "My App 1"
                    type: "application"
        required: true
      responses:
        '202':
          description: Sharing process triggered successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProcessSuccessResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /users/unshare:
    post:
      tags:
        - User Sharing
      summary: Unshare a user from specific organizations
      description: |
        This API removes shared access for one or more users from specified organizations.
        The payload includes the list of user IDs and the organizations from which the users should be unshared.
        
        <b>Scope(Permission) required:</b> `internal_user_unshare`
      operationId: processUserUnsharing
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserUnshareRequestBody'
            example:
              userCriteria:
                userIds:
                  - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
                  - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"
              organizations:
                - "b028ca17-8f89-449c-ae27-fa955e66465d"
                - "a17b28ca-9f89-449c-ae27-fa955e66465f"
        required: true
      responses:
        '202':
          description: Unsharing process triggered successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProcessSuccessResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /users/unshare-with-all:
    post:
      tags:
        - User Sharing
      summary: Remove a user's shared access
      description: |
        This API removes all shared access for one or more users, unsharing them from all organizations.
        
        <b>Scope(Permission) required:</b> `internal_user_unshare`
      operationId: removeUserSharing
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserUnshareWithAllRequestBody'
            example:
              userCriteria:
                userIds:
                  - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
                  - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"
        required: true
      responses:
        '202':
          description: Share removal process triggered successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProcessSuccessResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /users/{userId}/shared-organizations:
    get:
      tags:
        - User Accessible Organizations
      summary: Get organizations a user has access to
      description: |
        This API retrieves the list of organizations where the specified user has shared access, with support for pagination and filtering.

        <b>Scope(Permission) required:</b> `internal_user_shared_access_view`
      parameters:
        - in: path
          name: userId
          required: true
          schema:
            type: string
          description: The ID of the user whose accessible organizations are being retrieved.
        - in: query
          name: after
          schema:
            type: string
          description: The cursor pointing to the item after which the next page of results should be returned.
        - in: query
          name: before
          schema:
            type: string
          description: The cursor pointing to the item before which the previous page of results should be returned.
        - in: query
          name: limit
          schema:
            type: integer
          description: The maximum number of results to return per page.
        - in: query
          name: filter
          schema:
            type: string
          description: A filter to apply to the results, such as by organization name or other criteria.
        - in: query
          name: recursive
          schema:
            type: boolean
            default: false
          description: Whether to retrieve organizations recursively, including child organizations.
      responses:
        '200':
          description: Successful Response with Accessible Organizations
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserSharedOrganizationsResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /users/{userId}/shared-roles:
    get:
      tags:
        - User Accessible Roles
      summary: Get roles assigned to a user in an organization
      description: |
        This API fetches the roles assigned to the specified user within a particular organization, with support for pagination, filtering, and recursion.

        <b>Scope(Permission) required:</b> `internal_user_shared_access_view`
      parameters:
        - in: path
          name: userId
          required: true
          schema:
            type: string
          description: The ID of the user for whom roles are being retrieved.
        - in: query
          name: orgId
          required: true
          schema:
            type: string
          description: The organization ID for which roles are being fetched.
        - in: query
          name: after
          schema:
            type: string
          description: The cursor pointing to the item after which the next page of results should be returned.
        - in: query
          name: before
          schema:
            type: string
          description: The cursor pointing to the item before which the previous page of results should be returned.
        - in: query
          name: limit
          schema:
            type: integer
          description: The maximum number of results to return per page.
        - in: query
          name: filter
          schema:
            type: string
          description: Filter to apply when retrieving the roles.
        - in: query
          name: recursive
          schema:
            type: boolean
          description: Set to true to retrieve roles recursively.
      responses:
        '200':
          description: Successful Response with Accessible Roles
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserSharedRolesResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'


components:
  schemas:

    UserShareRequestBody:
      type: object
      description: |
        The request body for sharing users with multiple child organizations.
        Includes a list of users, organizations, sharing scope as policy, and roles.
      required:
        - userCriteria
        - organizations
      properties:
        userCriteria:
          type: object
          description: Contains a list of user IDs to be shared.
          properties:
            userIds:
              type: array
              description: List of user IDs.
              items:
                type: string
                description: The ID of a user to be shared.
        organizations:
          type: array
          description: List of organizations specifying sharing scope and roles.
          items:
            type: object
            required:
              - orgId
              - policy
            properties:
              orgId:
                type: string
                description: The ID of the organization to share the users with.
              policy:
                type: string
                description: The scope of sharing for this organization.
                enum: ["SELECTED_ORG_ONLY", "SELECTED_ORG_WITH_ALL_EXISTING_CHILDREN_ONLY",
                       "SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN",
                       "SELECTED_ORG_WITH_EXISTING_IMMEDIATE_CHILDREN_ONLY",
                       "SELECTED_ORG_WITH_EXISTING_IMMEDIATE_AND_FUTURE_CHILDREN", "NO_ORG"]
              roles:
                type: array
                description: A list of roles to be shared with the organization.
                items:
                  $ref: '#/components/schemas/RoleWithAudience'
      example:
        userCriteria:
          userIds:
            - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
            - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"
        organizations:
          - orgId: "b028ca17-8f89-449c-ae27-fa955e66465d"
            policy: "SELECTED_ORG_ONLY"
            roles:
              - displayName: "role_2"
                audience:
                  display: "My Org 1"
                  type: "organization"
          - orgId: "a17b28ca-9f89-449c-ae27-fa955e66465f"
            policy: "SELECTED_ORG_ONLY"
            roles: []

    UserShareWithAllRequestBody:
      type: object
      description: |
        Process a request to share users with all organizations. 
        The payload contains the roles applicable across all organizations and a policy that defines the scope of sharing.
      required:
        - userCriteria
        - policy
      properties:
        userCriteria:
          type: object
          description: Contains a list of user IDs to be shared.
          properties:
            userIds:
              type: array
              description: List of user IDs.
              items:
                type: string
                description: The ID of a user to be shared.
        policy:
          type: string
          description: A policy to specify the sharing scope.
          enum: ["ALL_EXISTING_ORGS_ONLY", "ALL_EXISTING_AND_FUTURE_ORGS", "IMMEDIATE_EXISTING_ORGS_ONLY", "IMMEDIATE_EXISTING_AND_FUTURE_ORGS"]
        roles:
          type: array
          description: A list of roles shared across all organizations.
          items:
            $ref: '#/components/schemas/RoleWithAudience'
      example:
        userCriteria:
          userIds:
            - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
            - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"
        policy: "ALL_EXISTING_ORGS_ONLY"
        roles:
          - displayName: "role_1"
            audience:
              display: "My Org 1"
              type: "organization"
          - displayName: "role_2"
            audience:
              display: "My App 1"
              type: "application"

    UserUnshareRequestBody:
      type: object
      description: |
        The request body for unsharing users from multiple organizations.
        Includes a list of user IDs and a list of organization IDs.
      required:
        - userCriteria
        - organizations
      properties:
        userCriteria:
          type: object
          description: Contains a list of user IDs to be unshared.
          properties:
            userIds:
              type: array
              description: List of user IDs.
              items:
                type: string
                description: The ID of a user to be unshared.
        organizations:
          type: array
          description: List of organization IDs from which the users should be unshared.
          items:
            type: string
      example:
        userCriteria:
          userIds:
            - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
            - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"
        organizations:
          - "b028ca17-8f89-449c-ae27-fa955e66465d"
          - "a17b28ca-9f89-449c-ae27-fa955e66465f"

    UserUnshareWithAllRequestBody:
      type: object
      description: |
        The request body for unsharing users from all organizations.
        Includes a list of user IDs.
      required:
        - userCriteria
      properties:
        userCriteria:
          type: object
          description: Contains a list of user IDs to be unshared.
          properties:
            userIds:
              type: array
              description: List of user IDs.
              items:
                type: string
                description: The ID of a user to be unshared.
      example:
        userCriteria:
          userIds:
            - "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
            - "5d2a1c84-9f7a-43cd-b12e-6e52d7f87e16"

    UserSharedOrganizationsResponse:
      type: object
      description: |
        Response listing organizations where a user has shared access, including sharing policies, shared type and pagination links for navigating results.
      properties:
        links:
          type: array
          description: Pagination links for navigating the result set.
          items:
            type: object
            properties:
              href:
                type: string
                description: URL to navigate to the next or previous page.
              rel:
                type: string
                description: Indicates if the link is for the "next" or "previous" page.
        sharedOrganizations:
          type: array
          description: A list of shared access details for the user across multiple organizations
          items:
            type: object
            properties:
              orgId:
                type: string
                description: ID of the child organization
                example: "b028ca17-8f89-449c-ae27-fa955e66465d"
              orgName:
                type: string
                description: Name of the child organization
                example: "Organization Name"
              sharedUserId:
                type: string
                description: ID of the shared user
                example: "7a1b7d63-8cfc-4dc9-9332-3f84641b72d8"
              sharedType:
                type: string
                description: Shared type of the user (SHARED/INVITED)
                example: "SHARED"
              rolesRef:
                type: string
                description: URL reference to retrieve paginated roles for the shared user in this organization
                example: "/api/server/v1/users/{userId}/shared-roles?orgId=b028ca17-8f89-449c-ae27-fa955e66465d&after=&before=&limit=2&filter=&recursive=false"

    UserSharedRolesResponse:
      type: object
      description: |
        Response showing the roles assigned to a user within a specific organization, with pagination support for large role sets.
      properties:
        links:
          type: array
          description: Pagination links for navigating the result set.
          items:
            type: object
            properties:
              href:
                type: string
                description: URL to navigate to the next or previous page.
              rel:
                type: string
                description: Indicates if the link is for the "next" or "previous" page.
        roles:
          type: array
          description: A list of roles with audience details
          items:
            $ref: '#/components/schemas/RoleWithAudience'

    RoleWithAudience:
      type: object
      description: |
        Represents a user role within a specific audience (organization or application), defined by its display name and audience type.
      required:
        - displayName
        - audience
      properties:
        displayName:
          type: string
          description: Display name of the role
          example: "role_1"
        audience:
          type: object
          required:
            - display
            - type
          properties:
            display:
              type: string
              description: Display name of the audience
              example: "My Org 1"
            type:
              type: string
              description: Type of the audience, e.g., 'organization' or 'application'
              example: "organization"

    ProcessSuccessResponse:
      type: object
      description: |
        Indicates that the sharing or unsharing process has started successfully, with the current status and relevant details.
      properties:
        status:
          type: string
          description: Status of the process.
          example: "Processing"
        details:
          type: string
          description: Additional information about the process.
          example: "User sharing process triggered successfully."

    Error:
      type: object
      description: |
        Details of an error, including code, message, description, and a trace ID to help with debugging.
      required:
        - code
        - message
        - traceId
      properties:
        code:
          type: string
          example: "OUI-00000"
          description: An error code.
        message:
          type: string
          example: "Some Error Message"
          description: An error message.
        description:
          type: string
          example: "Some Error Description"
          description: An error description.
        traceId:
          type: string
          format: uuid
          example: "e0fbcfeb-7fc2-4b62-8b82-72d3c5fbcdeb"
          description: A trace ID in UUID format to help with debugging.
