Skip to content

Commit

Permalink
Allow building a regex to compute a username out of an email address
Browse files Browse the repository at this point in the history
  • Loading branch information
cccs-sgaron committed Apr 7, 2020
1 parent 35afe22 commit 0bee6d7
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
50 changes: 33 additions & 17 deletions assemblyline_ui/helper/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,55 @@
cl_engine = forge.get_classification()


def parse_profile(profile, auto_prop_list=None):
if not auto_prop_list:
auto_prop_list = []

def parse_profile(profile, provider):
# Find email address
email_adr = profile.get('email', profile.get('upn', None))

# Find username or compute it from email
uname = profile.get('uname', email_adr)
if uname == email_adr and provider.uid_regex:
match = re.match(provider.uid_regex, uname)
if match:
if provider.uid_format:
uname = provider.uid_format.format(*[x or "" for x in match.groups()]).lower()
else:
uname = ''.join([x for x in match.groups() if x is not None]).lower()

# Get avatar from gravatar
if config.auth.oauth.gravatar_enabled:
email_hash = hashlib.md5(email_adr.encode('utf-8')).hexdigest()
alternate = f"https://www.gravatar.com/avatar/{email_hash}?s=256&d=404&r=pg"
else:
alternate = None

# Compute access, roles and classification using auto_properties
access = True
roles = ['user']
classification = cl_engine.UNRESTRICTED
for auto_prop in auto_prop_list:
if auto_prop.type == "access":
if auto_prop.value == "True":
access = re.match(auto_prop.pattern, profile.get(auto_prop.field, "")) is not None
else:
access = re.match(auto_prop.pattern, profile.get(auto_prop.field, "")) is None
elif auto_prop.type == "role":
if re.match(auto_prop.pattern, profile.get(auto_prop.field, "")):
roles.append(auto_prop.value)
elif auto_prop.type == "classification":
if re.match(auto_prop.pattern, profile.get(auto_prop.field, "")):
classification = cl_engine.max_classification(classification, auto_prop.value)
if provider.auto_properties:
for auto_prop in provider.auto_properties:
if auto_prop.type == "access":
# Check access
if auto_prop.value == "True":
# If its a positive access pattern
access = re.match(auto_prop.pattern, profile.get(auto_prop.field, "")) is not None
else:
# If its a negative access pattern
access = re.match(auto_prop.pattern, profile.get(auto_prop.field, "")) is None
elif auto_prop.type == "role":
# Append roles from matching patterns
if re.match(auto_prop.pattern, profile.get(auto_prop.field, "")):
roles.append(auto_prop.value)
elif auto_prop.type == "classification":
# Compute classification from matching patterns
if re.match(auto_prop.pattern, profile.get(auto_prop.field, "")):
classification = cl_engine.max_classification(classification, auto_prop.value)

return dict(
access=access,
type=roles,
classification=classification,
uname=profile.get('uname', email_adr),
uname=uname,
name=profile.get('name', None),
email=email_adr,
password="__NO_PASSWORD__",
Expand Down
13 changes: 12 additions & 1 deletion assemblyline_ui/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def login():
# Get user data
resp = provider.get(config.auth.oauth.providers[oauth_provider].user_get)
if resp.ok:
data = parse_profile(resp.json(), config.auth.oauth.providers[oauth_provider].auto_properties)
data = parse_profile(resp.json(), config.auth.oauth.providers[oauth_provider])
has_access = data.pop('access', False)
if has_access:
oauth_avatar = data.pop('avatar', None)
Expand All @@ -232,6 +232,17 @@ def login():
data['uname'] = cur_user.get('uname', data['uname'])
data['password'] = cur_user.get('password', data['password'])
else:
if data['uname'] != data['email']:
# Username was computed using a regular expression, lets make sure we don't
# assign the same username to two users
res = STORAGE.user.search(f"uname:{data['uname']}", rows=0, as_obj=False)
if res['total'] > 0:
cnt = res['total']
new_uname = f"{data['uname']}{cnt}"
while STORAGE.user.get(new_uname) is not None:
cnt += 1
new_uname = f"{data['uname']}{cnt}"
data['uname'] = new_uname
cur_user = {}

username = data['uname']
Expand Down

0 comments on commit 0bee6d7

Please sign in to comment.