goz 0.0.3 → 0.1.0
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.
- data/.gitignore +1 -0
- data/HISTORY.rdoc +6 -0
- data/README.rdoc +2 -17
- data/TODO.md +16 -0
- data/goz.gemspec +5 -1
- data/lib/goz.rb +9 -25
- data/lib/goz/database.rb +10 -0
- data/lib/goz/database/migrations.rb +15 -9
- data/lib/goz/event.rb +78 -16
- data/lib/goz/event_type.rb +4 -4
- data/lib/goz/group.rb +121 -44
- data/lib/goz/group/base.rb +115 -0
- data/lib/goz/group/etc_group.rb +113 -0
- data/lib/goz/group/grouper.rb +153 -0
- data/lib/goz/group/grouper/stemmed_groups.rb +140 -0
- data/lib/goz/group/test_case.rb +200 -0
- data/lib/goz/group_service.rb +5 -10
- data/lib/goz/logger.rb +41 -72
- data/lib/goz/service.rb +50 -30
- data/lib/goz/service/base.rb +43 -0
- data/lib/goz/service/fake_service.rb +81 -0
- data/lib/goz/test_case.rb +26 -14
- data/lib/goz/user.rb +98 -37
- data/lib/goz/user/base.rb +81 -0
- data/lib/goz/user/etc_passwd.rb +56 -0
- data/lib/goz/user/ldap.rb +112 -0
- data/lib/goz/user/test_case.rb +55 -0
- data/lib/goz/version.rb +1 -1
- metadata +89 -45
- data/lib/goz/cache.rb +0 -136
- data/lib/goz/cache/hash_store.rb +0 -75
- data/test/test_admins.rb +0 -189
- data/test/test_cache.rb +0 -90
- data/test/test_event.rb +0 -576
- data/test/test_event_type.rb +0 -47
- data/test/test_goz.rb +0 -22
- data/test/test_group.rb +0 -180
- data/test/test_group_services.rb +0 -241
- data/test/test_hash_store_cash.rb +0 -42
- data/test/test_logger.rb +0 -93
- data/test/test_members.rb +0 -189
- data/test/test_service.rb +0 -150
- data/test/test_user.rb +0 -205
@@ -0,0 +1,115 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/group'
|
4
|
+
require 'goz/logger'
|
5
|
+
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
class Group # :nodoc:
|
9
|
+
|
10
|
+
#
|
11
|
+
# = Goz::Group::Base - TODO
|
12
|
+
#
|
13
|
+
# == Usage
|
14
|
+
#
|
15
|
+
# TODO
|
16
|
+
#
|
17
|
+
# == Author
|
18
|
+
#
|
19
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
20
|
+
#
|
21
|
+
# == Homepage
|
22
|
+
#
|
23
|
+
# https://github.com/blairc/goz/
|
24
|
+
#
|
25
|
+
class Base
|
26
|
+
|
27
|
+
TAG = self.name
|
28
|
+
|
29
|
+
attr_accessor :display_name, :identifier, :klass, :name
|
30
|
+
|
31
|
+
@@cf = {}
|
32
|
+
|
33
|
+
|
34
|
+
#
|
35
|
+
# TODO
|
36
|
+
#
|
37
|
+
def [](key)
|
38
|
+
send key.to_sym
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Set configuration.
|
43
|
+
#
|
44
|
+
def self.configuration(configuration)
|
45
|
+
@@cf = configuration
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Find Goz::Group by name or return +nil+
|
50
|
+
#
|
51
|
+
# MUST be implemented by API extensions.
|
52
|
+
#
|
53
|
+
def self.find_by_name(name)
|
54
|
+
raise RuntimeError, "not implemented"
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# TODO
|
59
|
+
#
|
60
|
+
# MUST be implemented by API extensions.
|
61
|
+
#
|
62
|
+
def admins()
|
63
|
+
raise RuntimeError, "not implemented"
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# TODO
|
68
|
+
#
|
69
|
+
# MUST be implemented by API extensions.
|
70
|
+
#
|
71
|
+
def members()
|
72
|
+
raise RuntimeError, "not implemented"
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Return groups where +user+ is an admin.
|
77
|
+
#
|
78
|
+
# MUST be implemented by API extensions.
|
79
|
+
#
|
80
|
+
def self.groups(user)
|
81
|
+
raise RuntimeError, "not implemented"
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Return groups where +user+ is a member.
|
86
|
+
#
|
87
|
+
# MUST be implemented by API extensions.
|
88
|
+
#
|
89
|
+
def self.memberships(user)
|
90
|
+
raise RuntimeError, "not implemented"
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Convert to Goz::Group-style hash
|
95
|
+
#
|
96
|
+
def to_hash
|
97
|
+
return { :display_name => self.display_name,
|
98
|
+
:identifier => self.identifier,
|
99
|
+
:klass => self.klass,
|
100
|
+
:name => self.name
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# TODO
|
106
|
+
#
|
107
|
+
def to_s
|
108
|
+
"display_name=#{display_name} | identifier=#{identifier} | klass=#{klass} | name=#{name}"
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'etc'
|
4
|
+
require 'goz/group/base'
|
5
|
+
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
class Group # :nodoc:
|
9
|
+
|
10
|
+
#
|
11
|
+
# = Goz::Group::EtcGroup - +/etc/group+ derived users (mostly for testing)
|
12
|
+
#
|
13
|
+
# == Usage
|
14
|
+
#
|
15
|
+
# TODO
|
16
|
+
#
|
17
|
+
# == Author
|
18
|
+
#
|
19
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
20
|
+
#
|
21
|
+
# == Homepage
|
22
|
+
#
|
23
|
+
# https://github.com/blairc/goz/
|
24
|
+
#
|
25
|
+
class EtcGroup < Goz::Group::Base
|
26
|
+
|
27
|
+
TAG = self.name
|
28
|
+
|
29
|
+
|
30
|
+
def initialize(g)
|
31
|
+
@display_name = g[:name]
|
32
|
+
@identifier = g[:gid]
|
33
|
+
@klass = self.class.name
|
34
|
+
@name = g[:name]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
#
|
39
|
+
# Find Goz::Group by name or return +nil+
|
40
|
+
#
|
41
|
+
def self.find_by_name(name)
|
42
|
+
Goz::Logger.debug TAG, "find_by_name( name=#{name} )"
|
43
|
+
begin
|
44
|
+
return self.new( Etc.getgrnam(name) )
|
45
|
+
rescue ArgumentError => e
|
46
|
+
Goz::Logger.warn TAG, "find_by_name( name=#{name} ) - not found"
|
47
|
+
end
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# TODO
|
53
|
+
#
|
54
|
+
def admins()
|
55
|
+
Goz::Logger.debug TAG, "name=#{self.name} - #admins()"
|
56
|
+
users = []
|
57
|
+
g = Etc.getgrnam self.name
|
58
|
+
return users if g.nil?
|
59
|
+
# XXX ???
|
60
|
+
users
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# TODO
|
65
|
+
#
|
66
|
+
def members()
|
67
|
+
Goz::Logger.debug TAG, "#{self.name} - #members()"
|
68
|
+
users = []
|
69
|
+
g = Etc.getgrnam self.name
|
70
|
+
return users if g.nil?
|
71
|
+
users = g[:mem].collect { |m| Goz::User.find_by_login m }
|
72
|
+
users.delete_if { |_| _.nil? }
|
73
|
+
users
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Return groups where +user+ is an admin.
|
78
|
+
#
|
79
|
+
def self.groups(user)
|
80
|
+
Goz::Logger.debug TAG, "groups( user.login=#{user.login} )"
|
81
|
+
groups = []
|
82
|
+
return groups if user.nil? || user.identifier.nil? || user.name.nil?
|
83
|
+
loop do
|
84
|
+
g = Etc.getgrent
|
85
|
+
break if g.nil?
|
86
|
+
groups << self.new(g) if ( '0' === user.identifier || ( g[:gid].to_s === user.identifier && g[:name] == user.login ) )
|
87
|
+
end
|
88
|
+
Etc.endgrent
|
89
|
+
return groups
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Return groups where +user+ is a member.
|
94
|
+
#
|
95
|
+
def self.memberships(user)
|
96
|
+
Goz::Logger.debug TAG, "groups( user.login=#{user.login} )"
|
97
|
+
groups = []
|
98
|
+
return groups if user.nil? || user.login.nil? || user.identifier.nil?
|
99
|
+
loop do
|
100
|
+
g = Etc.getgrent
|
101
|
+
break if g.nil?
|
102
|
+
groups << self.new(g) if ( g[:mem].include?(user.login) || ( g[:gid].to_s == user.identifier && g[:name] == user.login ) )
|
103
|
+
end
|
104
|
+
Etc.endgrent
|
105
|
+
return groups
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/group/base'
|
4
|
+
require 'grouper-rest-client'
|
5
|
+
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
class Group # :nodoc:
|
9
|
+
|
10
|
+
#
|
11
|
+
# = Goz::Group::Grouper - TODO
|
12
|
+
#
|
13
|
+
# == Usage
|
14
|
+
#
|
15
|
+
# TODO
|
16
|
+
#
|
17
|
+
# == Author
|
18
|
+
#
|
19
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
20
|
+
#
|
21
|
+
# == Homepage
|
22
|
+
#
|
23
|
+
# https://github.com/blairc/goz/
|
24
|
+
#
|
25
|
+
class Grouper < Goz::Group::Base
|
26
|
+
|
27
|
+
TAG = self.name
|
28
|
+
|
29
|
+
|
30
|
+
def initialize(g)
|
31
|
+
@display_name = _prettify_name g['name']
|
32
|
+
@identifier = g['uuid']
|
33
|
+
@klass = self.class.name
|
34
|
+
@name = g['name']
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
#
|
39
|
+
# Find Goz::Group by name or return +nil+
|
40
|
+
#
|
41
|
+
def self.find_by_name(name)
|
42
|
+
Goz::Logger.debug TAG, "find_by_name( name=#{name} )"
|
43
|
+
connect do |grouper|
|
44
|
+
g = grouper.group(name.rstrip) # TODO Sigh...
|
45
|
+
if g.nil?
|
46
|
+
Goz::Logger.warn TAG, "find_by_name( name=#{name} ) - not found"
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
group = new g
|
50
|
+
yield group if block_given?
|
51
|
+
return group
|
52
|
+
end
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# TODO
|
58
|
+
#
|
59
|
+
def admins()
|
60
|
+
Goz::Logger.debug TAG, "name=#{self.name} - #admins() - not implemented"
|
61
|
+
[] # TODO
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# TODO
|
66
|
+
#
|
67
|
+
def self.extension(name)
|
68
|
+
m = name.match( /^.+:(.+)$/ )
|
69
|
+
m ? m[1] : nil
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# TODO
|
74
|
+
#
|
75
|
+
def members()
|
76
|
+
Goz::Logger.debug TAG, "#{self.name} - #members()"
|
77
|
+
users = []
|
78
|
+
Goz::Group::Grouper.connect do |grouper|
|
79
|
+
users = grouper.group(self.name).members.collect { |m| Goz::User.find_by_identifier m['id'] }
|
80
|
+
users.delete_if { |_| _.nil? }
|
81
|
+
end
|
82
|
+
users.each { |u| yield u } if block_given?
|
83
|
+
users
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Return groups where +user+ is an admin.
|
88
|
+
#
|
89
|
+
def self.groups(user)
|
90
|
+
Goz::Logger.debug TAG, "groups( user.login=#{user.login} ) - not implemented"
|
91
|
+
[]
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Return groups where +user+ is a member.
|
96
|
+
#
|
97
|
+
def self.memberships(user)
|
98
|
+
if user.nil?
|
99
|
+
Goz::Logger.warn TAG, "memberships( user=nil )"
|
100
|
+
return []
|
101
|
+
end
|
102
|
+
Goz::Logger.debug TAG, "memberships( user.login=#{user.login} )"
|
103
|
+
groups = []
|
104
|
+
self.connect do |grouper|
|
105
|
+
subject = grouper.subject user.identifier
|
106
|
+
if subject.nil?
|
107
|
+
Goz::Logger.warn TAG, "memberships( user.login=#{user.login} ) - could not find user with identifier=#{ user.identifier }"
|
108
|
+
break
|
109
|
+
end
|
110
|
+
groups = subject.groups( @@cf['base'] ).collect { |g| new g }
|
111
|
+
end
|
112
|
+
groups.each { |g| yield g } if block_given?
|
113
|
+
groups
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# TODO
|
118
|
+
#
|
119
|
+
def self.stem(name)
|
120
|
+
m = name.match( /^(.+):.+$/ )
|
121
|
+
m ? m[1] : nil
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# TODO
|
126
|
+
#
|
127
|
+
def self.stemmed_group?(name)
|
128
|
+
suffixes = @@cf['admin_suffix'] | @@cf['member_suffix']
|
129
|
+
Regexp.new( "^.*?:(#{ suffixes.join('|') })$" ).match(name) ? true : false
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def self.connect
|
136
|
+
grouper = ::Grouper::Rest::Client::Resource.new @@cf['url'],
|
137
|
+
:user => @@cf['user'],
|
138
|
+
:password => @@cf['password']
|
139
|
+
yield grouper if block_given?
|
140
|
+
grouper
|
141
|
+
end
|
142
|
+
|
143
|
+
def _prettify_name(name)
|
144
|
+
return name if name.nil?
|
145
|
+
name.sub /^#{ @@cf['base'] }/, ''
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/group/grouper'
|
4
|
+
require 'grouper-rest-client'
|
5
|
+
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
class Group # :nodoc:
|
9
|
+
class Grouper # :nodoc:
|
10
|
+
|
11
|
+
#
|
12
|
+
# = Goz::Group::Grouper::StemmedGroups - TODO
|
13
|
+
#
|
14
|
+
# == Usage
|
15
|
+
#
|
16
|
+
# TODO
|
17
|
+
#
|
18
|
+
# == Author
|
19
|
+
#
|
20
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
21
|
+
#
|
22
|
+
# == Homepage
|
23
|
+
#
|
24
|
+
# https://github.com/blairc/goz/
|
25
|
+
#
|
26
|
+
class StemmedGroups < Goz::Group::Grouper
|
27
|
+
|
28
|
+
TAG = self.name
|
29
|
+
|
30
|
+
|
31
|
+
#
|
32
|
+
# TODO
|
33
|
+
#
|
34
|
+
def initialize(g)
|
35
|
+
super(g)
|
36
|
+
@klass = self.class.name
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Find Goz::Group by name or return +nil+
|
41
|
+
#
|
42
|
+
def self.find_by_name(name)
|
43
|
+
name.rstrip!
|
44
|
+
Goz::Logger.debug TAG, "find_by_name( name=#{name} )"
|
45
|
+
g = super(name)
|
46
|
+
if g.nil?
|
47
|
+
connect do |grouper|
|
48
|
+
ns = grouper.stem(name)
|
49
|
+
if ns.nil?
|
50
|
+
Goz::Logger.debug TAG, "find_by_name( name=#{name} ) - not found"
|
51
|
+
return nil
|
52
|
+
end
|
53
|
+
return new ns
|
54
|
+
end
|
55
|
+
end
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# TODO
|
61
|
+
#
|
62
|
+
def admins()
|
63
|
+
Goz::Logger.debug TAG, "name=#{self.name} - #admins()"
|
64
|
+
return super(self) unless stem?(self.name)
|
65
|
+
return super(self) if self.class.stemmed_group?(self.name)
|
66
|
+
_members @@cf['admin_suffix']
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Return groups where +user+ is an admin.
|
71
|
+
#
|
72
|
+
def self.groups(user)
|
73
|
+
Goz::Logger.debug TAG, "groups( user.login=#{user.login} )"
|
74
|
+
groups = []
|
75
|
+
memberships(user).each do |g|
|
76
|
+
groups << g if stemmed_group?(g.name) && @@cf['admin_suffix'].include?( extension(g.name) )
|
77
|
+
end
|
78
|
+
groups.each { |g| yield g } if block_given?
|
79
|
+
groups
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# TODO
|
84
|
+
#
|
85
|
+
def members()
|
86
|
+
Goz::Logger.debug TAG, "#{self.name} - #members()"
|
87
|
+
return super(self) unless stem?(self.name)
|
88
|
+
_members @@cf['member_suffix']
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Return groups where +user+ is a member.
|
93
|
+
#
|
94
|
+
def self.memberships(user)
|
95
|
+
Goz::Logger.debug TAG, "memberships( user.login=#{user.login} )"
|
96
|
+
groups = []
|
97
|
+
super(user).each do |g|
|
98
|
+
g.klass = self.name
|
99
|
+
groups << g
|
100
|
+
groups << find_by_name( stem(g.name) ) if stemmed_group?(g.name)
|
101
|
+
end
|
102
|
+
groups.each { |g| yield g } if block_given?
|
103
|
+
groups
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# TODO
|
108
|
+
#
|
109
|
+
def stem?(name)
|
110
|
+
self.class.connect do |grouper|
|
111
|
+
return grouper.stem(name) ? true : false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def _members(suffixes)
|
119
|
+
users = []
|
120
|
+
self.class.connect do |grouper|
|
121
|
+
suffixes.each do |suffix|
|
122
|
+
name = "#{self.name}:#{suffix}"
|
123
|
+
_ = Goz::Group.find_by_name(name)
|
124
|
+
next if _.nil?
|
125
|
+
g = Goz::Group.find_or_create _.to_hash
|
126
|
+
g.members.each do |m|
|
127
|
+
users << m unless users.include?(m)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
users.each { |u| yield u } if block_given?
|
132
|
+
users
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|