annotate rhodecode/bin/ldap_sync.py @ 3903:ddd05df2aced beta

added more info into __repr__ of auth user for better debugging and logging
author Marcin Kuzminski <marcin@python-works.com>
date Tue, 28 May 2013 16:21:27 +0200
parents b84c83b651de
children ffd45b185016
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3556
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
1 # This program is free software: you can redistribute it and/or modify
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
2 # it under the terms of the GNU General Public License as published by
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
3 # the Free Software Foundation, either version 3 of the License, or
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
4 # (at your option) any later version.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
5 #
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
6 # This program is distributed in the hope that it will be useful,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
9 # GNU General Public License for more details.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
10 #
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
11 # You should have received a copy of the GNU General Public License
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
12 # along with this program. If not, see <http://www.gnu.org/licenses/>.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
13
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
14 import ldap
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
15 import urllib2
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
16 import uuid
3705
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
17
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
18 try:
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
19 from rhodecode.lib.compat import json
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
20 except ImportError:
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
21 try:
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
22 import simplejson as json
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
23 except ImportError:
f37d7514e7ab always use json from compat module
Marcin Kuzminski <marcin@python-works.com>
parents: 3556
diff changeset
24 import json
3556
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
25
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
26 from ConfigParser import ConfigParser
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
27
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
28 config = ConfigParser()
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
29 config.read('ldap_sync.conf')
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
30
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
31
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
32 class InvalidResponseIDError(Exception):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
33 """ Request and response don't have the same UUID. """
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
34
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
35
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
36 class RhodecodeResponseError(Exception):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
37 """ Response has an error, something went wrong with request execution. """
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
38
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
39
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
40 class UserAlreadyInGroupError(Exception):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
41 """ User is already a member of the target group. """
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
42
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
43
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
44 class UserNotInGroupError(Exception):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
45 """ User is not a member of the target group. """
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
46
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
47
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
48 class RhodecodeAPI():
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
49
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
50 def __init__(self, url, key):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
51 self.url = url
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
52 self.key = key
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
53
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
54 def get_api_data(self, uid, method, args):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
55 """Prepare dict for API post."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
56 return {
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
57 "id": uid,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
58 "api_key": self.key,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
59 "method": method,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
60 "args": args
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
61 }
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
62
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
63 def rhodecode_api_post(self, method, args):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
64 """Send a generic API post to Rhodecode.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
65
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
66 This will generate the UUID for validation check after the
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
67 response is returned. Handle errors and get the result back.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
68 """
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
69 uid = str(uuid.uuid1())
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
70 data = self.get_api_data(uid, method, args)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
71
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
72 data = json.dumps(data)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
73 headers = {'content-type': 'text/plain'}
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
74 req = urllib2.Request(self.url, data, headers)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
75
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
76 response = urllib2.urlopen(req)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
77 response = json.load(response)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
78
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
79 if uid != response["id"]:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
80 raise InvalidResponseIDError("UUID does not match.")
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
81
3889
b84c83b651de replace equality comparision to None
Marcin Kuzminski <marcin@python-works.com>
parents: 3705
diff changeset
82 if response["error"] is not None:
3556
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
83 raise RhodecodeResponseError(response["error"])
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
84
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
85 return response["result"]
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
86
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
87 def create_group(self, name, active=True):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
88 """Create the Rhodecode user group."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
89 args = {
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
90 "group_name": name,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
91 "active": str(active)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
92 }
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
93 self.rhodecode_api_post("create_users_group", args)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
94
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
95 def add_membership(self, group, username):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
96 """Add specific user to a group."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
97 args = {
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
98 "usersgroupid": group,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
99 "userid": username
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
100 }
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
101 result = self.rhodecode_api_post("add_user_to_users_group", args)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
102 if not result["success"]:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
103 raise UserAlreadyInGroupError("User %s already in group %s." %
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
104 (username, group))
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
105
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
106 def remove_membership(self, group, username):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
107 """Remove specific user from a group."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
108 args = {
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
109 "usersgroupid": group,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
110 "userid": username
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
111 }
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
112 result = self.rhodecode_api_post("remove_user_from_users_group", args)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
113 if not result["success"]:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
114 raise UserNotInGroupError("User %s not in group %s." %
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
115 (username, group))
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
116
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
117 def get_group_members(self, name):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
118 """Get the list of member usernames from a user group."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
119 args = {"usersgroupid": name}
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
120 members = self.rhodecode_api_post("get_users_group", args)['members']
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
121 member_list = []
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
122 for member in members:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
123 member_list.append(member["username"])
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
124 return member_list
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
125
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
126 def get_group(self, name):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
127 """Return group info."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
128 args = {"usersgroupid": name}
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
129 return self.rhodecode_api_post("get_users_group", args)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
130
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
131 def get_user(self, username):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
132 """Return user info."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
133 args = {"userid": username}
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
134 return self.rhodecode_api_post("get_user", args)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
135
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
136
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
137 class LdapClient():
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
138
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
139 def __init__(self, uri, user, key, base_dn):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
140 self.client = ldap.initialize(uri, trace_level=0)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
141 self.client.set_option(ldap.OPT_REFERRALS, 0)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
142 self.client.simple_bind(user, key)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
143 self.base_dn = base_dn
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
144
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
145 def __del__(self):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
146 self.client.unbind()
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
147
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
148 def get_groups(self):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
149 """Get all the groups in form of dict {group_name: group_info,...}."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
150 searchFilter = "objectClass=groupOfUniqueNames"
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
151 result = self.client.search_s(self.base_dn, ldap.SCOPE_SUBTREE,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
152 searchFilter)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
153
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
154 groups = {}
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
155 for group in result:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
156 groups[group[1]['cn'][0]] = group[1]
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
157
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
158 return groups
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
159
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
160 def get_group_users(self, groups, group):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
161 """Returns all the users belonging to a single group.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
162
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
163 Based on the list of groups and memberships, returns all the
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
164 users belonging to a single group, searching recursively.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
165 """
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
166 users = []
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
167 for member in groups[group]["uniqueMember"]:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
168 member = self.parse_member_string(member)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
169 if member[0] == "uid":
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
170 users.append(member[1])
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
171 elif member[0] == "cn":
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
172 users += self.get_group_users(groups, member[1])
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
173
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
174 return users
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
175
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
176 def parse_member_string(self, member):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
177 """Parses the member string and returns a touple of type and name.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
178
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
179 Unique member can be either user or group. Users will have 'uid' as
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
180 prefix while groups will have 'cn'.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
181 """
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
182 member = member.split(",")[0]
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
183 return member.split('=')
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
184
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
185
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
186 class LdapSync(object):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
187
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
188 def __init__(self):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
189 self.ldap_client = LdapClient(config.get("default", "ldap_uri"),
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
190 config.get("default", "ldap_user"),
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
191 config.get("default", "ldap_key"),
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
192 config.get("default", "base_dn"))
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
193 self.rhodocode_api = RhodecodeAPI(config.get("default", "api_url"),
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
194 config.get("default", "api_key"))
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
195
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
196 def update_groups_from_ldap(self):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
197 """Add all the groups from LDAP to Rhodecode."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
198 added = existing = 0
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
199 groups = self.ldap_client.get_groups()
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
200 for group in groups:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
201 try:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
202 self.rhodecode_api.create_group(group)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
203 added += 1
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
204 except Exception:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
205 existing += 1
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
206
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
207 return added, existing
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
208
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
209 def update_memberships_from_ldap(self, group):
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
210 """Update memberships in rhodecode based on the LDAP groups."""
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
211 groups = self.ldap_client.get_groups()
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
212 group_users = self.ldap_client.get_group_users(groups, group)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
213
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
214 # Delete memberships first from each group which are not part
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
215 # of the group any more.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
216 rhodecode_members = self.rhodecode_api.get_group_members(group)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
217 for rhodecode_member in rhodecode_members:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
218 if rhodecode_member not in group_users:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
219 try:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
220 self.rhodocode_api.remove_membership(group,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
221 rhodecode_member)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
222 except UserNotInGroupError:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
223 pass
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
224
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
225 # Add memberships.
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
226 for member in group_users:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
227 try:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
228 self.rhodecode_api.add_membership(group, member)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
229 except UserAlreadyInGroupError:
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
230 # TODO: handle somehow maybe..
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
231 pass
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
232
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
233
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
234 if __name__ == '__main__':
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
235 sync = LdapSync()
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
236 print sync.update_groups_from_ldap()
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
237
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
238 for gr in sync.ldap_client.get_groups():
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
239 # TODO: exception when user does not exist during add membership...
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
240 # How should we handle this.. Either sync users as well at this step,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
241 # or just ignore those who don't exist. If we want the second case,
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
242 # we need to find a way to recognize the right exception (we always get
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
243 # RhodecodeResponseError with no error code so maybe by return msg (?)
4358b1b9307d added linaro ldap sync script
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
244 sync.update_memberships_from_ldap(gr)