-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Conflicts: atlas/prodtask/templates/prodtask/_task_detail.html setup.cfg
- Loading branch information
Showing
43 changed files
with
2,808 additions
and
607 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__author__ = 'sbel' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
============================================================== | ||
Perform fake authentication as a specified user | ||
============================================================== | ||
|
||
Prequsities | ||
+++++++++++ | ||
|
||
User to authenticate as should exist in the database (table 'auth_user'). | ||
|
||
|
||
Configuration | ||
+++++++++++++ | ||
|
||
|
||
settings/config.py | ||
.................. | ||
|
||
* Add 'atlas.auth.fake.backends.LoginAsBackend' to AUTHENTICATION_BACKENDS | ||
before all other backends. | ||
|
||
* Set FAKE_LOGIN_AS_USER = 'username' , pointing to the desired username existing | ||
in the database | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from django.conf import settings | ||
from django.contrib.auth.backends import ModelBackend | ||
from django.contrib.auth.models import User | ||
|
||
|
||
class LoginAsBackend(ModelBackend): | ||
""" Authenticate as user specified in configuration file. | ||
The user should exist in the database. | ||
""" | ||
def authenticate(self, request=None): | ||
username = settings.FAKE_LOGIN_AS_USER | ||
if not username: | ||
return | ||
|
||
try: | ||
user = User.objects.get(username=username) | ||
except User.DoesNotExist: | ||
return | ||
|
||
return user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__author__ = 'sbel' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
from django.conf import settings | ||
from django.contrib.auth.backends import ModelBackend | ||
from django.contrib.auth.models import Group | ||
from django.contrib.auth.models import User | ||
|
||
from .interface import VomsInterface | ||
from .models import VomsUser | ||
|
||
|
||
def add_group(group_name): | ||
try: | ||
group = Group.objects.get(name=group_name) | ||
except Group.DoesNotExist: | ||
group = Group(name=group_name) | ||
group.save() | ||
|
||
return group | ||
|
||
|
||
class VomsBackend(ModelBackend): | ||
""" Adding VOMS-based authentication groups for user. """ | ||
|
||
def authenticate(self, request=None): | ||
""" Checking user against VOMS data and adding corresponding authentication groups. | ||
Parameters: | ||
request: Http request (HttpRequest). | ||
Returns always None to pass further handling to ShibSSO module. | ||
""" | ||
|
||
username = request.META.get(settings.META_USERNAME) | ||
|
||
if not username: | ||
return | ||
|
||
dn_map = {} | ||
for record in VomsUser.objects.filter(username=username): | ||
dn_map[record.dn] = record.ca | ||
|
||
if not dn_map: | ||
return | ||
|
||
voms = VomsInterface(settings.VOMS_OPTIONS) | ||
voms_groups = [] | ||
|
||
for (dn, ca) in dn_map.items(): | ||
vo_roles = voms.list_user_roles(dn, ca) or [] | ||
vo_groups = voms.list_user_groups(dn, ca) or [] | ||
vo_roles = ["vomsrole:" + x for x in vo_roles] | ||
vo_groups = ["vomsgroup:" + x for x in vo_groups] | ||
|
||
voms_groups = vo_groups + vo_roles | ||
|
||
|
||
for group in voms_groups: | ||
add_group(group) | ||
|
||
meta_groups = request.META.get(settings.META_GROUP, '') | ||
groups = ';'.join( [x for x in (voms_groups + [meta_groups]) if x] ) | ||
request.META[settings.META_GROUP] = groups | ||
|
||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#!/bin/env python | ||
|
||
import re | ||
from django.conf import settings | ||
|
||
from .interface import VomsInterface | ||
from .models import VomsUser | ||
|
||
def run(): | ||
""" | ||
Update VOMS mapping nickname <-> (DN, CA) in the database | ||
:return: dictionary, 'added', 'removed' - records added/removed, | ||
'details' - more information on operations performed | ||
""" | ||
|
||
voms = VomsInterface(settings.VOMS_OPTIONS) | ||
voms_users = {} | ||
|
||
for user_info in voms.list_users(): | ||
dn = user_info["DN"] | ||
ca = user_info["CA"] | ||
try: | ||
nickname = voms.get_user_nickname(dn, ca) | ||
except: | ||
# TODO: log the error (e.g. user was removed during data collection) | ||
continue | ||
if not re.match(r"^\w+$", nickname): | ||
# TODO: log the warning | ||
continue | ||
|
||
if not voms_users.get(nickname): | ||
voms_users[nickname] = {} | ||
voms_users[nickname].update({dn: ca}) | ||
|
||
result = {'added': 0, 'removed': 0, 'detailed': []} | ||
|
||
for user in VomsUser.objects.all(): | ||
info = voms_users.get(user.username) | ||
if not info or not user.dn in info: | ||
try: | ||
user.delete() | ||
except: | ||
# TODO: log the error | ||
continue | ||
|
||
result['removed'] += 1 | ||
result['detailed'].append({ | ||
'action': 'remove', 'username': user.username, | ||
'dn': user.dn, 'ca': user.ca, | ||
}) | ||
# TODO: log operation | ||
continue | ||
else: | ||
del voms_users[user.username][user.dn] | ||
|
||
for (nickname, info) in voms_users.items(): | ||
for (dn, ca) in info.items(): | ||
user = VomsUser() | ||
|
||
try: | ||
user = VomsUser.objects.get(username=nickname, dn=dn) | ||
except: | ||
user.username = nickname | ||
user.dn = dn | ||
user.ca = ca | ||
try: | ||
user.save() | ||
except: | ||
# TODO: log the error | ||
continue | ||
result['added'] += 1 | ||
result['detailed'].append({ | ||
'action': 'add', 'username': user.username, | ||
'dn': user.dn, 'ca': user.ca, | ||
}) | ||
|
||
return result | ||
|
||
|
||
if __name__ == "__main__": | ||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import os | ||
|
||
from VOMSAdmin.VOMSCommands import VOMSAdminProxy | ||
|
||
|
||
class VomsInterface: | ||
""" | ||
Retrieving information from VOMS server. | ||
""" | ||
|
||
def __init__(self, options): | ||
self.options = dict(options) | ||
self.voms = VOMSAdminProxy(**options) | ||
|
||
def list_users(self): | ||
vo_users = self.voms.listUsers() | ||
users = [] | ||
|
||
for user in vo_users: | ||
user_info = {} | ||
for field in "CA,DN,mail".split(","): | ||
user_info[field] = getattr(user, "_" + field) | ||
users.append(user_info) | ||
return users | ||
|
||
def list_user_attributes(self, dn, ca): | ||
""" | ||
Read user's attributes from VOMS server | ||
:param dn: DN of user's certificate | ||
:param ca: DN of the issuer of the certificate (CA) | ||
:return: user's attributes as a dict | ||
""" | ||
result = {} | ||
attrs = self.voms.call_method("list-user-attributes", dn, ca) | ||
for item in attrs: | ||
result[item._attributeClass._name] = item._value | ||
return result | ||
|
||
def list_user_groups(self, dn, ca): | ||
""" | ||
Get user's groups in VO from VOMS server | ||
:param dn: DN of user's certificate | ||
:param ca: DN of the issuer of the certificate (CA) | ||
:return: list of groups | ||
""" | ||
return self.voms.call_method("list-user-groups", dn, ca) | ||
|
||
def list_user_roles(self, dn, ca): | ||
return self.voms.call_method("list-user-roles", dn, ca) | ||
|
||
def get_user_nickname(self, dn, ca): | ||
attributes = self.list_user_attributes(dn, ca) | ||
return attributes.get("nickname") | ||
|
||
@staticmethod | ||
def get_identity_options(voms_admin_path="/usr/bin/voms-admin", proxy_cert=None): | ||
import imp | ||
voms_admin = imp.load_source("voms_admin", voms_admin_path) | ||
voms_admin.vlog = lambda msg: None | ||
|
||
if proxy_cert: | ||
old_proxy = os.environ.get("X509_USER_PROXY") | ||
os.environ["X509_USER_PROXY"] = proxy_cert | ||
voms_admin.setup_identity() | ||
# Restore initial environment | ||
if old_proxy is None: | ||
del os.environ["X509_USER_PROXY"] | ||
else: | ||
os.environ["X509_USER_PROXY"] = old_proxy | ||
else: | ||
voms_admin.setup_identity() | ||
|
||
return voms_admin.options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__author__ = 'serge' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__author__ = 'serge' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
__author__ = 'sbel' | ||
|
||
|
||
from django.core.management.base import BaseCommand, CommandError | ||
from atlas.auth.voms import collector | ||
|
||
|
||
class Command(BaseCommand): | ||
|
||
def handle(self, *args, **options): | ||
# TODO: add verbose and quiet mode | ||
info = collector.run() | ||
# TODO: use logging here | ||
print "Added records: %s" % (info['added']) | ||
print "Removed records: %s" % (info['removed']) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
__author__ = 'sbel' | ||
|
||
from django.db import models | ||
from django.utils import timezone | ||
|
||
class VomsUser(models.Model): | ||
id = models.AutoField(db_column='ID', primary_key=True) | ||
username = models.CharField(max_length=60, db_column='USERNAME', db_index=True) | ||
dn = models.CharField(max_length=255, db_column='DN', db_index=True) | ||
ca = models.CharField(max_length=255, db_column='CA') | ||
added_on = models.DateTimeField(auto_now_add=True, db_column='ADDED_ON') | ||
|
||
def save(self, *args, **kwargs): | ||
if not self.added_on: | ||
self.added_on = timezone.now() | ||
super(VomsUser, self).save(*args, **kwargs) | ||
|
||
|
||
class Meta: | ||
managed = True | ||
db_table = u'VOMS_USERS_MAP' | ||
app_label = 'auth' | ||
unique_together = (("username", "dn"),) |
Empty file.
Empty file.
Oops, something went wrong.