Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Crans Passwords
Manage
Activity
Members
Labels
Plan
Issues
5
Issue boards
Milestones
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Nounous
Crans Passwords
Commits
46235968
Verified
Commit
46235968
authored
4 years ago
by
me5na7qbjqbrp
Browse files
Options
Downloads
Patches
Plain Diff
autopep8 on server
parent
57a32c24
No related branches found
No related tags found
1 merge request
!7
Create pip package
Pipeline
#2880
passed with warnings with stage
in 39 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
cpasswords/server.py
+40
-18
40 additions, 18 deletions
cpasswords/server.py
with
40 additions
and
18 deletions
cpasswords/server.py
+
40
−
18
View file @
46235968
...
...
@@ -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\n
Des sauvegardes ont été réalisées.
"
+
u
"
\n\n
Modification effectuée sur %s.
"
%
socket
.
gethostname
()
+
u
"
\n\n
--
\n
Cranspasswords.py
"
,
_charset
=
"
utf-8
"
)
u
"
\n
"
.
join
(
liste
)
+
u
"
\n\n
Des sauvegardes ont été réalisées.
"
+
u
"
\n\n
Modification effectuée sur %s.
"
%
socket
.
gethostname
()
+
u
"
\n\n
--
\n
Cranspasswords.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
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment