csh-ldap 2.5.3__tar.gz → 2.5.4.dev4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/AUTHORS +4 -0
  2. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/ChangeLog +4 -0
  3. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/PKG-INFO +40 -8
  4. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/README.md +35 -3
  5. {csh_ldap-2.5.3/csh_ldap → csh_ldap-2.5.4.dev4/csh-ldap}/__init__.py +107 -0
  6. {csh_ldap-2.5.3/csh_ldap → csh_ldap-2.5.4.dev4/csh-ldap}/group.py +16 -3
  7. {csh_ldap-2.5.3/csh_ldap → csh_ldap-2.5.4.dev4/csh-ldap}/member.py +1 -1
  8. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/csh_ldap.egg-info/PKG-INFO +40 -8
  9. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/csh_ldap.egg-info/SOURCES.txt +4 -4
  10. csh_ldap-2.5.4.dev4/csh_ldap.egg-info/pbr.json +1 -0
  11. csh_ldap-2.5.4.dev4/csh_ldap.egg-info/top_level.txt +1 -0
  12. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/setup.cfg +5 -5
  13. csh_ldap-2.5.3/csh_ldap.egg-info/pbr.json +0 -1
  14. csh_ldap-2.5.3/csh_ldap.egg-info/top_level.txt +0 -1
  15. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/.github/workflows/python.yaml +0 -0
  16. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/.pylintrc +0 -0
  17. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/LICENSE +0 -0
  18. {csh_ldap-2.5.3/csh_ldap → csh_ldap-2.5.4.dev4/csh-ldap}/utility.py +0 -0
  19. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/csh_ldap.egg-info/dependency_links.txt +0 -0
  20. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/csh_ldap.egg-info/not-zip-safe +0 -0
  21. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/csh_ldap.egg-info/requires.txt +0 -0
  22. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/requirements-test.txt +0 -0
  23. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/requirements.txt +0 -0
  24. {csh_ldap-2.5.3 → csh_ldap-2.5.4.dev4}/setup.py +0 -0
@@ -8,6 +8,10 @@ Liam Middlebrook <liammiddlebrook@gmail.com>
8
8
  Marc Billow <mbillow@me.com>
9
9
  Max Meinhold <mxmeinhold@gmail.com>
10
10
  Michael Francis <mikefrancis95@gmail.com>
11
+ Noah Hanford (spaced) <spaced@csh.rit.edu>
12
+ Noah Hanford <bigspaceships56@gmail.com>
13
+ Noah Hanford <spaced@csh.rit.edu>
11
14
  Tyler Allen <tyler@tallen.me>
12
15
  William Stevens <contact@wastevensv.com>
13
16
  dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
