Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8108ed6
fix: get_all_server_groups returning all server for admin user in ser…
Jun 2, 2026
cdb686b
fix: class ServerGroupView get_all_server_groups
Jun 2, 2026
634c7d8
feat: Configuration for ADMIN see or not servers of all users
Jun 3, 2026
a57892d
fix: use get_all_server_groups to retrive groups in getnodes
Jun 3, 2026
96f1ed5
refactor: Refactoring get_servers_from_group as sugested
Jun 3, 2026
e79034c
fix: Adjust relationship between ServerGroup and Server
Jun 3, 2026
e226406
fix: Fix N+1 shared-server lookup
Jun 3, 2026
0181a09
Adjust get_nodes() to grant to not allow delete for the first owned …
Jun 3, 2026
d00a8ce
chore: Enforce comment that admin can see all servers and groups
Jun 3, 2026
5c494ec
Fix (#9917)
sbraaa Jun 5, 2026
27406b5
fix: fixed invalid '| None' syntax for python 3.9 (#9993)
jasparm Jun 5, 2026
2dc9d71
fix(webpack): alias react-checkbox-tree to its ESM bundle (#9989)
dpage Jun 5, 2026
679c39f
fix: resolve E501 pycodestyle line-too-long in llm tools database mod…
hiteshjambhale Jun 5, 2026
44a1a2c
fix: get_all_server_groups returning all server for admin user in ser…
Jun 2, 2026
802abc4
fix: class ServerGroupView get_all_server_groups
Jun 2, 2026
5ac036c
feat: Configuration for ADMIN see or not servers of all users
Jun 3, 2026
7f81ccb
fix: use get_all_server_groups to retrive groups in getnodes
Jun 3, 2026
2ad8768
refactor: Refactoring get_servers_from_group as sugested
Jun 3, 2026
4560cad
fix: Adjust relationship between ServerGroup and Server
Jun 3, 2026
3c9cf33
fix: Fix N+1 shared-server lookup
Jun 3, 2026
19eb8a3
Adjust get_nodes() to grant to not allow delete for the first owned …
Jun 3, 2026
297d07c
chore: Enforce comment that admin can see all servers and groups
Jun 3, 2026
0ca99cf
feat: Enforce order im get_all_server_groups
Jun 3, 2026
5a2b314
Merge branch 'fix-get_all_server_groups' of https://github.com/lkmats…
Jun 5, 2026
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
6 changes: 6 additions & 0 deletions web/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@
# "Unauthorised use is strictly forbidden."
LOGIN_BANNER = ""

##########################################################################
# Admin options
##########################################################################
ADMIN_CAN_SEE_ALL_SERVERS = False


##########################################################################
# Log settings
##########################################################################
Expand Down
41 changes: 27 additions & 14 deletions web/pgadmin/browser/server_groups/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
import config
from pgadmin.utils.preferences import Preferences
from pgadmin.utils.server_access import get_server_group, \
get_server_groups_for_user
get_server_groups_for_user, \
get_servers_from_group


def get_icon_css_class(group_id, group_user_id,
Expand Down Expand Up @@ -69,14 +70,35 @@ def csssnippets(self):
@staticmethod
def has_shared_server(gid):
"""
To check whether given server group contains shared server or not
To check whether given server group contains shared servers
:param gid:
:return: True if servergroup contains shared server else false
:return: True if servergroup contains shared servers else false
"""
servers = Server.query.filter_by(servergroup_id=gid)
pref = Preferences.module('browser')
hide_shared_server = pref.preference('hide_shared_server').get()

servers = get_servers_from_group(gid, hide_shared_server)
for s in servers:
if s.shared:
return True

return False

@staticmethod
def has_not_shared_server(gid):
"""
To check whether given server group contains NOT shared servers
:param gid:
:return: True if servergroup contains NOT shared servers else false
"""
pref = Preferences.module('browser')
hide_shared_server = pref.preference('hide_shared_server').get()

servers = get_servers_from_group(gid, hide_shared_server)
for s in servers:
if not s.shared:
return True

return False

def get_nodes(self, *arg, **kwargs):
Expand Down Expand Up @@ -387,16 +409,7 @@ def get_all_server_groups():
pref = Preferences.module('browser')
hide_shared_server = pref.preference('hide_shared_server').get()

server_groups = get_server_groups_for_user()

if hide_shared_server:
groups = []
for group in server_groups:
if group.user_id != current_user.id and \
ServerGroupModule.has_shared_server(group.id):
continue
groups.append(group)
return groups
server_groups = get_server_groups_for_user( only_owned=hide_shared_server).all()

return server_groups
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

Expand Down
2 changes: 2 additions & 0 deletions web/pgadmin/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ class ServerGroup(db.Model, UserScopedMixin):
name = db.Column(db.String(128), nullable=False)
__table_args__ = (db.UniqueConstraint('user_id', 'name'),)

servers = db.relationship('Server', backref='servergroup', lazy='select')
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

@property
def serialize(self):
"""Return object data in easily serializable format"""
Expand Down
80 changes: 40 additions & 40 deletions web/pgadmin/utils/server_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def get_server(sid, only_owned=False):
if not config.SERVER_MODE:
return Server.query.filter_by(id=sid).first()

# Administrators can access all servers if ADMIN_CAN_SEE_ALL_SERVERS is True
if _is_admin() and config.ADMIN_CAN_SEE_ALL_SERVERS:
return Server.query.filter_by(id=sid).first()

if only_owned:
return Server.query.filter_by(
id=sid, user_id=current_user.id).first()
Expand All @@ -64,17 +68,25 @@ def get_server(sid, only_owned=False):
)
).first()

if server is not None:
return server
return server

# Administrators can access all servers
if _is_admin():
return Server.query.filter_by(id=sid).first()

return None
def get_servers_from_group(gid, only_owned=False):
"""Fetch servers from a group

Args:
gid: Server group ID.
only_owned: If True, only return servers owned by the current
user.
"""
if only_owned:
return Server.query.filter_by(
servergroup_id=gid, user_id=current_user.id)

return Server.query.filter_by(servergroup_id=gid)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated


def get_server_group(gid):
def get_server_group(gid,only_owned=False):
"""Fetch a server group by ID, verifying user access.

Returns the group if:
Expand All @@ -88,64 +100,52 @@ def get_server_group(gid):
if not config.SERVER_MODE:
return ServerGroup.query.filter_by(id=gid).first()

sg = ServerGroup.query.filter(
ServerGroup.id == gid,
or_(
ServerGroup.user_id == current_user.id,
ServerGroup.id.in_(
db.session.query(Server.servergroup_id).filter(
Server.shared
)
)
)
).first()

if sg is not None:
return sg

if _is_admin():
if _is_admin() and config.ADMIN_CAN_SEE_ALL_SERVERS:
return ServerGroup.query.filter_by(id=gid).first()
Comment thread
lkmatsumura marked this conversation as resolved.

return None
sg = get_server_groups_for_user(only_owned=only_owned).filter_by(id=gid).first()

return sg


def get_server_groups_for_user():
def get_server_groups_for_user(only_owned=False):
"""Return server groups visible to the current user.

Includes groups owned by the user plus groups containing shared
servers (Server.shared=True, visible to all authenticated users).
Administrators see all groups.
Administrators see all groups if ADMIN_CAN_SEE_ALL_SERVERS is True.
"""
if not config.SERVER_MODE:
return ServerGroup.query.filter_by(
user_id=current_user.id
).all()
)

if _is_admin():
return ServerGroup.query.all()
if _is_admin() and config.ADMIN_CAN_SEE_ALL_SERVERS:
return ServerGroup.query

return ServerGroup.query.filter(
or_(
ServerGroup.user_id == current_user.id,
ServerGroup.id.in_(
db.session.query(Server.servergroup_id).filter(
Server.shared
)
)
sg = ServerGroup.query.filter(
ServerGroup.user_id == current_user.id
)
).all()

if not only_owned:
sg = sg.union(
ServerGroup.query.join(ServerGroup.servers)
.filter(Server.shared)
)

return sg


def get_user_server_query():
"""Return a base query for servers accessible to the current user.

Includes owned servers + shared servers (visible to all users).
Administrators see all servers.
Administrators see all servers if ADMIN_CAN_SEE_ALL_SERVERS is True.
"""
if not config.SERVER_MODE:
return Server.query

if _is_admin():
if _is_admin() and config.ADMIN_CAN_SEE_ALL_SERVERS:
return Server.query

return Server.query.filter(
Expand Down