Massive reworking of how Services are created

This commit is contained in:
2010-10-14 10:28:39 +01:00
parent da3d694a4a
commit df1bdde396
4 changed files with 34 additions and 78 deletions

View File

@@ -24,30 +24,6 @@ class RemoveInvalidUsers():
# For each user, update access list based on Corp details # For each user, update access list based on Corp details
user.get_profile().update_access() user.get_profile().update_access()
class ValidateDisabledUsers():
"""
Cycles through all users, and disables any Service Account of disabled
users.
"""
# run daily
run_every = 84600
@property
def _logger(self):
if not hasattr(self, '__logger'):
self.__logger = logging.getLogger(__name__)
return self.__logger
def job(self):
for servacc in ServiceAccount.objects.filter(active=0):
self._logger.info('Checking %s' % servacc)
api = servacc.service.api_class
api.settings = servacc.service.settings
if not api.disable_user(servacc.service_uid):
self._logger.error('Error disabling %s on %s' % (servacc, servacc.service))
class UpdateServiceGroups(): class UpdateServiceGroups():
""" """
Cycles through all service accounts and updates group access. Cycles through all service accounts and updates group access.

View File

@@ -112,8 +112,7 @@ class SSOUser(models.Model):
def update_service_groups(sender, instance, created, **kwargs): def update_service_groups(sender, instance, created, **kwargs):
if not created: if not created:
for acc in instance.serviceaccount_set.all(): for acc in instance.serviceaccount_set.all():
cls = acc.service.api_class acc.service.api_class.update_groups(acc.service_uid, instance.groups.all())
cls.update_groups(acc.service_uid, instance.groups.all())
signals.post_save.connect(SSOUser.create_user_profile, sender=User) signals.post_save.connect(SSOUser.create_user_profile, sender=User)
#signals.post_save.connect(SSOUser.update_service_groups, sender=User) #signals.post_save.connect(SSOUser.update_service_groups, sender=User)
@@ -217,50 +216,20 @@ class ServiceAccount(models.Model):
return "%s: %s (%s)" % (self.service.name, self.user.username, self.service_uid) return "%s: %s (%s)" % (self.service.name, self.user.username, self.service_uid)
def save(self): def save(self):
""" Override default save to setup accounts as needed """ if self.id:
org = ServiceAccount.object.get(id=self.pk)
# Grab the API class and load the settings if org.active != self.active and self.service_uid:
api = self.service.api_class if self.active:
self.service.api_class.enable_user(self.service_uid)
if not self.service_uid:
# Create a account if we've not got a UID
if self.active:
# Force username to be the same as their selected character
# Fix unicode first of all
name = unicodedata.normalize('NFKD', self.character.name).encode('ASCII', 'ignore')
# Remove spaces and non-acceptable characters
self.username = re.sub('[^a-zA-Z0-9_-]+', '', name)
if not api.check_user(self.username):
eveapi = None
for eacc in EVEAccount.objects.filter(user=self.user):
if self.character in eacc.characters.all():
eveapi = eacc
break
reddit = RedditAccount.objects.filter(user=self.user)
d = api.add_user(self.username, self.password, user=self.user, character=self.character)
if not d:
raise ServiceError('Error occured while trying to create the Service Account, please try again later')
else:
self.service_uid = d['username']
else: else:
raise ExistingUser('Username %s has already been took' % self.username) self.service.api_class.disable_user(self.service_uid)
else:
return
# Disable account marked as inactive models.Model.save(self)
if self.service_uid and not self.active:
api.disable_user(self.service_uid)
# All went OK, save to the DB
return models.Model.save(self)
@staticmethod @staticmethod
def pre_delete_listener( **kwargs ): def pre_delete_listener( **kwargs ):
api = kwargs['instance'].service.api_class if not kwargs['instance'].service.api_class.delete_user(kwargs['instance'].service_uid):
if not api.delete_user(kwargs['instance'].service_uid):
raise ServiceError('Unable to delete account on related service') raise ServiceError('Unable to delete account on related service')
signals.pre_delete.connect(ServiceAccount.pre_delete_listener, sender=ServiceAccount) signals.pre_delete.connect(ServiceAccount.pre_delete_listener, sender=ServiceAccount)

View File

@@ -134,26 +134,36 @@ def service_add(request):
if request.method == 'POST': if request.method == 'POST':
form = clsform(request.POST) form = clsform(request.POST)
if form.is_valid(): if form.is_valid():
acc = ServiceAccount() acc = ServiceAccount()
acc.user = request.user acc.user = request.user
acc.service = form.cleaned_data['service'] acc.service = form.cleaned_data['service']
acc.character = form.cleaned_data['character'] acc.character = form.cleaned_data['character']
if settings.GENERATE_SERVICE_PASSWORD:
acc.password = hashlib.sha1('%s%s%s' % (form.cleaned_data['character'].name, settings.SECRET_KEY, random.randint(0, 2147483647))).hexdigest()
else:
acc.password = form.cleaned_data['password']
try: if acc.service.settings['require_password']:
acc.save() if settings.GENERATE_SERVICE_PASSWORD:
except ExistingUser: acc.password = hashlib.sha1('%s%s%s' % (form.cleaned_data['character'].name, settings.SECRET_KEY, random.randint(0, 2147483647))).hexdigest()
error = "User by this name already exists, your account has not been created" else:
except ServiceError: acc.password = form.cleaned_data['password']
error = "A error occured while trying to create the Service Account, please try again later"
else: else:
error = None acc.password = None
# Decode unicode and remove invalid characters
username = re.sub('[^a-zA-Z0-9_-]+', '', unicodedata.normalize('NFKD', self.character.name).encode('ASCII', 'ignore'))
if acc.service.api_class.check_user(username):
error = "Username already exists on the target service, please contact an admin."
else:
ret = acc.service.api_class.add_user(username, acc.password, user=request.user, character=acc.character)
if ret:
acc.service_uid = ret['username']
acc.save()
error = None
else:
error = "Error creating account on the service, please retry or contact an admin if the error persists."
return render_to_response('sso/serviceaccount/created.html', locals(), context_instance=RequestContext(request)) return render_to_response('sso/serviceaccount/created.html', locals(), context_instance=RequestContext(request))
else: else:
availserv = Service.objects.filter(groups__in=request.user.groups.all()).exclude(id__in=ServiceAccount.objects.filter(user=request.user).values('service')) availserv = Service.objects.filter(groups__in=request.user.groups.all()).exclude(id__in=ServiceAccount.objects.filter(user=request.user).values('service'))
if len(availserv) == 0: if len(availserv) == 0:

View File

@@ -14,8 +14,9 @@ this is incorrect please raise a bug on the tracker.
<table> <table>
<tr><td>Service:</td><td>{{ acc.service.name }}</td></tr> <tr><td>Service:</td><td>{{ acc.service.name }}</td></tr>
<tr><td>Service URL:</td><td><a href="{{ acc.service.url }}">{{ acc.service.url }}</a></td></tr> <tr><td>Service URL:</td><td><a href="{{ acc.service.url }}">{{ acc.service.url }}</a></td></tr>
<tr><td>Username:</td><td>{{ acc.service_uid }}</td></tr> {% for key,value in ret.items %}
<tr><td>Password:</td><td>{{ acc.password }}</td></tr> <tr><td>{{ key }}:</td><td>{{ value }}</td></tr>
{% endfor %}
</table> </table>
<p><a href="{% url sso.views.profile %}">Return to your profile page</a></p> <p><a href="{% url sso.views.profile %}">Return to your profile page</a></p>