Skip to content

Commit faf5a69

Browse files
committed
Add ability to restrict cauth sites to members of specific group(s)
If no groups are specified, work just like before where every user can log in to every site. Existing limited sites had the list of users defined locally on the machine, but it seems reasonable to be able to control this centrally as well.
1 parent 7417900 commit faf5a69

5 files changed

Lines changed: 45 additions & 5 deletions

File tree

pgweb/account/admin.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ class Meta:
2020
model = CommunityAuthSite
2121
exclude = ()
2222

23+
def __init__(self, *args, **kwargs):
24+
super().__init__(*args, **kwargs)
25+
26+
self.fields['org'].widget.can_add_related = False
27+
self.fields['org'].widget.can_change_related = False
28+
self.fields['require_groups'].widget.can_add_related = False
29+
2330
def clean_cryptkey(self):
2431
x = None
2532
try:
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Generated by Django 5.2.10 on 2026-05-22 19:23
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('account', '0010_communityauthsite_version'),
10+
('auth', '0012_alter_user_first_name_max_length'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='communityauthsite',
16+
name='require_groups',
17+
field=models.ManyToManyField(blank=True, help_text='Require membership in at least one of the specified groups in order to log in', to='auth.group'),
18+
),
19+
]

pgweb/account/models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from django.db import models
2-
from django.contrib.auth.models import User
2+
from django.contrib.auth.models import User, Group
33

44

55
class CommunityAuthOrg(models.Model):
@@ -29,6 +29,8 @@ class CommunityAuthSite(models.Model):
2929
help_text="Supports receiving http POSTs with changes to accounts")
3030
push_ssh = models.BooleanField(null=False, blank=False, default=False,
3131
help_text="Wants to receive SSH keys in push changes")
32+
require_groups = models.ManyToManyField(Group, blank=True,
33+
help_text="Require membership in at least one of the specified groups in order to log in")
3234

3335
def __str__(self):
3436
return self.name

pgweb/account/views.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -675,11 +675,16 @@ def communityauth(request, siteid):
675675
},
676676
)(request)
677677

678-
# When we reach this point, the user *has* already been authenticated.
679-
# The request variable "su" *may* contain a suburl and should in that
680-
# case be passed along to the site we're authenticating for. And of
681-
# course, we fill a structure with information about the user.
678+
# At this point, the user has been authenticated.
682679

680+
# If this site is group-restricted, verify it
681+
if site.require_groups.exists() and not site.require_groups.filter(id__in=request.user.groups.all()).exists():
682+
return render_pgweb(request, 'account', 'account/communityauth_nogroup.html', {
683+
'site': site,
684+
})
685+
686+
# Make sure we have some data to fill in before we redirect, so downstream consumers
687+
# don't need to verify that.
683688
if request.user.first_name == '' or request.user.last_name == '' or request.user.email == '':
684689
return render_pgweb(request, 'account', 'account/communityauth_noinfo.html', {
685690
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{%extends "base/page.html"%}
2+
{%block contents%}
3+
<h1>Access denied</h1>
4+
<p>
5+
You do not have access to {{ site.name }}.
6+
</p>
7+
{%endblock%}

0 commit comments

Comments
 (0)