Skip to content

Commit

Permalink
[server] Add regex_groups authentication method
Browse files Browse the repository at this point in the history
This creates new groups that users can belong to if their username
matches some regular expression.

Makes it possible to have all users belonging to a group in order to set
default permissions for products.

Solves Ericsson#3072.
  • Loading branch information
jimis committed Dec 30, 2020
1 parent 75ef0ec commit 5566bfc
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 15 deletions.
15 changes: 15 additions & 0 deletions docs/web/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Table of Contents
* [<i>PAM</i> authentication](#pam-authentication)
* [<i>LDAP</i> authentication](#ldap-authentication)
* [Configuration options](#configuration-options)
* Membership in custom groups with [<i>regex_groups</i>](#regex_groups-authentication)
* [Client-side configuration](#client-side-configuration)
* [Web-browser client](#web-browser-client)
* [Command-line client](#command-line-client)
Expand Down Expand Up @@ -285,6 +286,20 @@ servers as it can elongate the authentication process.
}
~~~

## Membership in custom groups with <a name="regex_groups-authentication">regex_groups</a>

The following example will create a group named `everybody` that contains
every user, regardless of the authentication method.

~~~{.json}
"method_regex_groups": {
"enabled" : true,
"groups" : {
"everybody" : [ ".*" ]
}
}
~~~

----

# Client-side configuration <a name="client-side-configuration"></a>
Expand Down
58 changes: 43 additions & 15 deletions web/server/codechecker_server/session_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import hashlib
import json
import os
import re
import uuid

from codechecker_common.logger import get_logger
Expand Down Expand Up @@ -333,23 +334,20 @@ def __handle_validation(self, auth_string):
This validation object contains two keys: username and groups.
"""
validation = self.__try_auth_root(auth_string)
if validation:
return validation

validation = self.__try_auth_dictionary(auth_string)
if validation:
return validation

validation = self.__try_auth_pam(auth_string)
if validation:
return validation
validation = self.__try_auth_root(auth_string) \
or self.__try_auth_dictionary(auth_string) \
or self.__try_auth_pam(auth_string) \
or self.__try_auth_ldap(auth_string)
if not validation:
return False

validation = self.__try_auth_ldap(auth_string)
if validation:
return validation
extra_groups = self.__try_regex_groups(validation['username'])
if extra_groups:
already_groups = set(validation['groups'])
validation['groups'] = list(already_groups | extra_groups)

return False
LOG.debug('User validation details: %s', str(validation))
return validation

def __is_method_enabled(self, method):
return method not in UNSUPPORTED_METHODS and \
Expand Down Expand Up @@ -480,6 +478,36 @@ def __update_groups(self, user_name, groups):

return False

def __try_regex_groups(self, username):
"""
Return a set of groups that the user belongs to, depending on whether
the username matches the regular expression of the group.
"""
if not self.__is_method_enabled('regex_groups'):
return set()
regex_groups = self.__auth_config['method_regex_groups']\
.get('groups', [])
if not regex_groups:
return set()

# Compile all regular expressions once and store them for later use.
try:
group_regexes_compiled = self.__group_regexes_compiled
except AttributeError:
d = dict()
for group_name, regex_list in regex_groups.items():
d[group_name] = [ re.compile(r) for r in regex_list ]
self.__group_regexes_compiled = d
group_regexes_compiled = d

matching_groups = set()
for group_name, regexes_list in group_regexes_compiled.items():
for r in regexes_list:
if re.search(r, username):
matching_groups.add(group_name)
return matching_groups

@staticmethod
def get_user_name(auth_string):
return auth_string.split(':')[0]
Expand Down

0 comments on commit 5566bfc

Please sign in to comment.