PMExtra / sentry-auth-ldap

A Sentry extension to add an LDAP server as an authention source.
Apache License 2.0
25 stars 6 forks source link

AUTH_LDAP_SENTRY_GROUP_ROLE_MAPPING not work #5

Closed integrator-sev closed 1 year ago

integrator-sev commented 1 year ago

AUTH_LDAP_SENTRY_GROUP_ROLE_MAPPING not working... sentry on-premise(docker) v22.12.0 sentry-auth-ldap latest Active Directory as ldap ldapsearch returns "cn" in base64 format and in logs I see "django_auth_ldap: cn=myadminuser,ou=myadminou,ou=myplace,ou=users,dc=test,dc=domain,dc=local is a member of cn=test-sentry-admins,ou=system services,dc=test,dc=domain,dc=local"

BUT myadminuser don't have "admin" role when log in sentry

my sentry.conf.py

#############
# LDAP auth #
#############

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, LDAPSearchUnion, ActiveDirectoryGroupType, NestedActiveDirectoryGroupType, GroupOfUniqueNamesType

AUTH_LDAP_CONNECTION_OPTIONS = {
    ldap.OPT_DEBUG_LEVEL: 0,
    ldap.OPT_REFERRALS: 0,
}

AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_SERVER_URI = "ldap://test.domain.local"
AUTH_LDAP_BIND_DN = env('SENTRY_LDAP_BIND_DN')
AUTH_LDAP_BIND_PASSWORD = env('SENTRY_LDAP_BIND_PASSWORD')

AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(
    LDAPSearch( "dc=test,dc=domain,dc=local", ldap.SCOPE_SUBTREE, "(&(objectClass=user)(sAMAccountName=%(user)s))")
    LDAPSearch( "ou=system services,dc=test,dc=domain,dc=local", ldap.SCOPE_SUBTREE, "(&(objectClass=user)(sAMAccountName=%(user)s))")
)

AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType(name_attr="cn")
AUTH_LDAP_ALWAYS_UPDATE_GROUP = True
AUTH_LDAP_GROUP_SEARCH = LDAPSearchUnion(
    LDAPSearch("cn=test-sentry-admins,ou=system services,dc=test,dc=domain,dc=local", ldap.SCOPE_SUBTREE, "(objectClass=group)")
)

AUTH_LDAP_DENY_GROUP = None

AUTH_LDAP_USER_ATTR_MAP = {
    "username": "sAMAccountName",
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail"
}

AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 0

AUTH_LDAP_DEFAULT_SENTRY_ORGANIZATION = u'Sentry'
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE = 'member'

AUTH_LDAP_SENTRY_GROUP_ROLE_MAPPING = {
    'admin': ['test-sentry-admins'],
    'manager': ['sentry - manager']
}

AUTH_LDAP_SENTRY_ORGANIZATION_GLOBAL_ACCESS = True
AUTH_LDAP_SENTRY_SUBSCRIBE_BY_DEFAULT = True

SENTRY_MANAGED_USER_FIELDS = ('email', 'password')

AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + (
    'sentry_auth_ldap.backend.SentryLdapBackend'
)

I experimented with different group types but role not mapping Can somebody help me, please ?

PMExtra commented 1 year ago

The role mapping is only effected while the first log-in, if the user is already exists in Sentry, it won't update the roles.

Have you tried to create a new user?

PMExtra commented 1 year ago

Another note: The admin role is not superuser, it only means that you have admin permissions of the default organization. And the role mapping will do nothing if the default organization is not set or not found.

integrator-sev commented 1 year ago

Yes, the first log-in success and user is 'admin'. So the AUTH_LDAP_ALWAYS_UPDATE_USER parameter doesn't make sense? it's a pity, because the user can first be a regular member, and later become a manager. And in this situation it would be very inconvenient to lose all his data or distract someone who does not deal with rights. Especially in the presence of ldap. Maybe you can somehow implement a re-mapping of roles when changing the user group in ldap?

PMExtra commented 1 year ago

This project was not originally designed by me. I only forked the original inactive project and make it compatible with the latest Sentry.

By the original design, AUTH_LDAP_ALWAYS_UPDATE_USER will only update the user attributes such as name and email. I think you may be right, the roles should be synced from LDAP.

The key code is that: https://github.com/PMExtra/sentry-auth-ldap/blob/e972999eb1788f75833238bc6141d0c45998461c/sentry_auth_ldap/backend.py#L64-L65

But I'm not sure if removing it will cause other side effects.

You can try to remove the 2 lines locally, and feedback here.

integrator-sev commented 1 year ago

Yes, you was right. I comment two strings, restart sentry, log in and ... In logs : "django.db.utils.IntegrityError: UniqueViolation('duplicate key value violates unique constraint "sentry_organizationmember_organizationid.....
"SQL: INSERT INTO "sentry_organizationmember" Should be something like "UPDATE" I think )

PMExtra commented 1 year ago

You should update this part: https://github.com/PMExtra/sentry-auth-ldap/blob/e972999eb1788f75833238bc6141d0c45998461c/sentry_auth_ldap/backend.py#L87-L94

There is a method named update_or_create: https://docs.djangoproject.com/en/4.2/ref/models/querysets/#update-or-create

PMExtra commented 1 year ago

Welcome to submit a pull request if your attempt is successful.

integrator-sev commented 1 year ago

You should update this part:

https://github.com/PMExtra/sentry-auth-ldap/blob/e972999eb1788f75833238bc6141d0c45998461c/sentry_auth_ldap/backend.py#L87-L94

There is a method named update_or_create: https://docs.djangoproject.com/en/4.2/ref/models/querysets/#update-or-create

get_db_prep_lookup not supported for Bit ((( Maybe there are some other ideas that will help me understand where to dig?

PMExtra commented 1 year ago

replace with

OrganizationMember.objects.update_or_create(
    organization=organizations[0],
    user=user,
    defaults={
        "role": member_role,
        "has_global_access": has_global_access, 
        "flags": getattr(OrganizationMember.flags, 'sso:linked')
    }
)
integrator-sev commented 1 year ago

Ok))) It works!