diff options
Diffstat (limited to 'coip/apps/userprofile/views.py')
-rw-r--r-- | coip/apps/userprofile/views.py | 176 |
1 files changed, 172 insertions, 4 deletions
diff --git a/coip/apps/userprofile/views.py b/coip/apps/userprofile/views.py index a7b15e8..b1be4c1 100644 --- a/coip/apps/userprofile/views.py +++ b/coip/apps/userprofile/views.py @@ -4,12 +4,93 @@ Created on Jul 6, 2010 @author: leifj ''' from django.contrib.auth.decorators import login_required -from coip.multiresponse import respond_to, json_response -from coip.apps.membership.models import Membership +from coip.multiresponse import respond_to, json_response, render403 +from coip.apps.membership.models import Membership, add_member from django.core.exceptions import ObjectDoesNotExist -from coip.apps.name.models import NameLink +from coip.apps.name.models import NameLink, lookup, Name from django.contrib.auth.models import User from django.shortcuts import get_object_or_404 +from coip.apps.userprofile.models import UserProfile +from django.db.models import Q +from coip.extensions.templatetags.userdisplay import userdisplay +import subprocess +import re +from tempfile import NamedTemporaryFile +from coip.apps.userprofile.forms import AddSSHKeyForm, AddCertificateForm +from django.http import HttpResponseRedirect + +def _add_sshkey(name,keyfile): + p = subprocess.Popen(['ssh-keygen','-l','-f',keyfile.name],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + (out,err) = p.communicate() + code = p.wait() + if code != 0: + raise Exception("Unable to fingerprint ssh key: %d - %s" % (code,err)) + parts = out.split() + fp = re.sub(':','',parts[1]) + + p = subprocess.Popen(['ssh-keygen','-e','-f',keyfile.name],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + (out,err) = p.communicate() + code = p.wait() + if code != 0: + raise Exception("Unable to import ssh key: %d - %s" % (code,err)) + id = out + + username = "sshkey:%s" % fp + user,created = User.objects.get_or_create(username=username) + profile = user.get_profile() + if created: + profile.type = UserProfile.SSHKEY + profile.home = name + profile.display = "SSH Key (%s)" % (fp) + profile.identifier = id + + add_member(profile.home,user) + profile.save() + + +def _add_gridcert(name,keyfile): + p = subprocess.Popen(['openssl','x509','-noout','-fingerprint','-sha1','-in',keyfile.name],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + (out,err) = p.communicate() + code = p.wait() + if code != 0: + raise Exception("Unable to fingerprint X509 certificate: %d - %s" % (code,err)) + parts = out.split('=') + fp = re.sub(':','',parts[1].lower()) + + p = subprocess.Popen(['openssl','x509','-outform','PEM','-in',keyfile.name],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + (out,err) = p.communicate() + code = p.wait() + if code != 0: + raise Exception("Unable to import X509 certificate: %d - %s" % (code,err)) + id = out + + username = "x509:%s" % fp + user,created = User.objects.get_or_create(username=username) + profile = user.get_profile() + if created: + profile.type = UserProfile.X509 + profile.home = name + profile.display = "X509 Certificate (%s)" % (fp) + profile.identifier = id + + add_member(profile.home,user) + profile.save() + +def home_name(user,short=None,autocreate=False): + if short == None: + short = user.username + urn = lookup("urn",True) + anyuser = lookup("system:anyuser",True) + urn.setacl(anyuser,'rl') + + home = lookup('user:'+user.username,autocreate=autocreate) + add_member(home,user,hidden=True) + home.setpacl(home, "rwlida") + home.setacl(home,"rwlia") #don't allow users to delete or reset acls on their home, nor invite members - that would be confusing as hell + home.short = short + home.save() + + return home @login_required def home(request): @@ -19,16 +100,103 @@ def home(request): except ObjectDoesNotExist: pass + user = request.user + profile = user.get_profile() + if profile.home == None: + cn = user.get_full_name() + if not cn: + cn = user.username + profile.home = home_name(user, short=cn, autocreate=True) + names = [(link.src,link.data) for link in NameLink.objects.filter(dst__memberships__user=request.user,type=NameLink.access_control,data__contains='i').all()] return respond_to(request, {'text/html': 'apps/userprofile/home.html'},{'memberships': memberships,'names': names}) @login_required +def add_sshkey(request,id=None): + name = None + if id == None: + name = request.user.get_profile().home + else: + name = get_object_or_404(Name,pk=id) + if name == None: + return render403(request, "Homeless user.") + if not name.has_permission(request.user,'i'): + return render403(request,"You do not have permission to manage aliases here.") + if not name.parent or name.parent.value != 'user': + return render403(request,"This is the wrong place for that.") + + if request.method == 'POST': + form = AddSSHKeyForm(request.POST) + if form.is_valid(): + sshkey = form.cleaned_data['sshkey'] + keyfile = NamedTemporaryFile() + keyfile.write(sshkey) + keyfile.seek(0) + _add_sshkey(name, keyfile) + keyfile.close() + return HttpResponseRedirect("/user/home") + else: + form = AddSSHKeyForm() + + return respond_to(request,{'text/html':'apps/userprofile/sshkey.html'},{'form':form}) + +@login_required +def add_cert(request,id=None): + name = None + if id == None: + name = request.user.get_profile().home + else: + name = get_object_or_404(Name,pk=id) + if name == None: + return render403(request, "Homeless user.") + if not name.has_permission(request.user,'i'): + return render403(request,"You do not have permission to manage aliases here.") + if not name.parent or name.parent.value != 'user': + return render403(request,"This is the wrong place for that.") + + if request.method == 'POST': + form = AddCertificateForm(request.POST) + if form.is_valid(): + certificate = form.cleaned_data['certificate'] + keyfile = NamedTemporaryFile() + keyfile.write(certificate) + keyfile.seek(0) + _add_gridcert(name, keyfile) + keyfile.close() + return HttpResponseRedirect("/user/home") + else: + form = AddCertificateForm() + + return respond_to(request,{'text/html':'apps/userprofile/cert.html'},{'form':form}) + +@login_required +def add_alias(request,id=None): + name = None + if id == None: + name = request.user.get_profile().home + else: + name = get_object_or_404(Name,pk=id) + if name == None: + return render403(request, "Homeless user.") + if not name.has_permission(request.user,'i'): + return render403(request,"You do not have permission to manage aliases here.") + if not name.parent or name.parent.value != 'user': + return render403(request,"This is the wrong place for that.") + + return respond_to(request,{'text/html':'apps/userprofile/addalias.html'}) + +@login_required def search(request): list = [] if request.REQUEST.has_key('term'): term = request.REQUEST['term'] - list = [{'label': user.username,'value': user.id} for user in User.objects.filter(username__contains=term)] + list = [{'label': userdisplay(user),'value': user.id} + for user in User.objects.filter(Q(username__contains=term) | + Q(profile__display_name__contains=term) | + Q(profile__identifier__contains=term) | + Q(first_name__contains=term) | + Q(last_name__contains=term))] return json_response(list) @login_required |