diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 6c5ab83507..88b9510c26 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -81529,55 +81529,57 @@ components: description: Attributes of user object returned by the API. properties: created_at: - description: Creation time of the user. + description: The ISO 8601 timestamp of when the user account was created. format: date-time type: string disabled: - description: Whether the user is disabled. + description: Whether the user account is deactivated. Disabled users cannot log in. type: boolean email: - description: Email of the user. + description: The email address of the user, used for login and notifications. type: string handle: - description: Handle of the user. + description: The unique handle (username) of the user, typically matching their email prefix. type: string icon: - description: URL of the user's icon. + description: URL of the user's profile icon, typically a Gravatar URL derived from the email address. type: string last_login_time: - description: The last time the user logged in. + description: The ISO 8601 timestamp of the user's most recent login, or null if the user has never logged in. format: date-time nullable: true readOnly: true type: string mfa_enabled: - description: If user has MFA enabled. + description: Whether multi-factor authentication (MFA) is enabled for the user's account. readOnly: true type: boolean modified_at: - description: Time that the user was last modified. + description: The ISO 8601 timestamp of when the user account was last modified. format: date-time type: string name: - description: Name of the user. + description: The full display name of the user as shown in the Datadog UI. nullable: true type: string service_account: - description: Whether the user is a service account. + description: |- + Whether this is a service account rather than a human user. + Service accounts are used for programmatic API access. type: boolean status: - description: Status of the user. + description: The current status of the user account (for example, `Active`, `Pending`, or `Disabled`). type: string title: - description: Title of the user. + description: The job title of the user (for example, "Senior Engineer" or "Product Manager"). nullable: true type: string uuid: - description: UUID of the user. + description: The globally unique identifier (UUID) of the user. readOnly: true type: string verified: - description: Whether the user is verified. + description: Whether the user's email address has been verified. type: boolean type: object UserAttributesStatus: @@ -81979,13 +81981,23 @@ components: description: Attributes of the edited user. properties: disabled: - description: If the user is enabled or disabled. + description: |- + When set to `true`, the user is deactivated and can no longer log in. + When `false`, the user is active. type: boolean email: - description: The email of the user. + description: |- + The email address of the user, used for login and notifications. + Must be a valid email format. type: string name: - description: The name of the user. + description: |- + The full display name of the user as shown in the Datadog UI. + Maximum 55 characters, cannot contain `<` or `>`. + type: string + title: + description: The job title of the user (for example, "Senior Engineer" or "Product Manager"). + nullable: true type: string type: object UserUpdateData: @@ -96714,6 +96726,144 @@ paths: $ref: "#/components/responses/TooManyRequestsResponse" summary: Get all CSM Serverless Agents tags: ["CSM Agents"] + /api/v2/current_user: + get: + description: |- + Get the user associated with the current authentication context. + The response includes the user's profile attributes (name, email, handle, + status, MFA state), along with related resources: the user's organization, + assigned roles with their granted permissions, and team-scoped roles. + No additional permissions are required beyond valid authentication. + operationId: GetCurrentUser + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + created_at: "2024-01-15T10:30:00+00:00" + disabled: false + email: jane.doe@example.com + handle: jane.doe + icon: "https://secure.gravatar.com/avatar/abc123" + mfa_enabled: true + modified_at: "2024-06-01T12:00:00+00:00" + name: Jane Doe + service_account: false + status: Active + title: Senior Engineer + verified: true + id: 00000000-0000-9999-0000-000000000000 + type: users + included: [] + schema: + $ref: "#/components/schemas/UserResponse" + description: OK + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Authentication error + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Get current user + tags: + - Users + patch: + description: |- + Edit the profile of the currently authenticated user. Updatable fields + include `name`, `title`, `email`, and `disabled` status. The `id` field + in the request body must match the authenticated user's UUID; a mismatch + returns a 422 error. Email address changes are recorded in the audit trail. + Requires the `user_access_manage` permission. + operationId: UpdateCurrentUser + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + email: jane.doe@example.com + name: Jane Doe + title: Staff Engineer + id: 00000000-0000-9999-0000-000000000000 + type: users + schema: + $ref: "#/components/schemas/UserUpdateRequest" + required: true + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + created_at: "2024-01-15T10:30:00+00:00" + disabled: false + email: jane.doe@example.com + handle: jane.doe + icon: "https://secure.gravatar.com/avatar/abc123" + mfa_enabled: true + modified_at: "2024-06-01T12:00:00+00:00" + name: Jane Doe + service_account: false + status: Active + title: Staff Engineer + verified: true + id: 00000000-0000-9999-0000-000000000000 + type: users + included: [] + schema: + $ref: "#/components/schemas/UserResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Bad Request + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Authentication error + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Not found + "422": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Unprocessable Entity + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Update current user + tags: + - Users + x-codegen-request-body-name: body + "x-permission": + operator: OR + permissions: + - user_access_manage /api/v2/current_user/application_keys: get: description: List all application keys available for current user diff --git a/examples/v2/users/GetCurrentUser.py b/examples/v2/users/GetCurrentUser.py new file mode 100644 index 0000000000..8b2242bf58 --- /dev/null +++ b/examples/v2/users/GetCurrentUser.py @@ -0,0 +1,13 @@ +""" +Get current user returns "OK" response +""" + +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.users_api import UsersApi + +configuration = Configuration() +with ApiClient(configuration) as api_client: + api_instance = UsersApi(api_client) + response = api_instance.get_current_user() + + print(response) diff --git a/examples/v2/users/UpdateCurrentUser.py b/examples/v2/users/UpdateCurrentUser.py new file mode 100644 index 0000000000..990ee6ba12 --- /dev/null +++ b/examples/v2/users/UpdateCurrentUser.py @@ -0,0 +1,27 @@ +""" +Update current user returns "OK" response +""" + +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.users_api import UsersApi +from datadog_api_client.v2.model.user_update_attributes import UserUpdateAttributes +from datadog_api_client.v2.model.user_update_data import UserUpdateData +from datadog_api_client.v2.model.user_update_request import UserUpdateRequest +from datadog_api_client.v2.model.users_type import UsersType + +body = UserUpdateRequest( + data=UserUpdateData( + attributes=UserUpdateAttributes( + title=None, + ), + id="00000000-0000-feed-0000-000000000000", + type=UsersType.USERS, + ), +) + +configuration = Configuration() +with ApiClient(configuration) as api_client: + api_instance = UsersApi(api_client) + response = api_instance.update_current_user(body=body) + + print(response) diff --git a/src/datadog_api_client/v2/api/users_api.py b/src/datadog_api_client/v2/api/users_api.py index 313cb17a72..7ef1bc7fe4 100644 --- a/src/datadog_api_client/v2/api/users_api.py +++ b/src/datadog_api_client/v2/api/users_api.py @@ -17,15 +17,15 @@ ) from datadog_api_client.v2.model.anonymize_users_response import AnonymizeUsersResponse from datadog_api_client.v2.model.anonymize_users_request import AnonymizeUsersRequest +from datadog_api_client.v2.model.user_response import UserResponse +from datadog_api_client.v2.model.user_update_request import UserUpdateRequest from datadog_api_client.v2.model.user_invitations_response import UserInvitationsResponse from datadog_api_client.v2.model.user_invitations_request import UserInvitationsRequest from datadog_api_client.v2.model.user_invitation_response import UserInvitationResponse from datadog_api_client.v2.model.users_response import UsersResponse from datadog_api_client.v2.model.query_sort_order import QuerySortOrder from datadog_api_client.v2.model.user import User -from datadog_api_client.v2.model.user_response import UserResponse from datadog_api_client.v2.model.user_create_request import UserCreateRequest -from datadog_api_client.v2.model.user_update_request import UserUpdateRequest from datadog_api_client.v2.model.permissions_response import PermissionsResponse @@ -125,6 +125,22 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._get_current_user_endpoint = _Endpoint( + settings={ + "response_type": (UserResponse,), + "auth": ["apiKeyAuth", "appKeyAuth"], + "endpoint_path": "/api/v2/current_user", + "operation_id": "get_current_user", + "http_method": "GET", + "version": "v2", + }, + params_map={}, + headers_map={ + "accept": ["application/json"], + }, + api_client=api_client, + ) + self._get_invitation_endpoint = _Endpoint( settings={ "response_type": (UserInvitationResponse,), @@ -284,6 +300,26 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._update_current_user_endpoint = _Endpoint( + settings={ + "response_type": (UserResponse,), + "auth": ["apiKeyAuth", "appKeyAuth"], + "endpoint_path": "/api/v2/current_user", + "operation_id": "update_current_user", + "http_method": "PATCH", + "version": "v2", + }, + params_map={ + "body": { + "required": True, + "openapi_types": (UserUpdateRequest,), + "location": "body", + }, + }, + headers_map={"accept": ["application/json"], "content_type": ["application/json"]}, + api_client=api_client, + ) + self._update_user_endpoint = _Endpoint( settings={ "response_type": (UserResponse,), @@ -379,6 +415,22 @@ def disable_user( return self._disable_user_endpoint.call_with_http_info(**kwargs) + def get_current_user( + self, + ) -> UserResponse: + """Get current user. + + Get the user associated with the current authentication context. + The response includes the user's profile attributes (name, email, handle, + status, MFA state), along with related resources: the user's organization, + assigned roles with their granted permissions, and team-scoped roles. + No additional permissions are required beyond valid authentication. + + :rtype: UserResponse + """ + kwargs: Dict[str, Any] = {} + return self._get_current_user_endpoint.call_with_http_info(**kwargs) + def get_invitation( self, user_invitation_uuid: str, @@ -587,6 +639,26 @@ def send_invitations( return self._send_invitations_endpoint.call_with_http_info(**kwargs) + def update_current_user( + self, + body: UserUpdateRequest, + ) -> UserResponse: + """Update current user. + + Edit the profile of the currently authenticated user. Updatable fields + include ``name`` , ``title`` , ``email`` , and ``disabled`` status. The ``id`` field + in the request body must match the authenticated user's UUID; a mismatch + returns a 422 error. Email address changes are recorded in the audit trail. + Requires the ``user_access_manage`` permission. + + :type body: UserUpdateRequest + :rtype: UserResponse + """ + kwargs: Dict[str, Any] = {} + kwargs["body"] = body + + return self._update_current_user_endpoint.call_with_http_info(**kwargs) + def update_user( self, user_id: str, diff --git a/src/datadog_api_client/v2/model/user_attributes.py b/src/datadog_api_client/v2/model/user_attributes.py index 771ce371ad..afd575639b 100644 --- a/src/datadog_api_client/v2/model/user_attributes.py +++ b/src/datadog_api_client/v2/model/user_attributes.py @@ -78,46 +78,47 @@ def __init__( """ Attributes of user object returned by the API. - :param created_at: Creation time of the user. + :param created_at: The ISO 8601 timestamp of when the user account was created. :type created_at: datetime, optional - :param disabled: Whether the user is disabled. + :param disabled: Whether the user account is deactivated. Disabled users cannot log in. :type disabled: bool, optional - :param email: Email of the user. + :param email: The email address of the user, used for login and notifications. :type email: str, optional - :param handle: Handle of the user. + :param handle: The unique handle (username) of the user, typically matching their email prefix. :type handle: str, optional - :param icon: URL of the user's icon. + :param icon: URL of the user's profile icon, typically a Gravatar URL derived from the email address. :type icon: str, optional - :param last_login_time: The last time the user logged in. + :param last_login_time: The ISO 8601 timestamp of the user's most recent login, or null if the user has never logged in. :type last_login_time: datetime, none_type, optional - :param mfa_enabled: If user has MFA enabled. + :param mfa_enabled: Whether multi-factor authentication (MFA) is enabled for the user's account. :type mfa_enabled: bool, optional - :param modified_at: Time that the user was last modified. + :param modified_at: The ISO 8601 timestamp of when the user account was last modified. :type modified_at: datetime, optional - :param name: Name of the user. + :param name: The full display name of the user as shown in the Datadog UI. :type name: str, none_type, optional - :param service_account: Whether the user is a service account. + :param service_account: Whether this is a service account rather than a human user. + Service accounts are used for programmatic API access. :type service_account: bool, optional - :param status: Status of the user. + :param status: The current status of the user account (for example, ``Active`` , ``Pending`` , or ``Disabled`` ). :type status: str, optional - :param title: Title of the user. + :param title: The job title of the user (for example, "Senior Engineer" or "Product Manager"). :type title: str, none_type, optional - :param uuid: UUID of the user. + :param uuid: The globally unique identifier (UUID) of the user. :type uuid: str, optional - :param verified: Whether the user is verified. + :param verified: Whether the user's email address has been verified. :type verified: bool, optional """ if created_at is not unset: diff --git a/src/datadog_api_client/v2/model/user_update_attributes.py b/src/datadog_api_client/v2/model/user_update_attributes.py index 6ef0277ffa..2f2a07d75a 100644 --- a/src/datadog_api_client/v2/model/user_update_attributes.py +++ b/src/datadog_api_client/v2/model/user_update_attributes.py @@ -8,6 +8,7 @@ from datadog_api_client.model_utils import ( ModelNormal, cached_property, + none_type, unset, UnsetType, ) @@ -20,12 +21,14 @@ def openapi_types(_): "disabled": (bool,), "email": (str,), "name": (str,), + "title": (str, none_type), } attribute_map = { "disabled": "disabled", "email": "email", "name": "name", + "title": "title", } def __init__( @@ -33,19 +36,26 @@ def __init__( disabled: Union[bool, UnsetType] = unset, email: Union[str, UnsetType] = unset, name: Union[str, UnsetType] = unset, + title: Union[str, none_type, UnsetType] = unset, **kwargs, ): """ Attributes of the edited user. - :param disabled: If the user is enabled or disabled. + :param disabled: When set to ``true`` , the user is deactivated and can no longer log in. + When ``false`` , the user is active. :type disabled: bool, optional - :param email: The email of the user. + :param email: The email address of the user, used for login and notifications. + Must be a valid email format. :type email: str, optional - :param name: The name of the user. + :param name: The full display name of the user as shown in the Datadog UI. + Maximum 55 characters, cannot contain ``<`` or ``>``. :type name: str, optional + + :param title: The job title of the user (for example, "Senior Engineer" or "Product Manager"). + :type title: str, none_type, optional """ if disabled is not unset: kwargs["disabled"] = disabled @@ -53,4 +63,6 @@ def __init__( kwargs["email"] = email if name is not unset: kwargs["name"] = name + if title is not unset: + kwargs["title"] = title super().__init__(kwargs) diff --git a/tests/v2/features/undo.json b/tests/v2/features/undo.json index a3e509a0bc..72f55d80bc 100644 --- a/tests/v2/features/undo.json +++ b/tests/v2/features/undo.json @@ -1506,6 +1506,19 @@ "type": "safe" } }, + "GetCurrentUser": { + "tag": "Users", + "undo": { + "type": "safe" + } + }, + "UpdateCurrentUser": { + "tag": "Users", + "undo": { + "operationId": "GetCurrentUser", + "type": "idempotent" + } + }, "ListCurrentUserApplicationKeys": { "tag": "Key Management", "undo": { diff --git a/tests/v2/features/users.feature b/tests/v2/features/users.feature index 2fee7ffedc..9d9fa48963 100644 --- a/tests/v2/features/users.feature +++ b/tests/v2/features/users.feature @@ -118,6 +118,12 @@ Feature: Users Then the response status is 200 OK And the response "data" has length 0 + @generated @skip @team:DataDog/org-management + Scenario: Get current user returns "OK" response + Given new "GetCurrentUser" request + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/org-management Scenario: Get user details returns "Not found" response Given new "GetUser" request @@ -181,7 +187,7 @@ Feature: Users Scenario: Update a user returns "Bad Request" response Given new "UpdateUser" request And request contains "user_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} + And body with value {"data": {"attributes": {"title": null}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} When the request is sent Then the response status is 400 Bad Request @@ -219,6 +225,34 @@ Feature: Users Scenario: Update a user returns "Unprocessable Entity" response Given new "UpdateUser" request And request contains "user_id" parameter from "REPLACE.ME" - And body with value {"data": {"attributes": {}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} + And body with value {"data": {"attributes": {"title": null}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} + When the request is sent + Then the response status is 422 Unprocessable Entity + + @generated @skip @team:DataDog/org-management + Scenario: Update current user returns "Bad Request" response + Given new "UpdateCurrentUser" request + And body with value {"data": {"attributes": {"title": null}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/org-management + Scenario: Update current user returns "Not found" response + Given new "UpdateCurrentUser" request + And body with value {"data": {"attributes": {"title": null}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} + When the request is sent + Then the response status is 404 Not found + + @generated @skip @team:DataDog/org-management + Scenario: Update current user returns "OK" response + Given new "UpdateCurrentUser" request + And body with value {"data": {"attributes": {"title": null}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} + When the request is sent + Then the response status is 200 OK + + @generated @skip @team:DataDog/org-management + Scenario: Update current user returns "Unprocessable Entity" response + Given new "UpdateCurrentUser" request + And body with value {"data": {"attributes": {"title": null}, "id": "00000000-0000-feed-0000-000000000000", "type": "users"}} When the request is sent Then the response status is 422 Unprocessable Entity