mirror of
https://github.com/goauthentik/authentik
synced 2026-05-05 22:52:42 +02:00
Compare commits
3 Commits
fix-logger
...
core/concr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f457c05f21 | ||
|
|
34cda6688f | ||
|
|
5cdcd5f336 |
80
authentik/core/migrations/0058_groupmembership.py
Normal file
80
authentik/core/migrations/0058_groupmembership.py
Normal file
@@ -0,0 +1,80 @@
|
||||
# Generated by Django 5.2.11 on 2026-02-25 15:09
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
from django.apps.registry import Apps
|
||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
from authentik.lib.migrations import progress_bar
|
||||
|
||||
|
||||
def migrate_group_membership(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
Group = apps.get_model("authentik_core", "group")
|
||||
GroupMembership = apps.get_model("authentik_core", "GroupMembership")
|
||||
|
||||
print("Re-creating group memberships, this might take a couple of minutes...")
|
||||
for group in progress_bar(Group.objects.using(db_alias).all()):
|
||||
GroupMembership.objects.bulk_create(
|
||||
[GroupMembership(group=group, user=user) for user in group.users.all()]
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_core", "0057_remove_user_groups_remove_user_user_permissions_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="GroupMembership",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
("attributes", models.JSONField(blank=True, default=dict)),
|
||||
("expires", models.DateTimeField(default=None, null=True)),
|
||||
("expiring", models.BooleanField(default=True)),
|
||||
(
|
||||
"group",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="authentik_core.group"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Group Membership",
|
||||
"verbose_name_plural": "Group Memberships",
|
||||
"abstract": False,
|
||||
"indexes": [
|
||||
models.Index(fields=["expires"], name="authentik_c_expires_a2bb46_idx"),
|
||||
models.Index(fields=["expiring"], name="authentik_c_expirin_bdd43a_idx"),
|
||||
models.Index(
|
||||
fields=["expiring", "expires"], name="authentik_c_expirin_ff3ad1_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.RunPython(migrate_group_membership, migrations.RunPython.noop),
|
||||
migrations.RemoveField(model_name="user", name="groups"),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="groups",
|
||||
field=models.ManyToManyField(
|
||||
related_name="users",
|
||||
through="authentik_core.GroupMembership",
|
||||
to="authentik_core.group",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -368,7 +368,7 @@ class User(SerializerModel, AttributesMixin, AbstractUser):
|
||||
type = models.TextField(choices=UserTypes.choices, default=UserTypes.INTERNAL)
|
||||
|
||||
sources = models.ManyToManyField("Source", through="UserSourceConnection")
|
||||
groups = models.ManyToManyField("Group", related_name="users")
|
||||
groups = models.ManyToManyField("Group", related_name="users", through="GroupMembership")
|
||||
roles = models.ManyToManyField("authentik_rbac.Role", related_name="users", blank=True)
|
||||
password_change_date = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@@ -1151,6 +1151,19 @@ class ExpiringModel(models.Model):
|
||||
return now() > self.expires
|
||||
|
||||
|
||||
class GroupMembership(ExpiringModel, AttributesMixin):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Group Membership")
|
||||
verbose_name_plural = _("Group Memberships")
|
||||
indexes = ExpiringModel.Meta.indexes
|
||||
|
||||
def __str__(self):
|
||||
return f"Group membership between {self.user_id} and {self.group_id}"
|
||||
|
||||
|
||||
class TokenIntents(models.TextChoices):
|
||||
"""Intents a Token can be created for."""
|
||||
|
||||
|
||||
@@ -5277,13 +5277,6 @@
|
||||
},
|
||||
"title": "Parents"
|
||||
},
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": "Users"
|
||||
},
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
@@ -5510,6 +5503,7 @@
|
||||
"authentik_core.add_authenticatedsession",
|
||||
"authentik_core.add_group",
|
||||
"authentik_core.add_groupancestrynode",
|
||||
"authentik_core.add_groupmembership",
|
||||
"authentik_core.add_groupparentagenode",
|
||||
"authentik_core.add_groupsourceconnection",
|
||||
"authentik_core.add_propertymapping",
|
||||
@@ -5524,6 +5518,7 @@
|
||||
"authentik_core.change_authenticatedsession",
|
||||
"authentik_core.change_group",
|
||||
"authentik_core.change_groupancestrynode",
|
||||
"authentik_core.change_groupmembership",
|
||||
"authentik_core.change_groupparentagenode",
|
||||
"authentik_core.change_groupsourceconnection",
|
||||
"authentik_core.change_propertymapping",
|
||||
@@ -5537,6 +5532,7 @@
|
||||
"authentik_core.delete_authenticatedsession",
|
||||
"authentik_core.delete_group",
|
||||
"authentik_core.delete_groupancestrynode",
|
||||
"authentik_core.delete_groupmembership",
|
||||
"authentik_core.delete_groupparentagenode",
|
||||
"authentik_core.delete_groupsourceconnection",
|
||||
"authentik_core.delete_propertymapping",
|
||||
@@ -5557,6 +5553,7 @@
|
||||
"authentik_core.view_authenticatedsession",
|
||||
"authentik_core.view_group",
|
||||
"authentik_core.view_groupancestrynode",
|
||||
"authentik_core.view_groupmembership",
|
||||
"authentik_core.view_groupparentagenode",
|
||||
"authentik_core.view_groupsourceconnection",
|
||||
"authentik_core.view_propertymapping",
|
||||
@@ -11102,6 +11099,7 @@
|
||||
"authentik_core.add_authenticatedsession",
|
||||
"authentik_core.add_group",
|
||||
"authentik_core.add_groupancestrynode",
|
||||
"authentik_core.add_groupmembership",
|
||||
"authentik_core.add_groupparentagenode",
|
||||
"authentik_core.add_groupsourceconnection",
|
||||
"authentik_core.add_propertymapping",
|
||||
@@ -11116,6 +11114,7 @@
|
||||
"authentik_core.change_authenticatedsession",
|
||||
"authentik_core.change_group",
|
||||
"authentik_core.change_groupancestrynode",
|
||||
"authentik_core.change_groupmembership",
|
||||
"authentik_core.change_groupparentagenode",
|
||||
"authentik_core.change_groupsourceconnection",
|
||||
"authentik_core.change_propertymapping",
|
||||
@@ -11129,6 +11128,7 @@
|
||||
"authentik_core.delete_authenticatedsession",
|
||||
"authentik_core.delete_group",
|
||||
"authentik_core.delete_groupancestrynode",
|
||||
"authentik_core.delete_groupmembership",
|
||||
"authentik_core.delete_groupparentagenode",
|
||||
"authentik_core.delete_groupsourceconnection",
|
||||
"authentik_core.delete_propertymapping",
|
||||
@@ -11149,6 +11149,7 @@
|
||||
"authentik_core.view_authenticatedsession",
|
||||
"authentik_core.view_group",
|
||||
"authentik_core.view_groupancestrynode",
|
||||
"authentik_core.view_groupmembership",
|
||||
"authentik_core.view_groupparentagenode",
|
||||
"authentik_core.view_groupsourceconnection",
|
||||
"authentik_core.view_propertymapping",
|
||||
|
||||
@@ -165,8 +165,12 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult,
|
||||
for _, u := range g.UsersObj {
|
||||
if flag.UserPk == u.Pk {
|
||||
// TODO: Is there a better way to clone this object?
|
||||
fg := api.NewGroup(g.Pk, g.NumPk, g.Name, []api.RelatedGroup{}, []api.PartialUser{u}, []api.Role{}, nil, []string{}, []api.RelatedGroup{})
|
||||
fg.SetUsers([]int32{flag.UserPk})
|
||||
fg := api.NewGroupWithDefaults()
|
||||
fg.Pk = g.Pk
|
||||
fg.NumPk = g.NumPk
|
||||
fg.Name = g.Name
|
||||
fg.Users = []int32{flag.UserPk}
|
||||
fg.UsersObj = []api.PartialUser{u}
|
||||
fg.SetAttributes(g.Attributes)
|
||||
fg.SetIsSuperuser(*g.IsSuperuser)
|
||||
groups = append(groups, group.FromAPIGroup(*fg, ms.si))
|
||||
|
||||
10
schema.yml
10
schema.yml
@@ -39957,6 +39957,7 @@ components:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
readOnly: true
|
||||
users_obj:
|
||||
type: array
|
||||
items:
|
||||
@@ -40003,6 +40004,7 @@ components:
|
||||
- parents_obj
|
||||
- pk
|
||||
- roles_obj
|
||||
- users
|
||||
- users_obj
|
||||
GroupKerberosSourceConnection:
|
||||
type: object
|
||||
@@ -40237,10 +40239,6 @@ components:
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
users:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
@@ -48270,10 +48268,6 @@ components:
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
users:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
|
||||
@@ -92,7 +92,6 @@ export class GroupForm extends ModelForm<Group, string> {
|
||||
patchedGroupRequest: data,
|
||||
});
|
||||
}
|
||||
data.users = [];
|
||||
return new CoreApi(DEFAULT_CONFIG).coreGroupsCreate({
|
||||
groupRequest: data,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user