This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Savane-cleanup framework".
The branch, master has been updated via ca244d41fab94ff2cfe648073010693d1a1edb7d (commit) via 8eb6080812d0ec40d03f5247073874d7a8cdfb4e (commit) via 5f14bd76bd2c185f5d5dd6f3f2c82ae1b446e46f (commit) via 37357a4e77021d0a3c46ecd8cd6f500a4c99df96 (commit) from c90ce44cd395fd635ae5cc9a326afe6aecbe1f33 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://git.savannah.gnu.org/cgit/savane-cleanup/framework.git/commit/?id=ca244d41fab94ff2cfe648073010693d1a1edb7d commit ca244d41fab94ff2cfe648073010693d1a1edb7d Author: Jonathan Gonzalez V <z...@gnu.org> Date: Sat Aug 8 13:41:52 2009 -0400 Added a form to upload one key per time and/or a public key file. Verfied in both cases, that it's a valid key diff --git a/src/savane/my/views.py b/src/savane/my/views.py index 3eb7686..3bb9617 100644 --- a/src/savane/my/views.py +++ b/src/savane/my/views.py @@ -3,17 +3,17 @@ # Copyright (C) 2009 Jonathan Gonzalez V. # # This file is part of Savane. -# +# # Savane is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # Savane is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. -# +# # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -23,7 +23,13 @@ from django.http import HttpResponseRedirect from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from django import forms -from savane.svmain.models import ExtendedUser +from savane.svmain.models import ExtendedUser, SshKey + +import random +import time +import os +import re +from subprocess import Popen, PIPE @login_required() def sv_conf( request ): @@ -91,54 +97,76 @@ def sv_ssh_gpg( request ): form_ssh = SSHForm() form_gpg = GPGForm() + ssh_keys = None + + if request.method == 'GET' and 'action' in request.GET: + action = request.GET['action'] + if action == 'delete_key': + key_pk = request.GET['key_pk'] + try: + ssh_key = eu.sshkey_set.get(pk=key_pk) + ssh_key.delete() + except: + error_msg = 'Cannot remove the selected key' if request.method == 'POST': form = None action = request.POST['action'] - if action == 'update_ssh': - form_ssh = SSHForm( request.POST ) + if action == 'add_ssh': + form_ssh = SSHForm( request.POST, request.FILES ) form = form_ssh elif action == 'update_gpg': form_gpg = GPGForm( request.POST ) if form is not None and form.is_valid(): - if action == 'update_ssh': - keys = list() - for i in range( 1, 6 ): - key_str = 'key_'+str(i) - key = request.POST[ key_str ] - if key != '': - keys.append( key ) - keys_str = str('###').join( keys ) - - eu.authorized_keys = keys_str - eu.save() - success_msg = 'Authorized keys stored.' + if action == 'add_ssh': + if 'key' in request.POST: + key = request.POST['key'].strip() + if len(key) > 0: + ssh_key = SshKey(ssh_key=key) + eu.sshkey_set.add(ssh_key) + success_msg = 'Authorized keys stored.' + + if 'key_file' in request.FILES: + ssh_key_file = request.FILES['key_file'] + if ssh_key_file is not None: + key = '' + for chunk in ssh_key_file.chunks(): + key = key + chunk + + if len(key) > 0: + ssh_key = SshKey(ssh_key=key) + eu.sshkey_set.add(ssh_key) + success_msg = 'Authorized keys stored.' + + form_ssh = SSHForm() + + if len( success_msg ) == 0: + error_msg = 'Cannot added the public key' + elif action == 'update_gpg': pass else: - if eu.authorized_keys != '': - keys_data = dict({'action':'update_ssh'}) - keys = (eu.authorized_keys or '').split('###') - i = 1 - for key in keys: - key_str = 'key_'+str(i) - keys_data[ key_str ] = key - i += 1 - form_ssh = SSHForm( keys_data ) - else: - form_ssh = SSHForm() - - if eu.gpg_key != '': - gpg_data = dict({'action':'update_gpg', 'gpg_key':eu.gpg_key}) - form_gpg = GPGForm( gpg_data ) - else: - form_gpg = GPGForm() + if eu.gpg_key != '': + gpg_data = dict({'action':'update_gpg', 'gpg_key':eu.gpg_key}) + form_gpg = GPGForm( gpg_data ) + else: + form_gpg = GPGForm() + + keys = eu.sshkey_set.all() + if keys is not None: + ssh_keys = dict() + for key in keys: + ssh_keys[key.pk] = key.ssh_key + return render_to_response('my/ssh_gpg.html', { 'form_gpg' : form_gpg, 'form_ssh' : form_ssh, + 'ssh_keys' : ssh_keys, + 'error_msg' : error_msg, + 'success_msg' : success_msg, }, context_instance=RequestContext(request)) @@ -167,10 +195,49 @@ class GPGForm( forms.Form ): action = forms.CharField( widget=forms.HiddenInput, required=True, initial='update_gpg' ) class SSHForm( forms.Form ): - widget = forms.TextInput( attrs={'size':'60'} ) - key_1 = forms.CharField( widget=widget, required=False ) - key_2 = forms.CharField( widget=widget, required=False ) - key_3 = forms.CharField( widget=widget, required=False ) - key_4 = forms.CharField( widget=widget, required=False ) - key_5 = forms.CharField( widget=widget, required=False ) - action = forms.CharField( widget=forms.HiddenInput, required=True, initial='update_ssh' ) + key_file = forms.FileField( required=False ) + key = forms.CharField( widget=forms.TextInput( attrs={'size':'60'} ), required=False ) + + action = forms.CharField( widget=forms.HiddenInput, required=True, initial='add_ssh' ) + + def clean_key( self ): + ssh_key = self.cleaned_data['key'] + + if ssh_key is None or len(ssh_key) == 0: + return ssh_key + + file_name = '/tmp/%d' % random.randint(0, int(time.time())) + + tmp_file = open( file_name, 'wb+' ) + tmp_file.write( ssh_key ) + tmp_file.close() + + cmd = 'ssh-keygen -l -f %s' % file_name + pipe = Popen( cmd, shell=True, stdout=PIPE).stdout + res = re.search("not a public key file", pipe.readline()) + if res is not None: + raise forms.ValidationError( "The uploaded string is not a public key file" ) + + return ssh_key + + def clean_key_file( self ): + ssh_key_file = self.cleaned_data['key_file'] + + if ssh_key_file is None: + return ssh_key_file + + file_name = '/tmp/%d' % random.randint(0, int(time.time())) + + tmp_file = open( file_name, 'wb+' ) + for chunk in ssh_key_file.chunks(): + tmp_file.write(chunk) + tmp_file.close() + + cmd = 'ssh-keygen -l -f %s' % file_name + pipe = Popen( cmd, shell=True, stdout=PIPE).stdout + res = re.search("not a public key file", pipe.readline()) + + if res is not None: + raise forms.ValidationError( "The uploaded file is not a public key file" ) + + return ssh_key_file http://git.savannah.gnu.org/cgit/savane-cleanup/framework.git/commit/?id=8eb6080812d0ec40d03f5247073874d7a8cdfb4e commit 8eb6080812d0ec40d03f5247073874d7a8cdfb4e Author: Jonathan Gonzalez V <z...@gnu.org> Date: Sat Aug 8 13:41:07 2009 -0400 Added list with all the ssh keys added by the user diff --git a/template/my/ssh_gpg.html b/template/my/ssh_gpg.html index f224661..8de124c 100644 --- a/template/my/ssh_gpg.html +++ b/template/my/ssh_gpg.html @@ -7,14 +7,20 @@ <li><a href="{% url savane.my.views.sv_ssh_gpg %}">SSH/GPG Keys</a></li> </ul> +<h3>Working SSH Keys</h3> +{% for key_pk,key in ssh_keys.items %} +<li> + {{ key }}<br /> + <a href="?action=delete_key&key_pk={{key_pk}}">Delete</a> +</li> +{% endfor %} + <h3>SSH Keys</h3> -<form method="post"> +<form method="post" enctype="multipart/form-data"> {{ form_ssh.as_p }} - <br /><input type="submit" value="Save" name="Save" /> + <br /><input type="submit" value="Add" name="Add" /> </form> - - <h3>GPG Key</h3> <form method="post"> {{ form_gpg.as_p }} http://git.savannah.gnu.org/cgit/savane-cleanup/framework.git/commit/?id=5f14bd76bd2c185f5d5dd6f3f2c82ae1b446e46f commit 5f14bd76bd2c185f5d5dd6f3f2c82ae1b446e46f Author: Jonathan Gonzalez V <z...@gnu.org> Date: Sat Aug 8 11:13:25 2009 -0400 Added script to migrate sshkeys from svmain_extendeduser to svmain_sshkey diff --git a/src/savane/backend/migrate_sshkeys.py b/src/savane/backend/migrate_sshkeys.py new file mode 100644 index 0000000..573825b --- /dev/null +++ b/src/savane/backend/migrate_sshkeys.py @@ -0,0 +1,42 @@ +# Replicate users and groups to an OpenLDAP directory +# Copyright (C) 2009 Jonathan Gonzalez +# +# This file is part of Savane. +# +# Savane is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# Savane is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Moves the keys stored at users.authorized_keys to a new table user.sshkeys + + +from savane.svmain.models import ExtendedUser, SshKey + +sv_users = ExtendedUser.objects.all().exclude(authorized_keys='') +for sv_user in sv_users: + keys = (sv_user.authorized_keys or '').split('###') + sv_user.sshkey_set.all().delete() + remove = False + for key in keys: + if len(key) > 0: + try: + ssh_key = SshKey(ssh_key=key) + sv_user.sshkey_set.add(ssh_key) + remove = True + except: + print "User: %s Failed" % sv_user.username + + if remove: + sv_user.authorized_keys = '' + sv_user.save() + + http://git.savannah.gnu.org/cgit/savane-cleanup/framework.git/commit/?id=37357a4e77021d0a3c46ecd8cd6f500a4c99df96 commit 37357a4e77021d0a3c46ecd8cd6f500a4c99df96 Author: Jonathan Gonzalez V <z...@gnu.org> Date: Sat Aug 8 11:12:34 2009 -0400 Added model SshKey to store the ssh keys per user diff --git a/src/savane/svmain/models.py b/src/savane/svmain/models.py index 5b7a50b..4d3dd53 100644 --- a/src/savane/svmain/models.py +++ b/src/savane/svmain/models.py @@ -5,17 +5,17 @@ # Copyright (C) 2009 Jonathan Gonzalez V. # # This file is part of Savane. -# +# # Savane is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # Savane is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. -# +# # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -59,6 +59,11 @@ from django.db import models from django.contrib.auth import models as auth_models +class SshKey(models.Model): + user = models.ForeignKey('ExtendedUser') + ssh_key = models.TextField(blank=False) + + class ExtendedUser(auth_models.User): """Django base User class + extra Savane fields""" @@ -311,7 +316,7 @@ class GroupConfiguration(models.Model): url_homepage = models.CharField(max_length=255, default='http://') url_cvs_viewcvs_homepage = models.CharField(max_length=255, default='http://') url_cvs_viewcvs = models.CharField(max_length=255, default='http://') - url_arch_viewcvs = models.CharField(max_length=255, default='http://') + url_arch_viewcvs = models.CharField(max_length=255, default='http://') url_svn_viewcvs = models.CharField(max_length=255, default='http://') url_git_viewcvs = models.CharField(max_length=255, default='http://') url_hg_viewcvs = models.CharField(max_length=255, default='http://') @@ -359,7 +364,7 @@ class GroupConfiguration(models.Model): class ExtendedGroup(auth_models.Group): """Django base Group class + extra Savane fields""" - + type = models.ForeignKey(GroupConfiguration) full_name = models.CharField(max_length=255, blank=True, help_text="Full project name (not Unix system name)") @@ -388,7 +393,7 @@ class ExtendedGroup(auth_models.Group): register_time = models.DateTimeField() #rand_hash text, - + registered_gpg_keys = models.TextField(blank=True) # Project "Features" @@ -520,7 +525,7 @@ class Membership(models.Model): # TODO: split news params #news_flags int(11) default NULL - + # Trackers-related #privacy_flags = models.BooleanField(default=True) #bugs_flags int(11) default NULL ----------------------------------------------------------------------- Summary of changes: src/savane/backend/migrate_sshkeys.py | 42 +++++++++ src/savane/my/views.py | 151 ++++++++++++++++++++++++--------- src/savane/svmain/models.py | 19 +++-- template/my/ssh_gpg.html | 14 ++- 4 files changed, 173 insertions(+), 53 deletions(-) create mode 100644 src/savane/backend/migrate_sshkeys.py hooks/post-receive -- Savane-cleanup framework _______________________________________________ Savannah-cvs mailing list Savannah-cvs@gnu.org http://lists.gnu.org/mailman/listinfo/savannah-cvs