Documentation sphinx-like
This commit is contained in:
parent
401056a468
commit
771a76d7de
1 changed files with 112 additions and 97 deletions
|
@ -1,6 +1,12 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
"""cranspasswords: gestion des mots de passe du Cr@ns"""
|
|
||||||
|
"""Gestion centralisée des mots de passe avec chiffrement GPG
|
||||||
|
|
||||||
|
Copyright (C) 2010-2013 Cr@ns <roots@crans.org>
|
||||||
|
Authors : Daniel Stan <daniel.stan@crans.org>
|
||||||
|
Vincent Le Gallic <legallic@crans.org>
|
||||||
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -20,20 +26,21 @@ except ImportError:
|
||||||
print "Read the README"
|
print "Read the README"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
## Password pattern in files:
|
#: pattern utilisé pour détecter la ligne contenant le mot de passe dans les fichiers
|
||||||
PASS = re.compile('[\t ]*pass(?:word)?[\t ]*:[\t ]*(.*)\r?\n?$', \
|
PASS = re.compile('[\t ]*pass(?:word)?[\t ]*:[\t ]*(.*)\r?\n?$',
|
||||||
flags=re.IGNORECASE)
|
flags=re.IGNORECASE)
|
||||||
|
|
||||||
######
|
|
||||||
## GPG Definitions
|
## GPG Definitions
|
||||||
|
#: path gu binaire gpg
|
||||||
GPG = '/usr/bin/gpg'
|
GPG = '/usr/bin/gpg'
|
||||||
|
#: paramètres à fournir à gpg en fonction de l'action désirée
|
||||||
GPG_ARGS = {
|
GPG_ARGS = {
|
||||||
'decrypt': ['-d'],
|
'decrypt' : ['-d'],
|
||||||
'encrypt': ['--armor', '-es'],
|
'encrypt' : ['--armor', '-es'],
|
||||||
'fingerprint': ['--fingerprint'],
|
'fingerprint' : ['--fingerprint'],
|
||||||
'receive-keys': ['--recv-keys'],
|
'receive-keys' : ['--recv-keys'],
|
||||||
}
|
}
|
||||||
|
#: map lettre de trustlevel -> (signification, faut-il faire confiance à la clé)
|
||||||
GPG_TRUSTLEVELS = {
|
GPG_TRUSTLEVELS = {
|
||||||
u"-" : (u"inconnue", False),
|
u"-" : (u"inconnue", False),
|
||||||
u"n" : (u"nulle", False),
|
u"n" : (u"nulle", False),
|
||||||
|
@ -44,13 +51,15 @@ GPG_TRUSTLEVELS = {
|
||||||
u"e" : (u"expirée", False),
|
u"e" : (u"expirée", False),
|
||||||
u"q" : (u"/données insuffisantes/", False),
|
u"q" : (u"/données insuffisantes/", False),
|
||||||
}
|
}
|
||||||
|
#: Mode verbeux
|
||||||
DEBUG = False
|
|
||||||
VERB = False
|
VERB = False
|
||||||
# Par défaut, place-t-on le mdp dans le presse-papier ?
|
#: Par défaut, place-t-on le mdp dans le presse-papier ?
|
||||||
CLIPBOARD = bool(os.getenv('DISPLAY')) and os.path.exists('/usr/bin/xclip')
|
CLIPBOARD = bool(os.getenv('DISPLAY')) and os.path.exists('/usr/bin/xclip')
|
||||||
FORCED = False #Mode interactif qui demande confirmation
|
#: Mode «ne pas demaner confirmation»
|
||||||
NROLES = None # Droits à définir sur le fichier en édition
|
FORCED = False
|
||||||
|
#: Droits à définir sur le fichier en édition
|
||||||
|
NROLES = None
|
||||||
|
#: Serveur à interroger (peuplée à l'exécution)
|
||||||
SERVER = None
|
SERVER = None
|
||||||
|
|
||||||
def gpg(command, args = None):
|
def gpg(command, args = None):
|
||||||
|
@ -83,14 +92,14 @@ class simple_memoize(object):
|
||||||
self.val = None
|
self.val = None
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
if self.val==None:
|
if self.val == None:
|
||||||
self.val = self.f()
|
self.val = self.f()
|
||||||
return self.val
|
return self.val
|
||||||
|
|
||||||
|
|
||||||
######
|
######
|
||||||
## Remote commands
|
## Remote commands
|
||||||
|
|
||||||
|
|
||||||
def ssh(command, arg = None):
|
def ssh(command, arg = None):
|
||||||
"""Lance ssh avec les arguments donnés. Renvoie son entrée
|
"""Lance ssh avec les arguments donnés. Renvoie son entrée
|
||||||
standard et sa sortie standard."""
|
standard et sa sortie standard."""
|
||||||
|
@ -137,19 +146,20 @@ def get_file(filename):
|
||||||
def put_file(filename, roles, contents):
|
def put_file(filename, roles, contents):
|
||||||
"""Dépose le fichier sur le serveur distant"""
|
"""Dépose le fichier sur le serveur distant"""
|
||||||
return remote_command("putfile", filename, {'roles': roles,
|
return remote_command("putfile", filename, {'roles': roles,
|
||||||
'contents': contents})
|
'contents' : contents})
|
||||||
|
|
||||||
def rm_file(filename):
|
def rm_file(filename):
|
||||||
"""Supprime le fichier sur le serveur distant"""
|
"""Supprime le fichier sur le serveur distant"""
|
||||||
return remote_command("rmfile", filename)
|
return remote_command("rmfile", filename)
|
||||||
|
|
||||||
@simple_memoize
|
@simple_memoize
|
||||||
def get_my_roles():
|
def get_my_roles():
|
||||||
"""Retoure la liste des rôles perso"""
|
"""Retourne la liste des rôles de l'utilisateur"""
|
||||||
allr = all_roles()
|
allr = all_roles()
|
||||||
return filter(lambda role: SERVER['user'] in allr[role],allr.keys())
|
return filter(lambda role: SERVER['user'] in allr[role], allr.keys())
|
||||||
|
|
||||||
def gen_password():
|
def gen_password():
|
||||||
"""Generate random password"""
|
"""Génère un mot de passe aléatoire"""
|
||||||
random.seed(datetime.datetime.now().microsecond)
|
random.seed(datetime.datetime.now().microsecond)
|
||||||
chars = string.letters + string.digits + '/=+*'
|
chars = string.letters + string.digits + '/=+*'
|
||||||
length = 15
|
length = 15
|
||||||
|
@ -160,15 +170,15 @@ def gen_password():
|
||||||
|
|
||||||
def update_keys():
|
def update_keys():
|
||||||
"""Met à jour les clés existantes"""
|
"""Met à jour les clés existantes"""
|
||||||
|
|
||||||
keys = all_keys()
|
keys = all_keys()
|
||||||
|
|
||||||
_, stdout = gpg("receive-keys", [key for _, key in keys.values() if key])
|
_, stdout = gpg("receive-keys", [key for _, key in keys.values() if key])
|
||||||
return stdout.read()
|
return stdout.read()
|
||||||
|
|
||||||
def check_keys():
|
def check_keys():
|
||||||
"""Vérifie les clés existantes"""
|
"""Vérifie les clés existantes"""
|
||||||
|
|
||||||
keys = all_keys()
|
keys = all_keys()
|
||||||
gpg = gnupg.GPG(gnupghome='~/.gnupg')
|
gpg = gnupg.GPG(gnupghome='~/.gnupg')
|
||||||
localkeys = gpg.list_keys()
|
localkeys = gpg.list_keys()
|
||||||
|
@ -202,18 +212,18 @@ def get_recipients_of_roles(roles):
|
||||||
for role in roles:
|
for role in roles:
|
||||||
for recipient in allroles[role]:
|
for recipient in allroles[role]:
|
||||||
recipients.add(recipient)
|
recipients.add(recipient)
|
||||||
|
|
||||||
return recipients
|
return recipients
|
||||||
|
|
||||||
def get_dest_of_roles(roles):
|
def get_dest_of_roles(roles):
|
||||||
""" Summarize recipients of a role """
|
"""Renvoie la liste des "username : mail (fingerprint)" """
|
||||||
allkeys = all_keys()
|
allkeys = all_keys()
|
||||||
return ["%s : %s (%s)" % (rec, allkeys[rec][0], allkeys[rec][1])
|
return ["%s : %s (%s)" % (rec, allkeys[rec][0], allkeys[rec][1])
|
||||||
for rec in get_recipients_of_roles(roles) if allkeys[rec][1]]
|
for rec in get_recipients_of_roles(roles) if allkeys[rec][1]]
|
||||||
|
|
||||||
def encrypt(roles, contents):
|
def encrypt(roles, contents):
|
||||||
"""Chiffre le contenu pour les roles donnés"""
|
"""Chiffre le contenu pour les roles donnés"""
|
||||||
|
|
||||||
allkeys = all_keys()
|
allkeys = all_keys()
|
||||||
recipients = get_recipients_of_roles(roles)
|
recipients = get_recipients_of_roles(roles)
|
||||||
|
|
||||||
|
@ -223,7 +233,7 @@ def encrypt(roles, contents):
|
||||||
if fpr:
|
if fpr:
|
||||||
fpr_recipients.append("-r")
|
fpr_recipients.append("-r")
|
||||||
fpr_recipients.append(fpr)
|
fpr_recipients.append(fpr)
|
||||||
|
|
||||||
stdin, stdout = gpg("encrypt", fpr_recipients)
|
stdin, stdout = gpg("encrypt", fpr_recipients)
|
||||||
stdin.write(contents)
|
stdin.write(contents)
|
||||||
stdin.close()
|
stdin.close()
|
||||||
|
@ -259,13 +269,14 @@ def get_password(name):
|
||||||
remotefile = get_file(name)
|
remotefile = get_file(name)
|
||||||
return decrypt(remotefile['contents'])
|
return decrypt(remotefile['contents'])
|
||||||
|
|
||||||
|
######
|
||||||
## Interface
|
## Interface
|
||||||
|
|
||||||
def editor(texte, annotations=""):
|
def editor(texte, annotations=""):
|
||||||
""" Lance $EDITOR sur texte.
|
""" Lance $EDITOR sur texte.
|
||||||
Renvoie le nouveau texte si des modifications ont été apportées, ou None
|
Renvoie le nouveau texte si des modifications ont été apportées, ou None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Avoid syntax hilight with ".txt". Would be nice to have some colorscheme
|
# Avoid syntax hilight with ".txt". Would be nice to have some colorscheme
|
||||||
# for annotations ...
|
# for annotations ...
|
||||||
f = tempfile.NamedTemporaryFile(suffix='.txt')
|
f = tempfile.NamedTemporaryFile(suffix='.txt')
|
||||||
|
@ -274,8 +285,8 @@ def editor(texte, annotations=""):
|
||||||
for l in annotations.split('\n'):
|
for l in annotations.split('\n'):
|
||||||
f.write("# %s\n" % l.encode('utf-8'))
|
f.write("# %s\n" % l.encode('utf-8'))
|
||||||
f.flush()
|
f.flush()
|
||||||
proc = subprocess.Popen(os.getenv('EDITOR') + ' ' + f.name,shell=True)
|
proc = subprocess.Popen(os.getenv('EDITOR') + ' ' + f.name, shell=True)
|
||||||
os.waitpid(proc.pid,0)
|
os.waitpid(proc.pid, 0)
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
ntexte = f.read()
|
ntexte = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
|
@ -285,9 +296,8 @@ def editor(texte, annotations=""):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def show_files():
|
def show_files():
|
||||||
proc = subprocess.Popen("cat",stdin=subprocess.PIPE,shell=True)
|
"""Affiche la liste des fichiers disponibles sur le serveur distant"""
|
||||||
out = proc.stdin
|
print """Liste des fichiers disponibles"""
|
||||||
out.write("""Liste des fichiers disponibles\n""" )
|
|
||||||
my_roles = get_my_roles()
|
my_roles = get_my_roles()
|
||||||
files = all_files()
|
files = all_files()
|
||||||
keys = files.keys()
|
keys = files.keys()
|
||||||
|
@ -295,32 +305,31 @@ def show_files():
|
||||||
for fname in keys:
|
for fname in keys:
|
||||||
froles = files[fname]
|
froles = files[fname]
|
||||||
access = set(my_roles).intersection(froles) != set([])
|
access = set(my_roles).intersection(froles) != set([])
|
||||||
out.write(" %s %s (%s)\n" % ((access and '+' or '-'),fname,", ".join(froles)))
|
print (u" %s %s (%s)" % ((access and '+' or '-'), fname, ", ".join(froles))).encode("utf-8")
|
||||||
out.write("""--Mes roles: %s\n""" % \
|
print (u"""--Mes roles: %s""" % (", ".join(my_roles),)).encode("utf-8")
|
||||||
", ".join(my_roles))
|
|
||||||
|
|
||||||
out.close()
|
|
||||||
os.waitpid(proc.pid,0)
|
|
||||||
|
|
||||||
def show_roles():
|
def show_roles():
|
||||||
|
"""Affiche la liste des roles existants"""
|
||||||
print """Liste des roles disponibles"""
|
print """Liste des roles disponibles"""
|
||||||
for role in all_roles().keys():
|
for role in all_roles().keys():
|
||||||
if role.endswith('-w'): continue
|
if not role.endswith('-w'):
|
||||||
print " * " + role
|
print " * " + role
|
||||||
|
|
||||||
def show_servers():
|
def show_servers():
|
||||||
|
"""Affiche la liste des serveurs disponibles"""
|
||||||
print """Liste des serveurs disponibles"""
|
print """Liste des serveurs disponibles"""
|
||||||
for server in config.servers.keys():
|
for server in config.servers.keys():
|
||||||
print " * " + server
|
print " * " + server
|
||||||
|
|
||||||
old_clipboard = None
|
old_clipboard = None
|
||||||
def saveclipboard(restore=False):
|
def saveclipboard(restore=False):
|
||||||
|
"""Enregistre le contenu du presse-papier. Le rétablit si ``restore=True``"""
|
||||||
global old_clipboard
|
global old_clipboard
|
||||||
if restore and old_clipboard == None:
|
if restore and old_clipboard == None:
|
||||||
return
|
return
|
||||||
act = '-in' if restore else '-out'
|
act = '-in' if restore else '-out'
|
||||||
proc =subprocess.Popen(['xclip',act,'-selection','clipboard'],\
|
proc = subprocess.Popen(['xclip', act, '-selection', 'clipboard'],
|
||||||
stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=sys.stderr)
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=sys.stderr)
|
||||||
if not restore:
|
if not restore:
|
||||||
old_clipboard = proc.stdout.read()
|
old_clipboard = proc.stdout.read()
|
||||||
else:
|
else:
|
||||||
|
@ -330,20 +339,22 @@ def saveclipboard(restore=False):
|
||||||
proc.stdout.close()
|
proc.stdout.close()
|
||||||
|
|
||||||
def clipboard(texte):
|
def clipboard(texte):
|
||||||
|
"""Place ``texte`` dans le presse-papier en mémorisant l'ancien contenu."""
|
||||||
saveclipboard()
|
saveclipboard()
|
||||||
proc =subprocess.Popen(['xclip','-selection','clipboard'],\
|
proc =subprocess.Popen(['xclip', '-selection', 'clipboard'],\
|
||||||
stdin=subprocess.PIPE,stdout=sys.stdout,stderr=sys.stderr)
|
stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr)
|
||||||
proc.stdin.write(texte)
|
proc.stdin.write(texte)
|
||||||
proc.stdin.close()
|
proc.stdin.close()
|
||||||
return "[Le mot de passe a été mis dans le presse papier]"
|
return "[Le mot de passe a été mis dans le presse papier]"
|
||||||
|
|
||||||
|
|
||||||
def show_file(fname):
|
def show_file(fname):
|
||||||
|
"""Affiche le contenu d'un fichier"""
|
||||||
value = get_file(fname)
|
value = get_file(fname)
|
||||||
if value == False:
|
if value == False:
|
||||||
print "Fichier introuvable"
|
print "Fichier introuvable"
|
||||||
return
|
return
|
||||||
(sin,sout) = gpg('decrypt')
|
(sin, sout) = gpg('decrypt')
|
||||||
sin.write(value['contents'])
|
sin.write(value['contents'])
|
||||||
sin.close()
|
sin.close()
|
||||||
texte = sout.read()
|
texte = sout.read()
|
||||||
|
@ -359,7 +370,7 @@ def show_file(fname):
|
||||||
showbin = "cat" if hidden else "less"
|
showbin = "cat" if hidden else "less"
|
||||||
proc = subprocess.Popen(showbin, stdin=subprocess.PIPE, shell=True)
|
proc = subprocess.Popen(showbin, stdin=subprocess.PIPE, shell=True)
|
||||||
out = proc.stdin
|
out = proc.stdin
|
||||||
out.write("Fichier %s:\n\n" % fname)
|
out.write("Fichier %s:\n\n" % (fname,))
|
||||||
out.write(ntexte)
|
out.write(ntexte)
|
||||||
out.write("-----\n")
|
out.write("-----\n")
|
||||||
out.write("Visible par: %s\n" % ','.join(value['roles']))
|
out.write("Visible par: %s\n" % ','.join(value['roles']))
|
||||||
|
@ -368,6 +379,7 @@ def show_file(fname):
|
||||||
|
|
||||||
|
|
||||||
def edit_file(fname):
|
def edit_file(fname):
|
||||||
|
"""Modifie/Crée un fichier"""
|
||||||
value = get_file(fname)
|
value = get_file(fname)
|
||||||
nfile = False
|
nfile = False
|
||||||
annotations = u""
|
annotations = u""
|
||||||
|
@ -377,7 +389,8 @@ def edit_file(fname):
|
||||||
if not confirm("Créer fichier ?"):
|
if not confirm("Créer fichier ?"):
|
||||||
return
|
return
|
||||||
annotations += u"""Ceci est un fichier initial contenant un mot de passe
|
annotations += u"""Ceci est un fichier initial contenant un mot de passe
|
||||||
aléatoire, pensez à rajouter une ligne "login: ${login}"\n"""
|
aléatoire, pensez à rajouter une ligne "login: ${login}"
|
||||||
|
Enregistrez le fichier vide pour annuler.\n"""
|
||||||
texte = "pass: %s\n" % gen_password()
|
texte = "pass: %s\n" % gen_password()
|
||||||
roles = get_my_roles()
|
roles = get_my_roles()
|
||||||
# Par défaut les roles d'un fichier sont ceux en écriture de son
|
# Par défaut les roles d'un fichier sont ceux en écriture de son
|
||||||
|
@ -386,16 +399,16 @@ aléatoire, pensez à rajouter une ligne "login: ${login}"\n"""
|
||||||
if roles == []:
|
if roles == []:
|
||||||
print "Vous ne possédez aucun rôle en écriture ! Abandon."
|
print "Vous ne possédez aucun rôle en écriture ! Abandon."
|
||||||
return
|
return
|
||||||
value = {'roles':roles}
|
value = {'roles' : roles}
|
||||||
else:
|
else:
|
||||||
(sin,sout) = gpg('decrypt')
|
(sin, sout) = gpg('decrypt')
|
||||||
sin.write(value['contents'])
|
sin.write(value['contents'])
|
||||||
sin.close()
|
sin.close()
|
||||||
texte = sout.read()
|
texte = sout.read()
|
||||||
value['roles'] = NROLES or value['roles']
|
value['roles'] = NROLES or value['roles']
|
||||||
|
|
||||||
annotations += u"Ce fichier sera chiffré pour les rôles suivants :\n%s\n\
|
annotations += u"""Ce fichier sera chiffré pour les rôles suivants :\n%s\n
|
||||||
C'est-à-dire pour les utilisateurs suivants :\n%s" % (
|
C'est-à-dire pour les utilisateurs suivants :\n%s""" % (
|
||||||
', '.join(value['roles']),
|
', '.join(value['roles']),
|
||||||
'\n'.join(' %s' % rec for rec in get_dest_of_roles(value['roles']))
|
'\n'.join(' %s' % rec for rec in get_dest_of_roles(value['roles']))
|
||||||
)
|
)
|
||||||
|
@ -406,12 +419,13 @@ C'est-à-dire pour les utilisateurs suivants :\n%s" % (
|
||||||
print "Pas de modifications effectuées"
|
print "Pas de modifications effectuées"
|
||||||
else:
|
else:
|
||||||
ntexte = texte if ntexte == None else ntexte
|
ntexte = texte if ntexte == None else ntexte
|
||||||
if put_password(fname,value['roles'],ntexte):
|
if put_password(fname, value['roles'], ntexte):
|
||||||
print "Modifications enregistrées"
|
print "Modifications enregistrées"
|
||||||
else:
|
else:
|
||||||
print "Erreur lors de l'enregistrement (avez-vous les droits suffisants ?)"
|
print "Erreur lors de l'enregistrement (avez-vous les droits suffisants ?)"
|
||||||
|
|
||||||
def confirm(text):
|
def confirm(text):
|
||||||
|
"""Demande confirmation, sauf si on est mode ``FORCED``"""
|
||||||
if FORCED: return True
|
if FORCED: return True
|
||||||
while True:
|
while True:
|
||||||
out = raw_input(text + ' (O/N)').lower()
|
out = raw_input(text + ' (O/N)').lower()
|
||||||
|
@ -421,24 +435,26 @@ def confirm(text):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def remove_file(fname):
|
def remove_file(fname):
|
||||||
|
"""Supprime un fichier"""
|
||||||
if not confirm('Êtes-vous sûr de vouloir supprimer %s ?' % fname):
|
if not confirm('Êtes-vous sûr de vouloir supprimer %s ?' % fname):
|
||||||
return
|
return
|
||||||
if rm_file(fname):
|
if rm_file(fname):
|
||||||
print "Suppression achevée"
|
print "Suppression effectuée"
|
||||||
else:
|
else:
|
||||||
print "Erreur de suppression (avez-vous les droits ?)"
|
print "Erreur de suppression (avez-vous les droits ?)"
|
||||||
|
|
||||||
|
|
||||||
def my_check_keys():
|
def my_check_keys():
|
||||||
|
"""Vérifie les clés et affiche un message en fonction du résultat"""
|
||||||
print (check_keys() and u"Base de clés ok" or u"Erreurs dans la base").encode("utf-8")
|
print (check_keys() and u"Base de clés ok" or u"Erreurs dans la base").encode("utf-8")
|
||||||
|
|
||||||
def my_update_keys():
|
def my_update_keys():
|
||||||
|
"""Met à jour les clés existantes et affiche le résultat"""
|
||||||
print update_keys()
|
print update_keys()
|
||||||
|
|
||||||
def update_role():
|
def update_role():
|
||||||
|
"""Rechiffre les fichiers"""
|
||||||
roles = None
|
roles = None
|
||||||
""" Reencode les fichiers, si roles est fourni,
|
|
||||||
contient une liste de rôles"""
|
|
||||||
my_roles = get_my_roles()
|
my_roles = get_my_roles()
|
||||||
if roles == None:
|
if roles == None:
|
||||||
# On ne conserve que les rôles qui finissent par -w
|
# On ne conserve que les rôles qui finissent par -w
|
||||||
|
@ -446,14 +462,14 @@ def update_role():
|
||||||
if type(roles) != list:
|
if type(roles) != list:
|
||||||
roles = [roles]
|
roles = [roles]
|
||||||
|
|
||||||
for (fname,froles) in all_files().iteritems():
|
for (fname, froles) in all_files().iteritems():
|
||||||
if set(roles).intersection(froles) == set([]):
|
if set(roles).intersection(froles) == set([]):
|
||||||
continue
|
continue
|
||||||
#if VERB:
|
print "Rechiffrement de %s" % fname
|
||||||
print "Reencodage de %s" % fname
|
put_password(fname, froles, get_password(fname))
|
||||||
put_password(fname,froles,get_password(fname))
|
|
||||||
|
|
||||||
def parse_roles(strroles):
|
def parse_roles(strroles):
|
||||||
|
"""Interprête une liste de rôles fournie par l'utilisateur"""
|
||||||
if strroles == None: return None
|
if strroles == None: return None
|
||||||
roles = all_roles()
|
roles = all_roles()
|
||||||
my_roles = filter(lambda r: SERVER['user'] in roles[r],roles.keys())
|
my_roles = filter(lambda r: SERVER['user'] in roles[r],roles.keys())
|
||||||
|
@ -473,69 +489,68 @@ def parse_roles(strroles):
|
||||||
|
|
||||||
if not FORCED and not writable:
|
if not FORCED and not writable:
|
||||||
if not confirm("""Vous vous apprêtez à perdre vos droits d'écritures\
|
if not confirm("""Vous vous apprêtez à perdre vos droits d'écritures\
|
||||||
(role ne contient pas %s) sur ce fichier, continuer ?""" % \
|
(role ne contient pas %s) sur ce fichier, continuer ?""" %
|
||||||
", ".join(my_roles_w)):
|
", ".join(my_roles_w)):
|
||||||
return False
|
return False
|
||||||
return list(ret)
|
return list(ret)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="trousseau crans")
|
parser = argparse.ArgumentParser(description="trousseau crans")
|
||||||
parser.add_argument('--server',default='default',
|
parser.add_argument('--server', default='default',
|
||||||
help='Utilisation d\'un serveur alternatif (test, etc)')
|
help="Utilisation d'un serveur alternatif (test, backup, etc)")
|
||||||
parser.add_argument('-v','--verbose',action='store_true',default=False,
|
parser.add_argument('-v', '--verbose', action='store_true', default=False,
|
||||||
help="Mode verbeux")
|
help="Mode verbeux")
|
||||||
parser.add_argument('-c','--clipboard',action='store_true',default=None,
|
parser.add_argument('-c', '--clipboard', action='store_true', default=None,
|
||||||
help="Stocker le mot de passe dans le presse papier")
|
help="Stocker le mot de passe dans le presse papier")
|
||||||
parser.add_argument('--no-clip', '--noclip', '--noclipboard',action='store_false',default=None,
|
parser.add_argument('--no-clip', '--noclip', '--noclipboard', action='store_false', default=None,
|
||||||
dest='clipboard',
|
dest='clipboard',
|
||||||
help="Ne PAS stocker le mot de passe dans le presse papier")
|
help="Ne PAS stocker le mot de passe dans le presse papier")
|
||||||
parser.add_argument('-f','--force',action='store_true',default=False,
|
parser.add_argument('-f', '--force', action='store_true', default=False,
|
||||||
help="Forcer l'action")
|
help="Ne pas demander confirmation")
|
||||||
|
|
||||||
# Actions possibles
|
# Actions possibles
|
||||||
action_grp = parser.add_mutually_exclusive_group(required=False)
|
action_grp = parser.add_mutually_exclusive_group(required=False)
|
||||||
action_grp.add_argument('-e', '--edit',action='store_const',dest='action',
|
action_grp.add_argument('-e', '--edit', action='store_const', dest='action',
|
||||||
default=show_file,const=edit_file,
|
default=show_file, const=edit_file,
|
||||||
help="Editer (ou créer)")
|
help="Editer (ou créer)")
|
||||||
action_grp.add_argument('--view',action='store_const',dest='action',
|
action_grp.add_argument('--view', action='store_const', dest='action',
|
||||||
default=show_file,const=show_file,
|
default=show_file, const=show_file,
|
||||||
help="Voir")
|
help="Voir le fichier")
|
||||||
action_grp.add_argument('--remove',action='store_const',dest='action',
|
action_grp.add_argument('--remove', action='store_const', dest='action',
|
||||||
default=show_file,const=remove_file,
|
default=show_file, const=remove_file,
|
||||||
help="Effacer")
|
help="Effacer le fichier")
|
||||||
action_grp.add_argument('-l','--list',action='store_const',dest='action',
|
action_grp.add_argument('-l', '--list', action='store_const', dest='action',
|
||||||
default=show_file,const=show_files,
|
default=show_file, const=show_files,
|
||||||
help="Lister les fichiers")
|
help="Lister les fichiers")
|
||||||
action_grp.add_argument('--check-keys',action='store_const',dest='action',
|
action_grp.add_argument('--check-keys', action='store_const', dest='action',
|
||||||
default=show_file,const=my_check_keys,
|
default=show_file, const=my_check_keys,
|
||||||
help="Vérifier les clés")
|
help="Vérifier les clés")
|
||||||
action_grp.add_argument('--update-keys',action='store_const',dest='action',
|
action_grp.add_argument('--update-keys', action='store_const', dest='action',
|
||||||
default=show_file,const=my_update_keys,
|
default=show_file, const=my_update_keys,
|
||||||
help="Mettre à jour les clés")
|
help="Mettre à jour les clés")
|
||||||
action_grp.add_argument('--list-roles',action='store_const',dest='action',
|
action_grp.add_argument('--list-roles', action='store_const', dest='action',
|
||||||
default=show_file,const=show_roles,
|
default=show_file, const=show_roles,
|
||||||
help="Lister les rôles des gens")
|
help="Lister les rôles existants")
|
||||||
action_grp.add_argument('--list-servers',action='store_const',dest='action',
|
action_grp.add_argument('--list-servers', action='store_const', dest='action',
|
||||||
default=show_file,const=show_servers,
|
default=show_file, const=show_servers,
|
||||||
help="Lister les rôles serveurs")
|
help="Lister les serveurs")
|
||||||
action_grp.add_argument('--recrypt-role',action='store_const',dest='action',
|
action_grp.add_argument('--recrypt-role', action='store_const', dest='action',
|
||||||
default=show_file,const=update_role,
|
default=show_file, const=update_role,
|
||||||
help="Met à jour (reencode les roles)")
|
help="Rechiffrer les mots de passe")
|
||||||
|
|
||||||
parser.add_argument('--roles',nargs='?',default=None,
|
parser.add_argument('--roles', nargs='?', default=None,
|
||||||
help="liste des roles à affecter au fichier")
|
help="liste des roles à affecter au fichier")
|
||||||
parser.add_argument('fname',nargs='?',default=None,
|
parser.add_argument('fname', nargs='?', default=None,
|
||||||
help="Nom du fichier à afficher")
|
help="Nom du fichier à afficher")
|
||||||
|
|
||||||
parsed = parser.parse_args(sys.argv[1:])
|
parsed = parser.parse_args(sys.argv[1:])
|
||||||
SERVER = config.servers[parsed.server]
|
SERVER = config.servers[parsed.server]
|
||||||
VERB = parsed.verbose
|
VERB = parsed.verbose
|
||||||
DEBUG = VERB
|
|
||||||
if parsed.clipboard != None:
|
if parsed.clipboard != None:
|
||||||
CLIPBOARD = parsed.clipboard
|
CLIPBOARD = parsed.clipboard
|
||||||
FORCED = parsed.force
|
FORCED = parsed.force
|
||||||
NROLES = parse_roles(parsed.roles)
|
NROLES = parse_roles(parsed.roles)
|
||||||
|
|
||||||
if NROLES != False:
|
if NROLES != False:
|
||||||
if parsed.action.func_code.co_argcount == 0:
|
if parsed.action.func_code.co_argcount == 0:
|
||||||
parsed.action()
|
parsed.action()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue