ucb_groups 0.0.2

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8a70a98622c14e05dc6d97321b88fa49814fe37c
4
+ data.tar.gz: f7a84e130fabac3db97c20f6927151eca557b66b
5
+ SHA512:
6
+ metadata.gz: dbb318e65608a45bb2f15782012ab6e556592cc1102cc774198cff91402542ba9ecbc2cd87660b008b9007ae37021bc78d338050aa0679ac64d5f87f32888d4b
7
+ data.tar.gz: aa28f08ef4abddf05884c02a979acbf67e4312f57b19a0e65a6a42549edceba8c9ebc1d45808606f26f95c5f36fbef4dee11cb149170b5516698c23997a936f9
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.iml
19
+ *.idea
20
+ *.yml
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in calmsgs_groups.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 sahglie
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # UcbGroups
2
+
3
+ Finds users that belong to a given ucb group
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'ucb_groups'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ucb_groups
18
+
19
+ ## Usage
20
+
21
+ First, authenticate:
22
+ ```
23
+ UcbGroups::LdapConn.authenticate(<username>, <password>)
24
+ ```
25
+
26
+ Then...
27
+
28
+ Get list of groups in namespace:
29
+ ```
30
+ UcbGroups::CampusGroup.find(<namespace>)
31
+ => [CampusGroup, CampusGroup, ...]
32
+ ```
33
+
34
+ Find people in one or more groups:
35
+ ```
36
+ finder = UcbGroups::MembershipFinder.new(<namespace>)
37
+ people = finder.find(:groups => [grp1, grp2])
38
+ => [Person, Person, Person, ...]
39
+ ```
40
+
41
+ Find people in groups and filter by org:
42
+ ```
43
+ finder = UcbGroups::MembershipFinder.new(<namespace>)
44
+ people = finder.find(:groups => [grp1, grp2], :orgs => [:JKASD])
45
+ => [Person, Person, Person, ...]
46
+ ```
47
+
48
+ ## Contributing
49
+
50
+ 1. Fork it
51
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
52
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
53
+ 4. Push to the branch (`git push origin my-new-feature`)
54
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,31 @@
1
+ module UcbGroups
2
+ class CampusGroup
3
+ attr_accessor :dn, :description, :namespace, :name
4
+
5
+ def initialize(ldap_entry)
6
+ @dn = ldap_entry[:dn].first.to_s
7
+ @description = ldap_entry[:description].first.to_s
8
+ @namespace, @name = parse_dn
9
+ end
10
+
11
+ def self.find(namespace)
12
+ args = {
13
+ :base => "ou=campus groups,dc=berkeley,dc=edu",
14
+ :filter => build_filter(namespace),
15
+ :attributes => %w(dn description name),
16
+ }
17
+ LdapConn.conn.search(args).map { |entry| CampusGroup.new(entry) }
18
+ end
19
+
20
+ private
21
+
22
+ # example dn: "cn=edu:berkeley:app:calmessages:faculty,ou=campus groups,dc=berkeley,dc=edu"
23
+ def parse_dn
24
+ dn.split(/:|,/)[3..4].map(&:to_s)
25
+ end
26
+
27
+ def self.build_filter(namespace)
28
+ "(&(objectclass=*)(cn=edu:berkeley:app:#{namespace}*))"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ module UcbGroups
2
+ class LdapConn
3
+ def self.conn
4
+ net_ldap = ::Net::LDAP.new(auth_info)
5
+ net_ldap.bind || raise(BindFailedException)
6
+ net_ldap
7
+ rescue ::Net::LDAP::LdapError
8
+ raise(LdapBindFailedException)
9
+ end
10
+
11
+ def self.authenticate(username, password)
12
+ @username = username
13
+ @password = password
14
+ end
15
+
16
+ def self.authenticate_from_config(config_file)
17
+ conf = YAML.load_file(config_file)
18
+ @username, @password = conf['username'], conf['password']
19
+ end
20
+
21
+ private
22
+
23
+ def self.auth_info
24
+ @auth_info ||= {
25
+ host: "ldap.berkeley.edu",
26
+ auth: {
27
+ method: :simple,
28
+ username: @username,
29
+ password: @password,
30
+ },
31
+ port: 636,
32
+ encryption: { method: :simple_tls }
33
+ }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,50 @@
1
+ module UcbGroups
2
+ class MembershipFilter
3
+ attr_accessor :namespace, :groups, :orgs
4
+
5
+ def initialize(namespace, groups, orgs)
6
+ @namespace = namespace
7
+ @groups = groups
8
+ @orgs = orgs
9
+ end
10
+
11
+ def to_s
12
+ @filter ||= begin
13
+ if groups.empty?
14
+ objectclass_filter & orgs_filter
15
+ elsif orgs.empty?
16
+ objectclass_filter & groups_filter
17
+ else
18
+ objectclass_filter & (groups_filter & orgs_filter)
19
+ end
20
+ end
21
+ @filter.to_rfc2254
22
+ end
23
+
24
+ private
25
+
26
+ def objectclass_filter
27
+ Net::LDAP::Filter.eq("objectclass", "person")
28
+ end
29
+
30
+ def groups_filter
31
+ groups.map { |group| group_filter(group) }
32
+ .reduce { |accum, filter| accum.send("|", filter) }
33
+ end
34
+
35
+ def group_filter(group)
36
+ Net::LDAP::Filter.
37
+ eq("ismemberof",
38
+ "cn=edu:berkeley:app:#{self.namespace}:#{group},ou=campus groups,dc=berkeley,dc=edu")
39
+ end
40
+
41
+ def orgs_filter
42
+ @orgs.map { |org| org_filter(org) }
43
+ .reduce { |accum, filter| accum.send("|", filter) }
44
+ end
45
+
46
+ def org_filter(org)
47
+ Net::LDAP::Filter.eq("berkeleyedudeptunithierarchystring", "*#{org}*")
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,52 @@
1
+ module UcbGroups
2
+ class MembershipFinder
3
+ attr_accessor :namespace, :groups, :orgs
4
+
5
+ def initialize(namespace)
6
+ @namespace = namespace
7
+ end
8
+
9
+ def find(*options)
10
+ @groups, @orgs = parse_options(options)
11
+
12
+ return [] if @groups.empty? && @orgs.empty?
13
+
14
+ ensure_valid_options
15
+
16
+ args = {
17
+ base: "ou=people,dc=berkeley,dc=edu",
18
+ filter: membership_filter,
19
+ attributes: Person.ldap_attributes
20
+ }
21
+
22
+ LdapConn.conn.search(args).map { |entry| Person.new(entry) }
23
+ end
24
+
25
+ private
26
+
27
+ def parse_options(options)
28
+ options = options.first || {}
29
+ groups = options.fetch(:groups, []).map(&:to_s)
30
+ orgs = options.fetch(:orgs, []).map(&:to_s)
31
+
32
+ [groups, orgs]
33
+ end
34
+
35
+ def ensure_valid_options
36
+ groups.each do |group|
37
+ unless namespace_groups.include?(group.to_s)
38
+ raise(InvalidCampusGroupError.new(group))
39
+ end
40
+ end
41
+ end
42
+
43
+ def membership_filter
44
+ MembershipFilter.new(namespace, groups, orgs).to_s
45
+ end
46
+
47
+ def namespace_groups
48
+ @namespace_groups ||= CampusGroup.find(namespace).map(&:name)
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,38 @@
1
+ # Pull request with this patch has been submitted via github. As soon
2
+ # as this patch is merged into ruby-net-ldap master branch we can remove
3
+ # this monkey patch
4
+
5
+ Net::LDAP::Filter::FilterParser.class_eval do
6
+ def parse_filter_branch(scanner)
7
+ scanner.scan(/\s*/)
8
+ if token = scanner.scan(/[-\w:.]*[\w]/)
9
+ scanner.scan(/\s*/)
10
+ if op = scanner.scan(/<=|>=|!=|:=|=/)
11
+ scanner.scan(/\s*/)
12
+ #if value = scanner.scan(/(?:[-\w*.+@=,#\$%&!'\s]|\\[a-fA-F\d]{2})+/)
13
+
14
+ # Our patch allows ':' as a valid character.
15
+ if value = scanner.scan(/(?:[-\w*.+@=,:#\$%&!'\s]|\\[a-fA-F\d]{2})+/)
16
+ # 20100313 AZ: Assumes that "(uid=george*)" is the same as
17
+ # "(uid=george* )". The standard doesn't specify, but I can find
18
+ # no examples that suggest otherwise.
19
+ value.strip!
20
+
21
+ case op
22
+ when "="
23
+ Net::LDAP::Filter.eq(token, value)
24
+ when "!="
25
+ Net::LDAP::Filter.ne(token, value)
26
+ when "<="
27
+ Net::LDAP::Filter.le(token, value)
28
+ when ">="
29
+ Net::LDAP::Filter.ge(token, value)
30
+ when ":="
31
+ Net::LDAP::Filter.ex(token, value)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,41 @@
1
+ module UcbGroups
2
+ class Person
3
+ include Comparable
4
+
5
+ ATTRIBUTE_MAPPINGS = {
6
+ :uid => :uid,
7
+ :first_name => :givenname,
8
+ :last_name => :sn,
9
+ :email => :mail,
10
+ :orgs => :berkeleyEduPrimaryDeptUnitHierarchyString
11
+ }.freeze
12
+
13
+ attr_accessor *ATTRIBUTE_MAPPINGS.keys
14
+
15
+ def initialize(ldap_entry)
16
+ ATTRIBUTE_MAPPINGS.each do |attr, val|
17
+ self.send("#{attr}=", ldap_entry[val].first.to_s) if ldap_entry[val]
18
+ end
19
+ end
20
+
21
+ def full_name
22
+ [first_name, last_name].join(" ")
23
+ end
24
+
25
+ def self.ldap_attributes
26
+ @ldap_attributes ||= ATTRIBUTE_MAPPINGS.values.map(&:to_s)
27
+ end
28
+
29
+ def eql?(other_person)
30
+ self.hash == other_person.hash
31
+ end
32
+
33
+ def hash
34
+ self.uid.to_i
35
+ end
36
+
37
+ def <=>(other_person)
38
+ self.hash <=> other_person.hash
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module UcbGroups
2
+ VERSION = "0.0.2"
3
+ end
data/lib/ucb_groups.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'pp'
2
+ require 'ostruct'
3
+ require 'net-ldap'
4
+ require 'json'
5
+
6
+ require "ucb_groups/version"
7
+ require "ucb_groups/person"
8
+ require "ucb_groups/ldap_conn"
9
+ require "ucb_groups/campus_group"
10
+ require "ucb_groups/membership_filter"
11
+ require "ucb_groups/membership_finder"
12
+ require "ucb_groups/monkey_patches/net_ldap_filter"
13
+
14
+
15
+ module UcbGroups
16
+ LdapBindFailedException = Class.new(StandardError)
17
+
18
+ class InvalidCampusGroupError < StandardError
19
+ def initialize(group)
20
+ super(group)
21
+ end
22
+ end
23
+
24
+ class InvalidFinderOptions < StandardError
25
+ def initialize
26
+ super("You must provide at least one group or one org")
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ if __FILE__ == $PROGRAM_NAME
33
+ finder = UcbGroups::MembershipFinder.new("calmessages")
34
+ people = finder.find(:groups => ["it-staff"], :orgs => ["JKASD"])
35
+ pp people
36
+ end
@@ -0,0 +1,127 @@
1
+ require 'rest-client'
2
+ require_relative "../spec_helper"
3
+ require 'set'
4
+
5
+ #groups = UcbGroups::CampusGroup.find(:calmessages)
6
+ #pp groups.map(&:name).sort
7
+
8
+
9
+ def assert_matching_group(group)
10
+ @finder ||= UcbGroups::MembershipFinder.new(:calmessages)
11
+ grouper_uids = @finder.find(:groups => [group]).map(&:uid).sort
12
+ calmsgs_uids = calmsgs_group_uids(group)
13
+
14
+ #if calmsgs_uids.length != grouper_uids.length
15
+ puts "calmsgs: #{calmsgs_uids.length}, grouper: #{grouper_uids.length}"
16
+ puts "Only In Calmsgs: #{calmsgs_uids - grouper_uids}\nOnly in Grouper: #{grouper_uids - calmsgs_uids}"
17
+ grouper_uids.length.should eql(calmsgs_uids.length)
18
+ #end
19
+
20
+ calmsgs_uids.should eql(grouper_uids)
21
+ end
22
+
23
+ def calmsgs_group_uids(group)
24
+ uids = RestClient.get("localhost:3000/api/groups/#{group}.json")
25
+ JSON.parse(uids).map(&:to_s).sort
26
+ end
27
+
28
+
29
+ describe "Calmsgs Groups Compatibility" do
30
+ it "academic-senate-faculty" do
31
+ # fails but close enough
32
+ assert_matching_group("academic-senate-faculty")
33
+ end
34
+
35
+ it "deans" do
36
+ # fails but close enough
37
+ assert_matching_group("deans")
38
+ end
39
+
40
+ it "dept-admin" do
41
+ # fails because ldap does not keep emptititlecode around for expired people and caldap does (close enough)
42
+ assert_matching_group("dept-admin")
43
+ end
44
+
45
+ it "dept-chairs" do
46
+ # fails but close enough
47
+ assert_matching_group("dept-chairs")
48
+ end
49
+
50
+ it "directors" do
51
+ assert_matching_group("directors")
52
+ end
53
+
54
+ it "emeriti" do
55
+ assert_matching_group("emeriti")
56
+ end
57
+
58
+ it "faculty" do
59
+ # fails because calmsgs is grabbing people that it shouldn't. In many instances calmsgs
60
+ # is grabbing staff that have no academic affiliation (close enough)
61
+ assert_matching_group("faculty")
62
+ end
63
+
64
+ it "it-staff" do
65
+ # fails because calmsgs it grabbing retired or expired it-staff (close enough)
66
+ assert_matching_group("it-staff")
67
+ end
68
+
69
+ it "staff" do
70
+ # fails but close enough
71
+ assert_matching_group("staff")
72
+ end
73
+
74
+ it "students" do
75
+ # fails but close enough
76
+ assert_matching_group("students")
77
+ end
78
+
79
+ it "managers" do
80
+ assert_matching_group("managers") # fails but close enough
81
+ end
82
+
83
+ it "supervisors" do
84
+ assert_matching_group("supervisors") # fails but close enough
85
+ end
86
+
87
+ it "affiliates" do
88
+ assert_matching_group("affiliates") # fails
89
+ end
90
+
91
+ it "ucop" do
92
+ # fails but close enough
93
+ assert_matching_group("ucop")
94
+ end
95
+
96
+ it "graduate-students" do
97
+ # no calmsgs group
98
+ # assert_matching_group("graduate-students")
99
+ end
100
+
101
+ it "advisors" do
102
+ # no calmsgs group
103
+ # assert_matching_group("advisors")
104
+ end
105
+
106
+ it "gsis" do
107
+ # no calmsgs group
108
+ # assert_matching_group("gsis")
109
+ end
110
+
111
+ it "gsrs" do
112
+ # no calmsgs group
113
+ # assert_matching_group("gsrs")
114
+ end
115
+
116
+ it "instructors" do
117
+ # no calmsgs group
118
+ #assert_matching_group("instructors")
119
+ end
120
+
121
+ it "undergrad-students" do
122
+ # no calmsgs group
123
+ # assert_matching_group("undergrad-students")
124
+ end
125
+ end
126
+
127
+
@@ -0,0 +1,7 @@
1
+ require_relative '../lib/ucb_groups'
2
+ require 'yaml'
3
+
4
+ RSpec.configure do |config|
5
+ ldap_yml = File.expand_path(File.dirname("#{__FILE__}") + "/../ldap.yml")
6
+ UcbGroups::LdapConn.authenticate_from_config(ldap_yml)
7
+ end
@@ -0,0 +1,25 @@
1
+ require_relative "../spec_helper"
2
+
3
+
4
+ describe "CampusGroup" do
5
+ let(:entry) do
6
+ {
7
+ :dn => ["cn=edu:berkeley:app:calmessages:faculty,ou=campus groups,dc=berkeley,dc=edu"],
8
+ :description => ["Instructors"]
9
+ }
10
+ end
11
+
12
+ it "Finds Campus Groups" do
13
+ groups = UcbGroups::CampusGroup.find(:calmessages)
14
+ groups.should_not be_empty
15
+ end
16
+
17
+ it "initializes an entry" do
18
+ group = UcbGroups::CampusGroup.new(entry)
19
+
20
+ group.dn.should eql(entry[:dn].first)
21
+ group.description.should eql(entry[:description].first)
22
+ group.namespace.should eql("calmessages")
23
+ group.name.should eql("faculty")
24
+ end
25
+ end
@@ -0,0 +1,54 @@
1
+ require_relative "../spec_helper"
2
+
3
+
4
+ describe "MembershipFilter" do
5
+ let(:finder) { UcbGroups::MembershipFilter.new(namespace, groups, orgs) }
6
+
7
+ it "creates groups filter" do
8
+ filter = UcbGroups::MembershipFilter.new(:calmessages, [:deans], []).to_s
9
+ filter_str = "(&(objectclass=person)" +
10
+ "(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu))"
11
+ filter.should eql(filter_str)
12
+
13
+ filter = UcbGroups::MembershipFilter.new(:calmessages, [:deans, :instructors], []).to_s
14
+ filter_str = "(&(objectclass=person)" +
15
+ "(|(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)" +
16
+ "(ismemberof=cn=edu:berkeley:app:calmessages:instructors,ou=campus groups,dc=berkeley,dc=edu)))"
17
+ filter.should eql(filter_str)
18
+ end
19
+
20
+ it "creates orgs filter" do
21
+ filter = UcbGroups::MembershipFilter.new(:calmessages, [], ["JKASD"]).to_s
22
+ filter_str = "(&(objectclass=person)" +
23
+ "(berkeleyedudeptunithierarchystring=*JKASD*))"
24
+ filter.should eql(filter_str)
25
+
26
+ filter = UcbGroups::MembershipFilter.new(:calmessages, [], ["JKASD", "JJCNS"]).to_s
27
+ filter_str = "(&(objectclass=person)" +
28
+ "(|(berkeleyedudeptunithierarchystring=*JKASD*)" +
29
+ "(berkeleyedudeptunithierarchystring=*JJCNS*)))"
30
+ filter.should eql(filter_str)
31
+ end
32
+
33
+ it "creates groups and orgs filter" do
34
+ filter = UcbGroups::MembershipFilter.new(:calmessages, [:deans], ["JKASD"]).to_s
35
+ filter_str = "(&(objectclass=person)" +
36
+ "(&(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)" +
37
+ "(berkeleyedudeptunithierarchystring=*JKASD*)))"
38
+ filter.should eql(filter_str)
39
+
40
+ filter = UcbGroups::MembershipFilter.new(:calmessages, [:deans, :instructors], ["JKASD"]).to_s
41
+ filter_str = "(&(objectclass=person)" +
42
+ "(&(|(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)" +
43
+ "(ismemberof=cn=edu:berkeley:app:calmessages:instructors,ou=campus groups,dc=berkeley,dc=edu))" +
44
+ "(berkeleyedudeptunithierarchystring=*JKASD*)))"
45
+ filter.should eql(filter_str)
46
+
47
+ filter = UcbGroups::MembershipFilter.new(:calmessages, [:deans, :instructors], ["JKASD", "JJCNS"]).to_s
48
+ filter_str = "(&(objectclass=person)" +
49
+ "(&(|(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)" +
50
+ "(ismemberof=cn=edu:berkeley:app:calmessages:instructors,ou=campus groups,dc=berkeley,dc=edu))" +
51
+ "(|(berkeleyedudeptunithierarchystring=*JKASD*)(berkeleyedudeptunithierarchystring=*JJCNS*))))"
52
+ filter.should eql(filter_str)
53
+ end
54
+ end
@@ -0,0 +1,52 @@
1
+ require_relative "../spec_helper"
2
+
3
+
4
+ describe "MembershipFinder" do
5
+ let(:finder) { UcbGroups::MembershipFinder.new(:calmessages) }
6
+
7
+ context "find options" do
8
+ it "recognizes if groups are invalid" do
9
+ err = UcbGroups::InvalidCampusGroupError
10
+ expect { finder.find(:groups => [:invalid_group]) }.to raise_error(err)
11
+ expect { finder.find(:groups => [:deans, :invalid_group]) }.to raise_error(err)
12
+ end
13
+
14
+ it "returns no results if :group and :orgs are both empty" do
15
+ finder.find(:groups => [], :orgs => []).should be_empty
16
+ end
17
+ end
18
+
19
+ context "Finding by group" do
20
+ it "finds users in a single group" do
21
+ finder.find(:groups => [:deans]).should_not be_empty
22
+ end
23
+
24
+ it "finds users in a multiple groups" do
25
+ finder.find(:groups => [:deans, :instructors]).should_not be_empty
26
+ end
27
+ end
28
+
29
+ context "Finding by org" do
30
+ it "finds users beneath a single org" do
31
+ finder.find(:orgs => [:JKASD]).should_not be_empty
32
+ end
33
+
34
+ it "finds users beneath any of the provided orgs" do
35
+ jkasd_people = finder.find(:orgs => [:JKASD])
36
+ jkasd_jjcns_people = finder.find(:orgs => [:JKASD, :JJCNS])
37
+
38
+ (jkasd_people.length < jkasd_jjcns_people.length).should be_true
39
+ end
40
+ end
41
+
42
+ context "Finding by group and org" do
43
+ it "finds users in a single group and org" do
44
+ campus_it_staff = finder.find(:groups => ["it-staff"])
45
+ ist_it_staff = finder.find(:groups => ["it-staff"], :orgs => [:VRIST])
46
+
47
+ campus_it_staff.should_not be_empty
48
+ ist_it_staff.should_not be_empty
49
+ (ist_it_staff.length < campus_it_staff.length).should be_true
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,4 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe UcbGroups do
4
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ucb_groups/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ucb_groups"
8
+ spec.version = UcbGroups::VERSION
9
+ spec.authors = ["sahglie"]
10
+ spec.email = ["sahglie@gmail.com"]
11
+ spec.description = %q{Finds users that belong to a given ucb group}
12
+ spec.summary = %q{Finds users that belong to a given ucb group}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 2.7"
24
+ spec.add_development_dependency "rest-client"
25
+ spec.add_development_dependency "json"
26
+
27
+ spec.add_runtime_dependency "ucb_ldap", "2.0.0.pre5"
28
+ spec.add_runtime_dependency "net-ldap", "0.2.2"
29
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ucb_groups
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - sahglie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ucb_ldap
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 2.0.0.pre5
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 2.0.0.pre5
97
+ - !ruby/object:Gem::Dependency
98
+ name: net-ldap
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 0.2.2
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 0.2.2
111
+ description: Finds users that belong to a given ucb group
112
+ email:
113
+ - sahglie@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - Gemfile
120
+ - LICENSE.txt
121
+ - README.md
122
+ - Rakefile
123
+ - lib/ucb_groups.rb
124
+ - lib/ucb_groups/campus_group.rb
125
+ - lib/ucb_groups/ldap_conn.rb
126
+ - lib/ucb_groups/membership_filter.rb
127
+ - lib/ucb_groups/membership_finder.rb
128
+ - lib/ucb_groups/monkey_patches/net_ldap_filter.rb
129
+ - lib/ucb_groups/person.rb
130
+ - lib/ucb_groups/version.rb
131
+ - spec/integration/calmsgs_groups_spec.rb
132
+ - spec/spec_helper.rb
133
+ - spec/ucb_groups/campus_group_spec.rb
134
+ - spec/ucb_groups/membership_filter_spec.rb
135
+ - spec/ucb_groups/membership_finder_spec.rb
136
+ - spec/ucb_groups_spec.rb
137
+ - ucb_groups.gemspec
138
+ homepage: ''
139
+ licenses:
140
+ - MIT
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.0.3
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Finds users that belong to a given ucb group
162
+ test_files:
163
+ - spec/integration/calmsgs_groups_spec.rb
164
+ - spec/spec_helper.rb
165
+ - spec/ucb_groups/campus_group_spec.rb
166
+ - spec/ucb_groups/membership_filter_spec.rb
167
+ - spec/ucb_groups/membership_finder_spec.rb
168
+ - spec/ucb_groups_spec.rb
169
+ has_rdoc: