summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNejc Habjan <hab.nejc@gmail.com>2021-05-14 22:15:18 +0200
committerGitHub <noreply@github.com>2021-05-14 22:15:18 +0200
commitf35c73e50918e4d55b70323669f394e52e75cde9 (patch)
tree8633286b906f4e8e87a3be4e86a0ad0890844de5
parentc4979a889c8aa6f0c0a5d71b45b3cde7e642b2e7 (diff)
parente444b39f9423b4a4c85cdb199afbad987df026f1 (diff)
downloadgitlab-f35c73e50918e4d55b70323669f394e52e75cde9.tar.gz
Merge pull request #1376 from Shkurupii/feat-get-inherited-members
feat: get inherited member for project/group
-rw-r--r--docs/gl_objects/groups.rst14
-rw-r--r--docs/gl_objects/projects.rst15
-rw-r--r--gitlab/mixins.py49
-rw-r--r--gitlab/v4/objects/groups.py3
-rw-r--r--gitlab/v4/objects/members.py72
-rw-r--r--gitlab/v4/objects/projects.py3
-rw-r--r--tools/functional/api/test_groups.py3
7 files changed, 97 insertions, 62 deletions
diff --git a/docs/gl_objects/groups.rst b/docs/gl_objects/groups.rst
index 1880a6b..cd8ab45 100644
--- a/docs/gl_objects/groups.rst
+++ b/docs/gl_objects/groups.rst
@@ -225,7 +225,9 @@ Reference
+ :class:`gitlab.v4.objects.GroupMember`
+ :class:`gitlab.v4.objects.GroupMemberManager`
+ + :class:`gitlab.v4.objects.GroupMemberAllManager`
+ :attr:`gitlab.v4.objects.Group.members`
+ + :attr:`gitlab.v4.objects.Group.members_all`
* GitLab API: https://docs.gitlab.com/ce/api/groups.html
@@ -233,19 +235,25 @@ Reference
Examples
--------
-List group members::
+List only direct group members::
members = group.members.list()
List the group members recursively (including inherited members through
ancestor groups)::
- members = group.members.all(all=True)
+ members = group.members_all.list(all=True)
+ # or
+ members = group.members.all(all=True) # Deprecated
-Get a group member::
+Get only direct group member::
members = group.members.get(member_id)
+Get a member of a group, including members inherited through ancestor groups::
+
+ members = group.members_all.get(member_id)
+
Add a member to the group::
member = group.members.create({'user_id': user_id,
diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst
index e61bb6a..42dbedf 100644
--- a/docs/gl_objects/projects.rst
+++ b/docs/gl_objects/projects.rst
@@ -502,30 +502,39 @@ Reference
+ :class:`gitlab.v4.objects.ProjectMember`
+ :class:`gitlab.v4.objects.ProjectMemberManager`
+ + :class:`gitlab.v4.objects.ProjectMemberAllManager`
+ :attr:`gitlab.v4.objects.Project.members`
+ + :attr:`gitlab.v4.objects.Project.members_all`
* GitLab API: https://docs.gitlab.com/ce/api/members.html
Examples
--------
-List the project members::
+List only direct project members::
members = project.members.list()
List the project members recursively (including inherited members through
ancestor groups)::
- members = project.members.all(all=True)
+ members = project.members_all.list(all=True)
+ # or
+ members = project.members.all(all=True) # Deprecated
Search project members matching a query string::
members = project.members.list(query='bar')
-Get a single project member::
+Get only direct project member::
member = project.members.get(user_id)
+Get a member of a project, including members inherited through ancestor groups::
+
+ members = project.members_all.get(member_id)
+
+
Add a project member::
member = project.members.create({'user_id': user.id, 'access_level':
diff --git a/gitlab/mixins.py b/gitlab/mixins.py
index b9026c5..a4ed9f5 100644
--- a/gitlab/mixins.py
+++ b/gitlab/mixins.py
@@ -36,7 +36,7 @@ from gitlab import cli
from gitlab import exceptions as exc
from gitlab import types as g_types
from gitlab import utils
-
+import warnings
__all__ = [
"GetMixin",
@@ -928,3 +928,50 @@ class BadgeRenderMixin(_RestManagerBase):
if TYPE_CHECKING:
assert not isinstance(result, requests.Response)
return result
+
+
+class MemberAllMixin(_RestManagerBase):
+ """This mixin is deprecated."""
+
+ _computed_path: Optional[str]
+ _from_parent_attrs: Dict[str, Any]
+ _obj_cls: Optional[Type[base.RESTObject]]
+ _parent: Optional[base.RESTObject]
+ _parent_attrs: Dict[str, Any]
+ _path: Optional[str]
+ gitlab: gitlab.Gitlab
+
+ @cli.register_custom_action(("GroupMemberManager", "ProjectMemberManager"))
+ @exc.on_http_error(exc.GitlabListError)
+ def all(self, **kwargs: Any) -> List[base.RESTObject]:
+ """List all the members, included inherited ones.
+
+ This Method is deprecated.
+
+ Args:
+ all (bool): If True, return all the items, without pagination
+ per_page (int): Number of items to retrieve per request
+ page (int): ID of the page to return (starts with page 1)
+ as_list (bool): If set to False and no pagination option is
+ defined, return a generator instead of a list
+ **kwargs: Extra options to send to the server (e.g. sudo)
+
+ Raises:
+ GitlabAuthenticationError: If authentication is not correct
+ GitlabListError: If the list could not be retrieved
+
+ Returns:
+ RESTObjectList: The list of members
+ """
+
+ warnings.warn(
+ "The all() method for this object is deprecated "
+ "and will be removed in a future version.",
+ DeprecationWarning,
+ )
+ path = "%s/all" % self.path
+
+ if TYPE_CHECKING:
+ assert self._obj_cls is not None
+ obj = self.gitlab.http_list(path, **kwargs)
+ return [self._obj_cls(self, item) for item in obj]
diff --git a/gitlab/v4/objects/groups.py b/gitlab/v4/objects/groups.py
index 9e27601..574c57b 100644
--- a/gitlab/v4/objects/groups.py
+++ b/gitlab/v4/objects/groups.py
@@ -11,7 +11,7 @@ from .export_import import GroupExportManager, GroupImportManager # noqa: F401
from .epics import GroupEpicManager # noqa: F401
from .issues import GroupIssueManager # noqa: F401
from .labels import GroupLabelManager # noqa: F401
-from .members import GroupMemberManager # noqa: F401
+from .members import GroupMemberManager, GroupMemberAllManager # noqa: F401
from .merge_requests import GroupMergeRequestManager # noqa: F401
from .milestones import GroupMilestoneManager # noqa: F401
from .notification_settings import GroupNotificationSettingsManager # noqa: F401
@@ -45,6 +45,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
("issues", "GroupIssueManager"),
("labels", "GroupLabelManager"),
("members", "GroupMemberManager"),
+ ("members_all", "GroupMemberAllManager"),
("mergerequests", "GroupMergeRequestManager"),
("milestones", "GroupMilestoneManager"),
("notificationsettings", "GroupNotificationSettingsManager"),
diff --git a/gitlab/v4/objects/members.py b/gitlab/v4/objects/members.py
index 2686587..839c89e 100644
--- a/gitlab/v4/objects/members.py
+++ b/gitlab/v4/objects/members.py
@@ -1,14 +1,20 @@
-from gitlab import cli, types
-from gitlab import exceptions as exc
+from gitlab import types
from gitlab.base import RequiredOptional, RESTManager, RESTObject
-from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
-
+from gitlab.mixins import (
+ CRUDMixin,
+ ObjectDeleteMixin,
+ SaveMixin,
+ RetrieveMixin,
+ MemberAllMixin,
+)
__all__ = [
"GroupMember",
"GroupMemberManager",
+ "GroupMemberAllManager",
"ProjectMember",
"ProjectMemberManager",
+ "ProjectMemberAllManager",
]
@@ -16,7 +22,7 @@ class GroupMember(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
-class GroupMemberManager(CRUDMixin, RESTManager):
+class GroupMemberManager(MemberAllMixin, CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/members"
_obj_cls = GroupMember
_from_parent_attrs = {"group_id": "id"}
@@ -28,37 +34,18 @@ class GroupMemberManager(CRUDMixin, RESTManager):
)
_types = {"user_ids": types.ListAttribute}
- @cli.register_custom_action("GroupMemberManager")
- @exc.on_http_error(exc.GitlabListError)
- def all(self, **kwargs):
- """List all the members, included inherited ones.
-
- Args:
- all (bool): If True, return all the items, without pagination
- per_page (int): Number of items to retrieve per request
- page (int): ID of the page to return (starts with page 1)
- as_list (bool): If set to False and no pagination option is
- defined, return a generator instead of a list
- **kwargs: Extra options to send to the server (e.g. sudo)
-
- Raises:
- GitlabAuthenticationError: If authentication is not correct
- GitlabListError: If the list could not be retrieved
- Returns:
- RESTObjectList: The list of members
- """
-
- path = "%s/all" % self.path
- obj = self.gitlab.http_list(path, **kwargs)
- return [self._obj_cls(self, item) for item in obj]
+class GroupMemberAllManager(RetrieveMixin, RESTManager):
+ _path = "/groups/%(group_id)s/members/all"
+ _obj_cls = GroupMember
+ _from_parent_attrs = {"group_id": "id"}
class ProjectMember(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
-class ProjectMemberManager(CRUDMixin, RESTManager):
+class ProjectMemberManager(MemberAllMixin, CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/members"
_obj_cls = ProjectMember
_from_parent_attrs = {"project_id": "id"}
@@ -70,27 +57,8 @@ class ProjectMemberManager(CRUDMixin, RESTManager):
)
_types = {"user_ids": types.ListAttribute}
- @cli.register_custom_action("ProjectMemberManager")
- @exc.on_http_error(exc.GitlabListError)
- def all(self, **kwargs):
- """List all the members, included inherited ones.
- Args:
- all (bool): If True, return all the items, without pagination
- per_page (int): Number of items to retrieve per request
- page (int): ID of the page to return (starts with page 1)
- as_list (bool): If set to False and no pagination option is
- defined, return a generator instead of a list
- **kwargs: Extra options to send to the server (e.g. sudo)
-
- Raises:
- GitlabAuthenticationError: If authentication is not correct
- GitlabListError: If the list could not be retrieved
-
- Returns:
- RESTObjectList: The list of members
- """
-
- path = "%s/all" % self.path
- obj = self.gitlab.http_list(path, **kwargs)
- return [self._obj_cls(self, item) for item in obj]
+class ProjectMemberAllManager(RetrieveMixin, RESTManager):
+ _path = "/projects/%(project_id)s/members/all"
+ _obj_cls = ProjectMember
+ _from_parent_attrs = {"project_id": "id"}
diff --git a/gitlab/v4/objects/projects.py b/gitlab/v4/objects/projects.py
index 4618292..4223b18 100644
--- a/gitlab/v4/objects/projects.py
+++ b/gitlab/v4/objects/projects.py
@@ -32,7 +32,7 @@ from .hooks import ProjectHookManager # noqa: F401
from .issues import ProjectIssueManager # noqa: F401
from .jobs import ProjectJobManager # noqa: F401
from .labels import ProjectLabelManager # noqa: F401
-from .members import ProjectMemberManager # noqa: F401
+from .members import ProjectMemberManager, ProjectMemberAllManager # noqa: F401
from .merge_request_approvals import ( # noqa: F401
ProjectApprovalManager,
ProjectApprovalRuleManager,
@@ -130,6 +130,7 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO
("issues", "ProjectIssueManager"),
("labels", "ProjectLabelManager"),
("members", "ProjectMemberManager"),
+ ("members_all", "ProjectMemberAllManager"),
("mergerequests", "ProjectMergeRequestManager"),
("milestones", "ProjectMilestoneManager"),
("notes", "ProjectNoteManager"),
diff --git a/tools/functional/api/test_groups.py b/tools/functional/api/test_groups.py
index c44c175..eae2d9b 100644
--- a/tools/functional/api/test_groups.py
+++ b/tools/functional/api/test_groups.py
@@ -88,7 +88,8 @@ def test_groups(gl):
group1.members.delete(user.id)
assert len(group1.members.list()) == 2
- assert len(group1.members.all())
+ assert len(group1.members.all()) # Deprecated
+ assert len(group1.members_all.list())
member = group1.members.get(user2.id)
member.access_level = gitlab.const.OWNER_ACCESS
member.save()