Newer
Older
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""cranspasswords-server.py: Serveur pour cranspasswords"""
MYDIR = '/root/cranspasswords/'
STORE = MYDIR+'db/'
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
MYUID = pwd.getpwuid(os.getuid())[0]
if MYUID == 'root':
MYUID = os.environ['SUDO_USER']
KEYS = {
"aza-vallina": ("Damien.Aza-Vallina@crans.org", None),
"dandrimont": ("nicolas.dandrimont@crans.org", "66475AAF"),
"blockelet": ("blockelet@crans.org", "AF087A52"),
"chambart": ("pierre.chambart@crans.org", "F2530FCE"),
"dimino": ("jdimino@dptinfo.ens-cachan.fr", "2127F85A"),
"durand-gasselin": ("adg@crans.org", "8E96ACDA"),
"glondu": ("Stephane.Glondu@crans.org", "49881AD3"),
"huber": ("olivier.huber@crans.org", "E0DCF376"),
"lagorce": ("xavier.lagorce@crans.org", "0BF3708E"),
"parret-freaud": ("parret-freaud@crans.org", "7D980513"),
"tvincent": ("vincent.thomas@crans.org", "C5C4ACC0"),
"iffrig": ("iffrig@crans.org","5BEC9A2F"),
"becue": ("becue@crans.org", "194974E2"),
"dstan": ("daniel.stan@crans.org", "6E1C820B"),
"boilard": ("boilard@crans.org", "C39EB6F4"),
"cauderlier": ("cauderlier@crans.org",None), #Méchant pas beau
"maioli": ("maioli@crans.org",None), #Bis (maybe 9E5026E8)
"legallic": ("legallic@crans.org", "3784CFC3"),
RTC=[
"iffrig"
]
NOUNOUS=RTC+[
"blockelet",
"becue",
"dstan",
"chambart",
"dimino",
"durand-gasselin",
"glondu",
"huber",
"lagorce",
"parret-freaud",
"cauderlier",
def validate(roles,mode='r'):
"""Valide que l'appelant appartient bien aux roles précisés
Si mode mode='w', recherche un rôle en écriture
"""
if mode == 'w': role+='-w'
if ROLES.has_key(role) and MYUID in ROLES[role]:
return os.path.join(STORE, '%s.%s' % (filename,'bak' if backup else 'json'))
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
def writefile(filename, contents):
"""Écrit le fichier de manière sécure"""
os.umask(0077)
f = open(filename, 'w')
f.write(contents)
f.close()
def listroles():
"""Liste des roles existant et de leurs membres"""
return ROLES
def listkeys():
"""Liste les uid et les clés correspondantes"""
return KEYS
def listfiles():
"""Liste les fichiers dans l'espace de stockage, et les roles qui peuvent y accéder"""
os.chdir(STORE)
filenames = glob.glob('*.json')
files = {}
for filename in filenames:
file_dict = json.loads(open(filename).read())
files[filename[:-5]] = file_dict["roles"]
return files
def getfile(filename):
"""Récupère le fichier `filename'"""
filepath = getpath(filename)
try:
obj = json.loads(open(filepath).read())
if not validate(obj['roles']):
return False
return obj
except IOError:
return False
def putfile(filename):
"""Écrit le fichier `filename' avec les données reçues sur stdin."""
filepath = getpath(filename)
stdin = sys.stdin.read()
parsed_stdin = json.loads(stdin)
try:
roles = parsed_stdin['roles']
contents = parsed_stdin['contents']
except KeyError:
return False
try:
old = getfile(filename)
oldroles = old['roles']
notification("Modification de %s" % filename,\
"Le fichier %s a été modifié par %s." %\
writefile(filepath, json.dumps({'roles': roles, 'contents': contents}))
return True
def rmfile(filename):
"""Supprime le fichier filename après avoir vérifié les droits sur le fichier"""
try:
old = getfile(filename)
roles = old['roles']
notification("Suppression de %s" % filename,\
"Le fichier %s a été supprimé par %s." %\
os.remove(getpath(filename))
else:
return False
return True
def notification(subject,corps,fname,old):
back = open(getpath(fname,True),'a')
back.write(json.dumps(old))
back.write('\n')
back.write('* %s: %s\n' % (str(datetime.datetime.now()),corps))
back.close()
# Puis envoi du message
conn = smtplib.SMTP('localhost')
frommail = CRANSP_MAIL
tomail = DEST_MAIL
msg = MIMEMultipart(_charset="utf-8")
msg['Subject'] = subject
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = "cranspasswords <%s>" % CRANSP_MAIL
msg['To'] = DEST_MAIL
msg.preamble = "cranspasswords report"
"\nLa version précédente a été sauvegardée." +
"\n\n-- \nCranspasswords.py",_charset="utf-8")
msg.attach(info)
#old = MIMEText(old)
#old.add_header('Content-Disposition', 'attachment', filename=fname)
conn.sendmail(frommail,tomail,msg.as_string())
conn.quit()
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
if __name__ == "__main__":
argv = sys.argv[1:]
if len(argv) not in [1, 2]:
sys.exit(1)
command = argv[0]
filename = None
try:
filename = argv[1]
except IndexError:
pass
if command == "listroles":
print json.dumps(listroles())
elif command == "listkeys":
print json.dumps(listkeys())
elif command == "listfiles":
print json.dumps(listfiles())
else:
if not filename:
sys.exit(1)
if command == "getfile":
print json.dumps(getfile(filename))
elif command == "putfile":
print json.dumps(putfile(filename))
elif command == "rmfile":
print json.dumps(rmfile(filename))
else:
sys.exit(1)