1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
126
127
128
129
130
131
132
133
134
135
136
137
|
"""Kazoo Security"""
from base64 import b64encode
from collections import namedtuple
import hashlib
# Represents a Zookeeper ID and ACL object
Id = namedtuple('Id', 'scheme id')
class ACL(namedtuple('ACL', 'perms id')):
"""An ACL for a Zookeeper Node
An ACL object is created by using an :class:`Id` object along with
a :class:`Permissions` setting. For convenience,
:meth:`make_digest_acl` should be used to create an ACL object with
the desired scheme, id, and permissions.
"""
@property
def acl_list(self):
perms = []
if self.perms & Permissions.ALL == Permissions.ALL:
perms.append('ALL')
return perms
if self.perms & Permissions.READ == Permissions.READ:
perms.append('READ')
if self.perms & Permissions.WRITE == Permissions.WRITE:
perms.append('WRITE')
if self.perms & Permissions.CREATE == Permissions.CREATE:
perms.append('CREATE')
if self.perms & Permissions.DELETE == Permissions.DELETE:
perms.append('DELETE')
if self.perms & Permissions.ADMIN == Permissions.ADMIN:
perms.append('ADMIN')
return perms
def __repr__(self):
return 'ACL(perms=%r, acl_list=%s, id=%r)' % (
self.perms, self.acl_list, self.id)
class Permissions(object):
READ = 1
WRITE = 2
CREATE = 4
DELETE = 8
ADMIN = 16
ALL = 31
# Shortcuts for common Ids
ANYONE_ID_UNSAFE = Id('world', 'anyone')
AUTH_IDS = Id('auth', '')
# Shortcuts for common ACLs
OPEN_ACL_UNSAFE = [ACL(Permissions.ALL, ANYONE_ID_UNSAFE)]
CREATOR_ALL_ACL = [ACL(Permissions.ALL, AUTH_IDS)]
READ_ACL_UNSAFE = [ACL(Permissions.READ, ANYONE_ID_UNSAFE)]
def make_digest_acl_credential(username, password):
"""Create a SHA1 digest credential"""
credential = username.encode('utf-8') + b":" + password.encode('utf-8')
cred_hash = b64encode(hashlib.sha1(credential).digest()).strip()
return username + ":" + cred_hash.decode('utf-8')
def make_acl(scheme, credential, read=False, write=False,
create=False, delete=False, admin=False, all=False):
"""Given a scheme and credential, return an :class:`ACL` object
appropriate for use with Kazoo.
:param scheme: The scheme to use. I.e. `digest`.
:param credential:
A colon separated username, password. The password should be
hashed with the `scheme` specified. The
:meth:`make_digest_acl_credential` method will create and
return a credential appropriate for use with the `digest`
scheme.
:param write: Write permission.
:type write: bool
:param create: Create permission.
:type create: bool
:param delete: Delete permission.
:type delete: bool
:param admin: Admin permission.
:type admin: bool
:param all: All permissions.
:type all: bool
:rtype: :class:`ACL`
"""
if all:
permissions = Permissions.ALL
else:
permissions = 0
if read:
permissions |= Permissions.READ
if write:
permissions |= Permissions.WRITE
if create:
permissions |= Permissions.CREATE
if delete:
permissions |= Permissions.DELETE
if admin:
permissions |= Permissions.ADMIN
return ACL(permissions, Id(scheme, credential))
def make_digest_acl(username, password, read=False, write=False,
create=False, delete=False, admin=False, all=False):
"""Create a digest ACL for Zookeeper with the given permissions
This method combines :meth:`make_digest_acl_credential` and
:meth:`make_acl` to create an :class:`ACL` object appropriate for
use with Kazoo's ACL methods.
:param username: Username to use for the ACL.
:param password: A plain-text password to hash.
:param write: Write permission.
:type write: bool
:param create: Create permission.
:type create: bool
:param delete: Delete permission.
:type delete: bool
:param admin: Admin permission.
:type admin: bool
:param all: All permissions.
:type all: bool
:rtype: :class:`ACL`
"""
cred = make_digest_acl_credential(username, password)
return make_acl("digest", cred, read=read, write=write, create=create,
delete=delete, admin=admin, all=all)
|