Skip to content
Snippets Groups Projects
Verified Commit 46235968 authored by me5na7qbjqbrp's avatar me5na7qbjqbrp
Browse files

autopep8 on server

parent 57a32c24
No related branches found
No related tags found
1 merge request!7Create pip package
Pipeline #2880 passed with warnings with stage
in 39 seconds
......@@ -43,7 +43,8 @@ MYUID = pwd.getpwuid(os.getuid())[0]
if MYUID == 'root':
MYUID = os.environ['SUDO_USER']
## Fonctions internes au serveur
# Fonctions internes au serveur
def validate(roles, mode='r'):
"""Vérifie que l'appelant appartient bien aux roles précisés
......@@ -56,12 +57,14 @@ def validate(roles, mode='r'):
return True
return False
def getpath(filename, backup=False):
"""Récupère le chemin du fichier ``filename``"""
assert(isinstance(filename, unicode))
filename = filename.encode('utf-8')
return os.path.join(serverconfig.STORE, '%s.%s' % (filename, 'bak' if backup else 'json'))
def writefile(filename, contents):
"""Écrit le fichier avec les bons droits UNIX"""
os.umask(0077)
......@@ -69,6 +72,7 @@ def writefile(filename, contents):
f.write(contents.encode("utf-8"))
f.close()
class server_command(object):
"""
Une instance est un décorateur pour la fonction servant de commande
......@@ -89,7 +93,7 @@ class server_command(object):
#: Est-ce que ceci a besoin d'écrire ?
write = False
def __init__(self, name, stdin_input = False, write=False):
def __init__(self, name, stdin_input=False, write=False):
"""
* ``name`` nom de l'action telle qu'appelée par le client
* ``stdin_input`` si True, stdin sera lu en mode non-keepalive, et
......@@ -105,7 +109,7 @@ class server_command(object):
self.decorated = fun
return fun
## Fonction exposées par le serveur
# Fonction exposées par le serveur
@server_command('keep-alive')
def keepalive():
""" Commande permettant de réaliser un tunnel json (un datagramme par ligne)
......@@ -135,6 +139,7 @@ def keepalive():
print(json.dumps(out, encoding='utf-8'))
sys.stdout.flush()
@server_command('listroles')
def listroles():
"""Liste des roles existant et de leurs membres.
......@@ -146,11 +151,13 @@ def listroles():
d["whoami"] = MYUID
return d
@server_command('listkeys')
def listkeys():
"""Liste les usernames et les (mail, fingerprint) correspondants"""
return serverconfig.KEYS
@server_command('listfiles')
def listfiles():
"""Liste les fichiers dans l'espace de stockage, et les roles qui peuvent y accéder"""
......@@ -164,6 +171,7 @@ def listfiles():
files[fname] = file_dict["roles"]
return files
@server_command('restorefiles')
def restorefiles():
"""Si un fichier a été corrompu, on restore son dernier backup valide"""
......@@ -178,9 +186,9 @@ def restorefiles():
with open(fname+'.bak') as f:
line = f.readline()
backup = ''
while not (line==''):
while not (line == ''):
try:
line_dict = json.loads(line)
line_dict = json.loads(line)
if ('-----BEGIN PGP MESSAGE-----' in line_dict["contents"]):
backup = line
except:
......@@ -188,7 +196,7 @@ def restorefiles():
line = f.readline()
if not (backup == ''):
files[fname] = 'restored'
with open(fname+'.json','w') as f2:
with open(fname+'.json', 'w') as f2:
f2.write(backup)
else:
files[fname] = 'not restored'
......@@ -202,18 +210,21 @@ def getfile(filename):
try:
obj = json.loads(open(filepath).read())
if not validate(obj['roles']):
return [False, u"Vous n'avez pas les droits de lecture sur le fichier %s." % filename]
return [False, u"Vous n'avez pas les droits de lecture sur le fichier %s." % filename]
obj["filename"] = filename
return [True, obj]
except IOError:
return [False, u"Le fichier %s n'existe pas." % filename]
@server_command('getfiles', stdin_input=True)
def getfiles(filenames):
"""Récupère plusieurs fichiers, lit la liste des filenames demandés sur stdin"""
return [getfile(f) for f in filenames]
# TODO ça n'a rien à faire là, à placer plus haut dans le code
def _putfile(filename, roles, contents):
"""Écrit ``contents`` avec les roles ``roles`` dans le fichier ``filename``
"""
......@@ -233,7 +244,7 @@ def _putfile(filename, roles, contents):
filepath = getpath(filename)
if type(contents) != unicode:
return [False, u"Erreur: merci de patcher votre cpasswords !"
+ "(contents should be encrypted str)"]
+ "(contents should be encrypted str)"]
# Or fuck yourself
writefile(filepath, json.dumps({'roles': roles, 'contents': contents}))
......@@ -244,6 +255,7 @@ def _putfile(filename, roles, contents):
return [True, u"Modification effectuée."]
@server_command('putfile', stdin_input=True, write=True)
def putfile(filename, parsed_stdin):
"""Écrit le fichier ``filename`` avec les données reçues sur stdin."""
......@@ -254,6 +266,7 @@ def putfile(filename, parsed_stdin):
return [False, u"Entrée invalide"]
return _putfile(filename, roles, contents)
@server_command('putfiles', stdin_input=True, write=True)
def putfiles(parsed_stdin):
"""Écrit plusieurs fichiers. Lit les filenames sur l'entrée standard avec le
......@@ -270,12 +283,13 @@ def putfiles(parsed_stdin):
results.append(_putfile(filename, roles, contents))
return results
@server_command('rmfile', write=True)
def rmfile(filename):
"""Supprime le fichier filename après avoir vérifié les droits sur le fichier"""
gotit, old = getfile(filename)
if not gotit:
return old # contient le message d'erreur
return old # contient le message d'erreur
roles = old['roles']
if validate(roles, 'w'):
corps = u"Le fichier %s a été supprimé par %s." % (filename, MYUID)
......@@ -294,9 +308,11 @@ def backup(corps, fname, old):
back = open(getpath(fname, backup=True), 'a')
back.write(json.dumps(old))
back.write('\n')
back.write((u'* %s: %s\n' % (str(datetime.datetime.now()), corps)).encode("utf-8"))
back.write((u'* %s: %s\n' %
(str(datetime.datetime.now()), corps)).encode("utf-8"))
back.close()
def _list_to_replicate(data):
"""Renvoie une liste d'options clients sur lesquels appliquer relancer
la procédure (pour réplication auto)"""
......@@ -305,13 +321,17 @@ def _list_to_replicate(data):
servers = getattr(serverconfig, 'BACKUP_SERVERS', {})
configs = set(name for role in roles for name in backups.get(role, []))
return [ clientlib.Client(servers[name]) for name in configs ]
return [clientlib.Client(servers[name]) for name in configs]
_notif_todo = []
def notification(action, fname, actor):
"""Enregistre une notification"""
_notif_todo.append((action, fname, actor))
def notification_mail():
"""Envoie par mail une notification de changement de fichier"""
if not _notif_todo:
......@@ -320,7 +340,7 @@ def notification_mail():
frommail = serverconfig.CRANSP_MAIL
tomail = serverconfig.DEST_MAIL
actions = set( task[1] for task in _notif_todo )
actions = set(task[1] for task in _notif_todo)
msg = MIMEMultipart(_charset="utf-8")
msg['Subject'] = u"Modification de la base (%s)" % (', '.join(actions))
......@@ -332,14 +352,16 @@ def notification_mail():
liste = (u" * %s de %s par %s" % task for task in _notif_todo)
info = MIMEText(u"Des modifications ont été faites:\n" +
u"\n".join(liste) +
u"\n\nDes sauvegardes ont été réalisées." +
u"\n\nModification effectuée sur %s." % socket.gethostname() +
u"\n\n-- \nCranspasswords.py", _charset="utf-8")
u"\n".join(liste) +
u"\n\nDes sauvegardes ont été réalisées." +
u"\n\nModification effectuée sur %s." % socket.gethostname() +
u"\n\n-- \nCranspasswords.py", _charset="utf-8")
msg.attach(info)
mailProcess = subprocess.Popen([serverconfig.sendmail_cmd, "-t"], stdin=subprocess.PIPE)
mailProcess = subprocess.Popen(
[serverconfig.sendmail_cmd, "-t"], stdin=subprocess.PIPE)
mailProcess.communicate(msg.as_string())
if __name__ == "__main__":
argv = sys.argv[0:]
command_name = argv[1]
......@@ -350,7 +372,7 @@ if __name__ == "__main__":
args = argv[2:]
# On veut des unicode partout
args = [ s.decode('utf-8') for s in args ]
args = [s.decode('utf-8') for s in args]
if command.stdin_input:
args.append(json.loads(sys.stdin.read()))
answer = command.decorated(*args)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment