|
17 | 17 | DatabaseDeleteError,
|
18 | 18 | DatabaseListError,
|
19 | 19 | ServerStatusError,
|
| 20 | + UserCreateError, |
| 21 | + UserDeleteError, |
| 22 | + UserGetError, |
| 23 | + UserListError, |
20 | 24 | )
|
21 | 25 | from arangoasync.executor import ApiExecutor, DefaultApiExecutor
|
22 | 26 | from arangoasync.request import Method, Request
|
@@ -553,6 +557,164 @@ def response_handler(resp: Response) -> bool:
|
553 | 557 |
|
554 | 558 | return await self._executor.execute(request, response_handler)
|
555 | 559 |
|
| 560 | + async def has_user(self, username: str) -> Result[bool]: |
| 561 | + """Check if a user exists. |
| 562 | +
|
| 563 | + Args: |
| 564 | + username (str): Username. |
| 565 | +
|
| 566 | + Returns: |
| 567 | + bool: True if the user exists, False otherwise. |
| 568 | +
|
| 569 | + Raises: |
| 570 | + UserListError: If the operation fails. |
| 571 | + """ |
| 572 | + request = Request(method=Method.GET, endpoint=f"/_api/user/{username}") |
| 573 | + |
| 574 | + def response_handler(resp: Response) -> bool: |
| 575 | + if resp.is_success: |
| 576 | + return True |
| 577 | + if resp.status_code == HTTP_NOT_FOUND: |
| 578 | + return False |
| 579 | + raise UserListError(resp, request) |
| 580 | + |
| 581 | + return await self._executor.execute(request, response_handler) |
| 582 | + |
| 583 | + async def user(self, username: str) -> Result[UserInfo]: |
| 584 | + """Fetches data about a user. |
| 585 | +
|
| 586 | + Args: |
| 587 | + username (str): Username. |
| 588 | +
|
| 589 | + Returns: |
| 590 | + UserInfo: User details. |
| 591 | +
|
| 592 | + Raises: |
| 593 | + UserGetError: If the operation fails. |
| 594 | +
|
| 595 | + References: |
| 596 | + - `get-a-user` <https://docs.arangodb.com/stable/develop/http-api/users/#get-a-user>`__ |
| 597 | + """ # noqa: E501 |
| 598 | + request = Request(method=Method.GET, endpoint=f"/_api/user/{username}") |
| 599 | + |
| 600 | + def response_handler(resp: Response) -> UserInfo: |
| 601 | + if not resp.is_success: |
| 602 | + raise UserGetError(resp, request) |
| 603 | + body = self.deserializer.loads(resp.raw_body) |
| 604 | + return UserInfo( |
| 605 | + user=body["user"], |
| 606 | + active=cast(bool, body.get("active")), |
| 607 | + extra=body.get("extra"), |
| 608 | + ) |
| 609 | + |
| 610 | + return await self._executor.execute(request, response_handler) |
| 611 | + |
| 612 | + async def users(self) -> Result[Sequence[UserInfo]]: |
| 613 | + """Fetches data about all users. |
| 614 | +
|
| 615 | + Without the necessary permissions, you might only get data about the |
| 616 | + current user. |
| 617 | +
|
| 618 | + Returns: |
| 619 | + list: User information. |
| 620 | +
|
| 621 | + Raises: |
| 622 | + UserListError: If the operation fails. |
| 623 | +
|
| 624 | + References: |
| 625 | + - `list-available-users <https://docs.arangodb.com/stable/develop/http-api/users/#list-available-users>`__ |
| 626 | + """ # noqa: E501 |
| 627 | + request = Request(method=Method.GET, endpoint="/_api/user") |
| 628 | + |
| 629 | + def response_handler(resp: Response) -> Sequence[UserInfo]: |
| 630 | + if not resp.is_success: |
| 631 | + raise UserListError(resp, request) |
| 632 | + body = self.deserializer.loads(resp.raw_body) |
| 633 | + return [ |
| 634 | + UserInfo(user=u["user"], active=u.get("active"), extra=u.get("extra")) |
| 635 | + for u in body["result"] |
| 636 | + ] |
| 637 | + |
| 638 | + return await self._executor.execute(request, response_handler) |
| 639 | + |
| 640 | + async def create_user( |
| 641 | + self, |
| 642 | + user: UserInfo, |
| 643 | + ) -> Result[UserInfo]: |
| 644 | + """Create a new user. |
| 645 | +
|
| 646 | + Args: |
| 647 | + user (UserInfo): User information. |
| 648 | +
|
| 649 | + Returns: |
| 650 | + UserInfo: New user details. |
| 651 | +
|
| 652 | + Raises: |
| 653 | + ValueError: If the username is missing. |
| 654 | + UserCreateError: If the operation fails. |
| 655 | +
|
| 656 | + Example: |
| 657 | + .. code-block:: python |
| 658 | +
|
| 659 | + await db.create_user(UserInfo(user="john", password="secret")) |
| 660 | +
|
| 661 | + References: |
| 662 | + - `create-a-user <https://docs.arangodb.com/stable/develop/http-api/users/#create-a-user>`__ |
| 663 | + """ # noqa: E501 |
| 664 | + if not user.user: |
| 665 | + raise ValueError("Username is required.") |
| 666 | + |
| 667 | + data: Json = user.to_dict() |
| 668 | + request = Request( |
| 669 | + method=Method.POST, |
| 670 | + endpoint="/_api/user", |
| 671 | + data=self.serializer.dumps(data), |
| 672 | + ) |
| 673 | + |
| 674 | + def response_handler(resp: Response) -> UserInfo: |
| 675 | + if not resp.is_success: |
| 676 | + raise UserCreateError(resp, request) |
| 677 | + body = self.deserializer.loads(resp.raw_body) |
| 678 | + return UserInfo( |
| 679 | + user=body["user"], |
| 680 | + active=cast(bool, body.get("active")), |
| 681 | + extra=body.get("extra"), |
| 682 | + ) |
| 683 | + |
| 684 | + return await self._executor.execute(request, response_handler) |
| 685 | + |
| 686 | + async def delete_user( |
| 687 | + self, |
| 688 | + username: str, |
| 689 | + ignore_missing: bool = False, |
| 690 | + ) -> Result[bool]: |
| 691 | + """Delete a user. |
| 692 | +
|
| 693 | + Args: |
| 694 | + username (str): Username. |
| 695 | + ignore_missing (bool): Do not raise an exception on missing user. |
| 696 | +
|
| 697 | + Returns: |
| 698 | + bool: True if the user was deleted successfully, `False` if the user was |
| 699 | + not found but **ignore_missing** was set to `True`. |
| 700 | +
|
| 701 | + Raises: |
| 702 | + UserDeleteError: If the operation fails. |
| 703 | +
|
| 704 | + References: |
| 705 | + - `remove-a-user <https://docs.arangodb.com/stable/develop/http-api/users/#remove-a-user>`__ |
| 706 | + """ # noqa: E501 |
| 707 | + request = Request(method=Method.DELETE, endpoint=f"/_api/user/{username}") |
| 708 | + |
| 709 | + def response_handler(resp: Response) -> bool: |
| 710 | + if resp.is_success: |
| 711 | + return True |
| 712 | + if resp.status_code == HTTP_NOT_FOUND and ignore_missing: |
| 713 | + return False |
| 714 | + raise UserDeleteError(resp, request) |
| 715 | + |
| 716 | + return await self._executor.execute(request, response_handler) |
| 717 | + |
556 | 718 |
|
557 | 719 | class StandardDatabase(Database):
|
558 | 720 | """Standard database API wrapper."""
|
|
0 commit comments