17
+ tyler <137842227+goosenotduck@users.noreply.github.com>
@@ -1,6 +1,10 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ * bump: 2.5.4
5
+ * feat: added methods to get member data while combining groups (#44)
6
+ * Fix subgroups (#43)
7
+
4
8
  2.5.3
5
9
  -----
6
10
 
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
- Name: csh_ldap
3
- Version: 2.5.3
2
+ Name: csh-ldap
3
+ Version: 2.5.4.dev4
4
4
  Summary: CSH LDAP ORM
5
- Home-page: https://github.com/ComputerScienceHouse/csh_ldap
6
- Author: Liam Middlebrook
7
- Author-email: liammiddlebrook@gmail.com
5
+ Home-page: https://github.com/ComputerScienceHouse/csh-ldap
6
+ Author: CSH RTP
7
+ Author-email: rtp@csh.rit.edu
8
8
  License: MIT
9
9
  Classifier: Natural Language :: English
10
10
  Classifier: Operating System :: POSIX :: Linux
@@ -21,7 +21,7 @@ Dynamic: license-file
21
21
  Dynamic: requires-dist
22
22
  Dynamic: summary
23
23
 
24
- # csh_ldap
24
+ # csh-ldap
25
25
 
26
26
  [![PyPI version](https://badge.fury.io/py/csh_ldap.svg)](https://badge.fury.io/py/csh_ldap)
27
27
  [![Build Status](https://travis-ci.org/liam-middlebrook/csh_ldap.svg?branch=master)](https://travis-ci.org/liam-middlebrook/csh_ldap)
@@ -31,13 +31,13 @@ Python 3 ORM for CSH LDAP
31
31
 
32
32
  ## Installation
33
33
 
34
- `pip install csh_ldap`
34
+ `pip install csh-ldap`
35
35
 
36
36
 
37
37
  ## Usage
38
38
 
39
39
  ```
40
- import csh_ldap
40
+ import csh-ldap
41
41
 
42
42
  # Create an unbatched instance
43
43
  instance = csh_ldap.CSHLDAP(bind_dn, bind_pw)
@@ -63,6 +63,38 @@ liam = instance.get_member_slackuid(slack_uid)
63
63
  # Get group by cn
64
64
  rtp = instance.get_group('rtp')
65
65
 
66
+ # get group member uids
67
+ rtp = instance.get_group('rtp').get_member_uids()
68
+ # returns ['spaced', ...]
69
+
70
+ # get group member uids (other way)
71
+ rtp = instance.get_group_member_uids(groups=["rtp"])
72
+
73
+ # get uids of members in two (or more) groups and not in groups
74
+ fancy = instance.get_group_member_uids(groups=["rtp", "onfloor"], excluded=["eboard-opcomm"])
75
+
76
+ # get uuids of members in two (or more) groups and not in groups
77
+ # that's right! ipaUniqueId
78
+ fancy = instance.get_group_member_uuids(groups=["rtp", "onfloor"], excluded=["eboard-opcomm"])
79
+
80
+ # get other miscellaneous attributes of members in group
81
+ # look how rich drink admins are (admin abuse!!!)
82
+ admin_abuse = instance.get_group_member_attributes(group=["drink"], attributes=["uid", "drinkBalance"])
83
+ # returns dicts for each member
84
+ """
85
+ I wonder what happened here
86
+ [
87
+ {
88
+ 'uid': 'cole',
89
+ 'drinkBalance': '996246'
90
+ },
91
+ {
92
+ 'uid': 'zxcv',
93
+ 'drinkBalance': '3847173'
94
+ }
95
+ ]
96
+ """
97
+
66
98
  # Get cn of member
67
99
  print(liam.cn)
68
100
 
@@ -1,4 +1,4 @@
1
- # csh_ldap
1
+ # csh-ldap
2
2
 
3
3
  [![PyPI version](https://badge.fury.io/py/csh_ldap.svg)](https://badge.fury.io/py/csh_ldap)
4
4
  [![Build Status](https://travis-ci.org/liam-middlebrook/csh_ldap.svg?branch=master)](https://travis-ci.org/liam-middlebrook/csh_ldap)
@@ -8,13 +8,13 @@ Python 3 ORM for CSH LDAP
8
8
 
9
9
  ## Installation
10
10
 
11
- `pip install csh_ldap`
11
+ `pip install csh-ldap`
12
12
 
13
13
 
14
14
  ## Usage
15
15
 
16
16
  ```
17
- import csh_ldap
17
+ import csh-ldap
18
18
 
19
19
  # Create an unbatched instance
20
20
  instance = csh_ldap.CSHLDAP(bind_dn, bind_pw)
@@ -40,6 +40,38 @@ liam = instance.get_member_slackuid(slack_uid)
40
40
  # Get group by cn
41
41
  rtp = instance.get_group('rtp')
42
42
 
43
+ # get group member uids
44
+ rtp = instance.get_group('rtp').get_member_uids()
45
+ # returns ['spaced', ...]
46
+
47
+ # get group member uids (other way)
48
+ rtp = instance.get_group_member_uids(groups=["rtp"])
49
+
50
+ # get uids of members in two (or more) groups and not in groups
51
+ fancy = instance.get_group_member_uids(groups=["rtp", "onfloor"], excluded=["eboard-opcomm"])
52
+
53
+ # get uuids of members in two (or more) groups and not in groups
54
+ # that's right! ipaUniqueId
55
+ fancy = instance.get_group_member_uuids(groups=["rtp", "onfloor"], excluded=["eboard-opcomm"])
56
+
57
+ # get other miscellaneous attributes of members in group
58
+ # look how rich drink admins are (admin abuse!!!)
59
+ admin_abuse = instance.get_group_member_attributes(group=["drink"], attributes=["uid", "drinkBalance"])
60
+ # returns dicts for each member
61
+ """
62
+ I wonder what happened here
63
+ [
64
+ {
65
+ 'uid': 'cole',
66
+ 'drinkBalance': '996246'
67
+ },
68
+ {
69
+ 'uid': 'zxcv',
70
+ 'drinkBalance': '3847173'
71
+ }
72
+ ]
73
+ """
74
+
43
75
  # Get cn of member
44
76
  print(liam.cn)
45
77
 
@@ -149,6 +149,113 @@ class CSHLDAP:
149
149
  True)
150
150
  for dn in ret]
151
151
 
152
+ def get_query_for_groups(self, groups = None, excluded_groups = None):
153
+ """Returns the ldap query string to get members in groups but not in others
154
+
155
+ Argumenets:
156
+ groups -- the groups members must be a member of
157
+ excluded_groups -- the groups members cannot be a part of
158
+ """
159
+
160
+ group_dns = [f"(memberOf=cn={group},cn=groups,cn=accounts,dc=csh,dc=rit,dc=edu)" for group in groups]
161
+ excluded_group_dns = [
162
+ f"(memberOf=cn={group},cn=groups,cn=accounts,dc=csh,dc=rit,dc=edu)"
163
+ for group in excluded_groups
164
+ ]
165
+
166
+ query = ""
167
+
168
+ for group in group_dns:
169
+ if query == "":
170
+ query = group
171
+ continue
172
+
173
+ query = f"(&{query}{group})"
174
+
175
+ for group in excluded_group_dns:
176
+ group = f"(!{group})"
177
+ if query == "":
178
+ query = group
179
+ continue
180
+
181
+ query = f"(&{query}{group})"
182
+
183
+ return query
184
+
185
+ def get_group_member_attributes(self, groups = None, excluded_groups = None, attributes = None):
186
+ """Returns a list of dicts containing all the attributes requested in the groups listed in groups,
187
+ but not in exlcuded_groups
188
+
189
+ Arguements:
190
+ groups -- the groups members must be a member of
191
+ excluded_groups -- the groups members cannot be a part of
192
+ attributues -- the ldap attributes to return, defaults to uid
193
+ """
194
+
195
+ # I HATE PYTHON
196
+ if attributes is None:
197
+ attributes = ['uid']
198
+
199
+ query_result = self.__con__.search_s(
200
+ "dc=csh,dc=rit,dc=edu",
201
+ ldap.SCOPE_SUBTREE,
202
+ self.get_query_for_groups(groups=groups, excluded_groups=excluded_groups),
203
+ attributes)
204
+
205
+ # the rest of this could be one giant list compression but I don't hate you that much so I chose not to
206
+
207
+ # filter out subgroups, probably the second check all we need
208
+ # but if we used just the second one but the first one was empty that would probably be confusing?
209
+ byte_result = [member[1] for member in query_result if not member[1] == {} and "cn=users" in member[0]]
210
+
211
+ result = []
212
+
213
+ for byte_member in byte_result:
214
+ # decoding the byte strings
215
+ result.append({key: value[0].decode('utf-8') for (key, value) in byte_member.items()})
216
+
217
+ return result
218
+
219
+ def get_group_member_uids(self, groups = None, excluded_groups = None):
220
+ """Get a list of member uids in a group
221
+
222
+ Arguements:
223
+ groups -- the groups members must be a member of
224
+ excluded_groups -- the groups members cannot be a part of
225
+ """
226
+
227
+ query_result = self.__con__.search_s(
228
+ "dc=csh,dc=rit,dc=edu",
229
+ ldap.SCOPE_SUBTREE,
230
+ self.get_query_for_groups(groups=groups, excluded_groups=excluded_groups),
231
+ ['uid'])
232
+
233
+ return [
234
+ member[1]['uid'][0].decode('utf-8')
235
+ for member in query_result
236
+ if not member[1] == {} and "cn=users" in member[0]
237
+ ]
238
+
239
+ def get_group_member_uuids(self, groups = None, excluded_groups = None):
240
+ """Get a list of member uuids in a group (ipaUniqueId)
241
+
242
+ Arguements:
243
+ groups -- the groups members must be a member of
244
+ excluded_groups -- the groups members cannot be a part of
245
+ """
246
+
247
+ query_result = self.__con__.search_s(
248
+ "dc=csh,dc=rit,dc=edu",
249
+ ldap.SCOPE_SUBTREE,
250
+ self.get_query_for_groups(groups=groups, excluded_groups=excluded_groups),
251
+ ['ipaUniqueId'])
252
+
253
+ return [
254
+ member[1]['ipaUniqueId'][0].decode('utf-8')
255
+ for member in query_result
256
+ if not member[1] == {} and "cn=users" in member[0]
257
+ ]
258
+
152
259
  def enqueue_mod(self, dn, mod):
153
260
  """Enqueue a LDAP modification.
154
261
 
@@ -30,8 +30,9 @@ class CSHGroup:
30
30
  raise KeyError("Invalid Search Name")
31
31
 
32
32
  @reconnect_on_fail
33
- def get_members(self):
34
- """Return all members in the group as CSHMember objects"""
33
+ def get_member_uids(self):
34
+ """Return the uids of all members in the group"""
35
+
35
36
  res = self.__con__.search_s(
36
37
  self.__ldap_base_dn__,
37
38
  ldap.SCOPE_SUBTREE,
@@ -40,6 +41,9 @@ class CSHGroup:
40
41
 
41
42
  ret = []
42
43
  for val in res:
44
+ if 'uid' not in val[1]:
45
+ continue
46
+
43
47
  val = val[1]['uid'][0]
44
48
  try:
45
49
  ret.append(val.decode('utf-8'))
@@ -48,10 +52,19 @@ class CSHGroup:
48
52
  except KeyError:
49
53
  continue
50
54
 
55
+ return ret
56
+
57
+
58
+ @reconnect_on_fail
59
+ def get_members(self):
60
+ """Return all members in the group as CSHMember objects"""
61
+
62
+ uids = self.get_member_uids()
63
+
51
64
  return [CSHMember(self.__lib__,
52
65
  result,
53
66
  uid=True)
54
- for result in ret]
67
+ for result in uids]
55
68
 
56
69
  @reconnect_on_fail
57
70
  def check_member(self, member, dn=False):
@@ -139,7 +139,7 @@ class CSHMember:
139
139
  if value is None:
140
140
  mod = (ldap_mod, key, None)
141
141
  else:
142
- mod = (ldap_mod, key, value.encode('ascii'))
142
+ mod = (ldap_mod, key, value.encode('utf-8'))
143
143
 
144
144
  if self.__lib__.__batch_mods__:
145
145
  self.__lib__.enqueue_mod(self.__dn__, mod)
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
- Name: csh_ldap
3
- Version: 2.5.3
2
+ Name: csh-ldap
3
+ Version: 2.5.4.dev4
4
4
  Summary: CSH LDAP ORM
5
- Home-page: https://github.com/ComputerScienceHouse/csh_ldap
6
- Author: Liam Middlebrook
7
- Author-email: liammiddlebrook@gmail.com
5
+ Home-page: https://github.com/ComputerScienceHouse/csh-ldap
6
+ Author: CSH RTP
7
+ Author-email: rtp@csh.rit.edu
8
8
  License: MIT
9
9
  Classifier: Natural Language :: English
10
10
  Classifier: Operating System :: POSIX :: Linux
@@ -21,7 +21,7 @@ Dynamic: license-file
21
21
  Dynamic: requires-dist
22
22
  Dynamic: summary
23
23
 
24
- # csh_ldap
24
+ # csh-ldap
25
25
 
26
26
  [![PyPI version](https://badge.fury.io/py/csh_ldap.svg)](https://badge.fury.io/py/csh_ldap)
27
27
  [![Build Status](https://travis-ci.org/liam-middlebrook/csh_ldap.svg?branch=master)](https://travis-ci.org/liam-middlebrook/csh_ldap)
@@ -31,13 +31,13 @@ Python 3 ORM for CSH LDAP
31
31
 
32
32
  ## Installation
33
33
 
34
- `pip install csh_ldap`
34
+ `pip install csh-ldap`
35
35
 
36
36
 
37
37
  ## Usage
38
38
 
39
39
  ```
40
- import csh_ldap
40
+ import csh-ldap
41
41
 
42
42
  # Create an unbatched instance
43
43
  instance = csh_ldap.CSHLDAP(bind_dn, bind_pw)
@@ -63,6 +63,38 @@ liam = instance.get_member_slackuid(slack_uid)
63
63
  # Get group by cn
64
64
  rtp = instance.get_group('rtp')
65
65
 
66
+ # get group member uids
67
+ rtp = instance.get_group('rtp').get_member_uids()
68
+ # returns ['spaced', ...]
69
+
70
+ # get group member uids (other way)
71
+ rtp = instance.get_group_member_uids(groups=["rtp"])
72
+
73
+ # get uids of members in two (or more) groups and not in groups
74
+ fancy = instance.get_group_member_uids(groups=["rtp", "onfloor"], excluded=["eboard-opcomm"])
75
+
76
+ # get uuids of members in two (or more) groups and not in groups
77
+ # that's right! ipaUniqueId
78
+ fancy = instance.get_group_member_uuids(groups=["rtp", "onfloor"], excluded=["eboard-opcomm"])
79
+
80
+ # get other miscellaneous attributes of members in group
81
+ # look how rich drink admins are (admin abuse!!!)
82
+ admin_abuse = instance.get_group_member_attributes(group=["drink"], attributes=["uid", "drinkBalance"])
83
+ # returns dicts for each member
84
+ """
85
+ I wonder what happened here
86
+ [
87
+ {
88
+ 'uid': 'cole',
89
+ 'drinkBalance': '996246'
90
+ },
91
+ {
92
+ 'uid': 'zxcv',
93
+ 'drinkBalance': '3847173'
94
+ }
95
+ ]
96
+ """
97
+
66
98
  # Get cn of member
67
99
  print(liam.cn)
68
100
 
@@ -8,10 +8,10 @@ requirements.txt
8
8
  setup.cfg
9
9
  setup.py
10
10
  .github/workflows/python.yaml
11
- csh_ldap/__init__.py
12
- csh_ldap/group.py
13
- csh_ldap/member.py
14
- csh_ldap/utility.py
11
+ csh-ldap/__init__.py
12
+ csh-ldap/group.py
13
+ csh-ldap/member.py
14
+ csh-ldap/utility.py
15
15
  csh_ldap.egg-info/PKG-INFO
16
16
  csh_ldap.egg-info/SOURCES.txt
17
17
  csh_ldap.egg-info/dependency_links.txt
@@ -0,0 +1 @@
1
+ {"git_version": "506d989", "is_release": false}
@@ -0,0 +1 @@
1
+ csh-ldap
@@ -1,13 +1,13 @@
1
1
  [metadata]
2
- name = csh_ldap
3
- author = Liam Middlebrook
4
- author_email = liammiddlebrook@gmail.com
5
- url = https://github.com/ComputerScienceHouse/csh_ldap
2
+ name = csh-ldap
3
+ author = CSH RTP
4
+ author_email = rtp@csh.rit.edu
5
+ url = https://github.com/ComputerScienceHouse/csh-ldap
6
6
  description = CSH LDAP ORM
7
7
  long_description = file: README.md
8
8
  long_description_content_type = text/markdown
9
9
  license = MIT
10
- version = 2.5.3
10
+ version = 2.5.4
11
11
  classifier =
12
12
  Natural Language :: English
13
13
  Operating System :: POSIX :: Linux
@@ -1 +0,0 @@
1
- {"git_version": "1bfdfae", "is_release": false}
@@ -1 +0,0 @@
1
- csh_ldap
File without changes
File without changes
File without changes
File without changes