goz 0.0.2 → 0.0.3
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/HISTORY.rdoc +7 -1
- data/README.rdoc +1 -1
- data/goz.gemspec +8 -7
- data/lib/goz.rb +6 -1
- data/lib/goz/cache/hash_store.rb +2 -2
- data/lib/goz/database.rb +53 -0
- data/lib/goz/database/migrations.rb +171 -0
- data/lib/goz/event.rb +109 -0
- data/lib/goz/event_type.rb +47 -0
- data/lib/goz/group.rb +174 -0
- data/lib/goz/group_service.rb +41 -0
- data/lib/goz/service.rb +137 -0
- data/lib/goz/test_case.rb +48 -0
- data/lib/goz/user.rb +164 -0
- data/lib/goz/version.rb +1 -1
- data/test/test_admins.rb +189 -0
- data/test/{test_goz_cache.rb → test_cache.rb} +4 -2
- data/test/test_event.rb +576 -0
- data/test/test_event_type.rb +47 -0
- data/test/test_goz.rb +8 -3
- data/test/test_group.rb +180 -0
- data/test/test_group_services.rb +241 -0
- data/test/{test_goz_cache_hash_store.rb → test_hash_store_cash.rb} +4 -2
- data/test/{test_goz_logger.rb → test_logger.rb} +5 -2
- data/test/test_members.rb +189 -0
- data/test/test_service.rb +150 -0
- data/test/test_user.rb +205 -0
- metadata +96 -19
data/lib/goz/group.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/database'
|
4
|
+
require 'goz/event'
|
5
|
+
require 'goz/group_service'
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
|
9
|
+
#
|
10
|
+
# = Goz::Group - Generic Goz group
|
11
|
+
#
|
12
|
+
# == Usage
|
13
|
+
#
|
14
|
+
# require 'goz/group'
|
15
|
+
#
|
16
|
+
# g = Goz::Group.find_by_name(name)
|
17
|
+
# unless g
|
18
|
+
# g = Goz::Group.create( :display_name => display_name,
|
19
|
+
# :identifier => identifier,
|
20
|
+
# :name => name
|
21
|
+
# )
|
22
|
+
# end
|
23
|
+
# g.display_name # => 'Foo : Bar'
|
24
|
+
# g.identifier # => <some unique identifier>
|
25
|
+
# g.name # => 'foo:bar'
|
26
|
+
# g.created_at # => '2012-03-23 14:58:02 -0500'
|
27
|
+
#
|
28
|
+
# == Author
|
29
|
+
#
|
30
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
31
|
+
#
|
32
|
+
# == Homepage
|
33
|
+
#
|
34
|
+
# https://github.com/blairc/goz/
|
35
|
+
#
|
36
|
+
class Group < Sequel::Model
|
37
|
+
include Comparable
|
38
|
+
|
39
|
+
plugin :validation_helpers
|
40
|
+
|
41
|
+
many_to_many :admins,
|
42
|
+
:left_key => :group_id,
|
43
|
+
:right_key => :user_id,
|
44
|
+
:join_table => :admins,
|
45
|
+
:class => :'Goz::User',
|
46
|
+
:after_add => proc { |g, u| Goz::Event.admin_add(g, u) },
|
47
|
+
:after_remove => proc { |g, u| Goz::Event.admin_remove(g, u) }
|
48
|
+
many_to_many :members,
|
49
|
+
:left_key => :group_id,
|
50
|
+
:right_key => :user_id,
|
51
|
+
:join_table => :members,
|
52
|
+
:class => :'Goz::User',
|
53
|
+
:after_add => proc { |g, u| Goz::Event.member_add(g, u) },
|
54
|
+
:after_remove => proc { |g, u| Goz::Event.member_remove(g, u) }
|
55
|
+
many_to_many :services,
|
56
|
+
:left_key => :group_id,
|
57
|
+
:right_key => :service_id,
|
58
|
+
:join_table => :group_services,
|
59
|
+
:class => :'Goz::Service',
|
60
|
+
:after_add => proc { |g, s| Goz::Event.group_service_add(g, s) },
|
61
|
+
:after_remove => proc { |g, s| Goz::Event.group_service_remove(g, s) }
|
62
|
+
|
63
|
+
|
64
|
+
#
|
65
|
+
# Initialize new (non-persistent) Goz::Group object
|
66
|
+
#
|
67
|
+
def initialize(*params)
|
68
|
+
super
|
69
|
+
yield self if block_given?
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Compare equality.
|
75
|
+
#
|
76
|
+
def <=>(other)
|
77
|
+
if self.display_name < other.display_name ||
|
78
|
+
self.identifier < other.identifier ||
|
79
|
+
self.name < other.name
|
80
|
+
-1
|
81
|
+
elsif self.display_name > other.display_name ||
|
82
|
+
self.identifier > other.identifier ||
|
83
|
+
self.name > other.name
|
84
|
+
1
|
85
|
+
else
|
86
|
+
0
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Create Goz::Group or raise +RuntimeError+
|
92
|
+
#
|
93
|
+
def self.create( params = {} )
|
94
|
+
params = {} unless params.kind_of?(Hash)
|
95
|
+
[ :display_name, :identifier, :name ].each do |k|
|
96
|
+
raise( "invalid #{k.to_s}" ) if ( params[k].nil? || params[k].empty? )
|
97
|
+
end
|
98
|
+
super
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Find Goz::Group by name or return +nil+
|
103
|
+
#
|
104
|
+
def self.find_by_name(name)
|
105
|
+
self.find( :name => name )
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Synchronize group with external data sources (if relevant).
|
110
|
+
#
|
111
|
+
def sync(force = false)
|
112
|
+
if force || synchronized_at.nil? || synchronized_at < ( Time.now - ( 1 * 60 * 60 ) ) # XXX
|
113
|
+
# XXX Synchronize group from remote source (if necessary)
|
114
|
+
# XXX Synchronize admins
|
115
|
+
# XXX Synchronize members
|
116
|
+
self.services.each { |s| self.sync_service(s, force) }
|
117
|
+
self.synchronized_at = Time.now
|
118
|
+
self.save
|
119
|
+
Goz::Event.group_sync(self)
|
120
|
+
return true
|
121
|
+
end
|
122
|
+
false
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Synchronize group service with external data soruces (if relevant).
|
127
|
+
#
|
128
|
+
def sync_service(service, force = false )
|
129
|
+
Goz::GroupService.first( :group_id => self.id, :service_id => service.id ).sync(force)
|
130
|
+
end
|
131
|
+
|
132
|
+
#
|
133
|
+
# Perform model valiations.
|
134
|
+
#
|
135
|
+
def validate
|
136
|
+
super
|
137
|
+
validates_presence [ :display_name, :identifier, :name ]
|
138
|
+
validates_type Time, [ :created_at, :modified_at, :synchronized_at ]
|
139
|
+
validates_unique [ :display_name, :identifier, :name ]
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def after_destroy
|
146
|
+
super
|
147
|
+
Goz::Event.group_remove(self)
|
148
|
+
end
|
149
|
+
|
150
|
+
def after_create
|
151
|
+
super
|
152
|
+
Goz::Event.group_add(self)
|
153
|
+
end
|
154
|
+
|
155
|
+
def before_create
|
156
|
+
super
|
157
|
+
self.created_at ||= Time.now
|
158
|
+
end
|
159
|
+
|
160
|
+
def before_destroy
|
161
|
+
remove_all_members
|
162
|
+
remove_all_admins
|
163
|
+
remove_all_services
|
164
|
+
end
|
165
|
+
|
166
|
+
def before_update
|
167
|
+
super
|
168
|
+
self.modified_at = Time.now
|
169
|
+
end
|
170
|
+
|
171
|
+
end # class Group
|
172
|
+
|
173
|
+
end # module Goz
|
174
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/database'
|
4
|
+
require 'goz/event'
|
5
|
+
require 'goz/group_service'
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
|
9
|
+
#
|
10
|
+
# = Goz::GroupService - TODO
|
11
|
+
#
|
12
|
+
# == Author
|
13
|
+
#
|
14
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
15
|
+
#
|
16
|
+
# == Homepage
|
17
|
+
#
|
18
|
+
# https://github.com/blairc/goz/
|
19
|
+
#
|
20
|
+
class GroupService < Sequel::Model
|
21
|
+
|
22
|
+
#
|
23
|
+
# Synchronize group with external service.
|
24
|
+
#
|
25
|
+
def sync(force = false)
|
26
|
+
if force || synchronized_at.nil? || synchronized_at < ( Time.now - ( 1 * 60 * 60 ) ) # XXX
|
27
|
+
# XXX Synchronize group from remote source (if necessary)
|
28
|
+
# XXX Synchronize admins
|
29
|
+
# XXX Synchronize members
|
30
|
+
self.synchronized_at = Time.now
|
31
|
+
self.save
|
32
|
+
Goz::Event.group_service_sync( Group[ self.group_id ], Service[ self.service_id ] )
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
data/lib/goz/service.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/database'
|
4
|
+
require 'goz/event'
|
5
|
+
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
|
9
|
+
#
|
10
|
+
# = Goz::Service - Generic Goz service
|
11
|
+
#
|
12
|
+
# == Usage
|
13
|
+
#
|
14
|
+
# TODO
|
15
|
+
#
|
16
|
+
# == Author
|
17
|
+
#
|
18
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
19
|
+
#
|
20
|
+
# == Homepage
|
21
|
+
#
|
22
|
+
# https://github.com/blairc/goz/
|
23
|
+
#
|
24
|
+
class Service < Sequel::Model
|
25
|
+
include Comparable
|
26
|
+
|
27
|
+
plugin :validation_helpers
|
28
|
+
|
29
|
+
many_to_many :groups,
|
30
|
+
:left_key => :service_id,
|
31
|
+
:right_key => :group_id,
|
32
|
+
:join_table => :group_services,
|
33
|
+
:class => :'Goz::Group',
|
34
|
+
:after_add => proc { |s, g| Goz::Event.group_service_add(g, s) },
|
35
|
+
:after_remove => proc { |s, g| Goz::Event.group_service_remove(g, s) }
|
36
|
+
|
37
|
+
#
|
38
|
+
# Initialize new (non-persistent) Goz::Event object
|
39
|
+
#
|
40
|
+
def initialize(*params)
|
41
|
+
super
|
42
|
+
yield self if block_given?
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
#
|
48
|
+
# Compare equality.
|
49
|
+
#
|
50
|
+
def <=>(other)
|
51
|
+
if self.name < other.name ||
|
52
|
+
self.klass < other.klass
|
53
|
+
-1
|
54
|
+
elsif self.name > other.name ||
|
55
|
+
self.klass > other.klass
|
56
|
+
1
|
57
|
+
else
|
58
|
+
0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Create Goz::Service or raise +RuntimeError+
|
64
|
+
#
|
65
|
+
def self.create( params = {} )
|
66
|
+
params = {} unless params.kind_of?(Hash)
|
67
|
+
[ :name, :klass ].each do |k|
|
68
|
+
raise( "invalid #{k.to_s}" ) if ( params[k].nil? || params[k].empty? )
|
69
|
+
end
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Find Goz::Service by name or return +nil+
|
75
|
+
#
|
76
|
+
def self.find_by_name(name)
|
77
|
+
self.find( :name => name )
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Synchronize service with external data sources (if relevant).
|
82
|
+
#
|
83
|
+
def sync(force = false)
|
84
|
+
if force || synchronized_at.nil? || synchronized_at < ( Time.now - ( 1 * 60 * 60 ) ) # XXX
|
85
|
+
# XXX Synchronize service from remote source (if necessary)
|
86
|
+
# XXX Synchronize groups
|
87
|
+
# XXX Synchronize group admins
|
88
|
+
# XXX Synchronize group members
|
89
|
+
self.synchronized_at = Time.now
|
90
|
+
self.save
|
91
|
+
Goz::Event.service_sync(self)
|
92
|
+
return true
|
93
|
+
end
|
94
|
+
false
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Perform model valiations.
|
99
|
+
#
|
100
|
+
def validate
|
101
|
+
super
|
102
|
+
validates_presence [ :name, :klass ]
|
103
|
+
validates_type Time, [ :created_at, :modified_at, :synchronized_at ]
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def after_destroy
|
110
|
+
super
|
111
|
+
Goz::Event.service_remove self
|
112
|
+
end
|
113
|
+
|
114
|
+
def after_create
|
115
|
+
super
|
116
|
+
Goz::Event.service_add self
|
117
|
+
end
|
118
|
+
|
119
|
+
def before_create
|
120
|
+
super
|
121
|
+
self.created_at ||= Time.now
|
122
|
+
end
|
123
|
+
|
124
|
+
def before_destroy
|
125
|
+
super
|
126
|
+
remove_all_groups
|
127
|
+
end
|
128
|
+
|
129
|
+
def before_update
|
130
|
+
super
|
131
|
+
self.modified_at = Time.now
|
132
|
+
end
|
133
|
+
|
134
|
+
end # class Service
|
135
|
+
|
136
|
+
end # module Goz
|
137
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/database'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
|
7
|
+
module Goz # :nodoc:
|
8
|
+
|
9
|
+
#
|
10
|
+
# = Goz::TestCase - Goz test case.
|
11
|
+
#
|
12
|
+
# == Author
|
13
|
+
#
|
14
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
15
|
+
#
|
16
|
+
# == Homepage
|
17
|
+
#
|
18
|
+
# https://github.com/blairc/goz/
|
19
|
+
#
|
20
|
+
class TestCase < Test::Unit::TestCase
|
21
|
+
|
22
|
+
def setup
|
23
|
+
super
|
24
|
+
Goz::Database.instance do |db|
|
25
|
+
[ :admins, :events, :group_services, :members ].each { |t| db[t].delete }
|
26
|
+
[ :groups, :services, :users ].each { |t| db[t].delete }
|
27
|
+
end
|
28
|
+
|
29
|
+
@groups = {
|
30
|
+
:a => { :display_name => 'Group:A', :identifier => 'c6347f2a0375db1e2ebfe0ad70e24172a3193037', :name => 'gA' },
|
31
|
+
:b => { :display_name => 'Group:B', :identifier => '341af322e54bea31f8d08d4f2c627a4db341781a', :name => 'gB' }
|
32
|
+
}
|
33
|
+
|
34
|
+
@services = {
|
35
|
+
:a => { :name => 'Service A', :klass => 'Goz::Service' },
|
36
|
+
:b => { :name => 'Service B', :klass => 'Goz::Service' }
|
37
|
+
}
|
38
|
+
|
39
|
+
@users = {
|
40
|
+
:a => { :email => 'a@example.org', :login => 'uA', :identifier => '40b071bd23a8fd2b8cff7f59da9211dca7806d47', :name => 'User A' },
|
41
|
+
:b => { :email => 'b@example.org', :login => 'uB', :identifier => '40b071bd23a8fd2b8cff7f59da9211dca7806d47', :name => 'User B' }
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
end # class TestCase
|
46
|
+
|
47
|
+
end # module Goz
|
48
|
+
|
data/lib/goz/user.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'goz/database'
|
4
|
+
require 'goz/event'
|
5
|
+
|
6
|
+
module Goz # :nodoc:
|
7
|
+
|
8
|
+
#
|
9
|
+
# = Goz::User - Generic Goz user
|
10
|
+
#
|
11
|
+
# == Usage
|
12
|
+
#
|
13
|
+
# require 'goz/user'
|
14
|
+
#
|
15
|
+
# u = Goz::User.find_by_login(login)
|
16
|
+
# unless u
|
17
|
+
# u = Goz::User.create( :email => email,
|
18
|
+
# :identifier => identifier,
|
19
|
+
# :login => login,
|
20
|
+
# :name => name
|
21
|
+
# )
|
22
|
+
# end
|
23
|
+
# u.email # => 'user1@example.org'
|
24
|
+
# u.identifier # => <some unique identifier>
|
25
|
+
# u.login # => 'user1'
|
26
|
+
# u.name # => 'User Number One'
|
27
|
+
# u.created_at # => '2012-03-23 14:58:02 -0500'
|
28
|
+
#
|
29
|
+
# == Author
|
30
|
+
#
|
31
|
+
# blair christensen. <mailto:blair.christensen@gmail.com>
|
32
|
+
#
|
33
|
+
# == Homepage
|
34
|
+
#
|
35
|
+
# https://github.com/blairc/goz/
|
36
|
+
#
|
37
|
+
class User < Sequel::Model
|
38
|
+
include Comparable
|
39
|
+
|
40
|
+
plugin :validation_helpers
|
41
|
+
|
42
|
+
many_to_many :groups,
|
43
|
+
:left_key => :user_id,
|
44
|
+
:right_key => :group_id,
|
45
|
+
:join_table => :admins,
|
46
|
+
:class => :'Goz::Group',
|
47
|
+
:after_add => proc { |u, g| Goz::Event.admin_add(g, u) },
|
48
|
+
:after_remove => proc { |u, g| Goz::Event.admin_remove(g, u) }
|
49
|
+
many_to_many :memberships,
|
50
|
+
:left_key => :user_id,
|
51
|
+
:right_key => :group_id,
|
52
|
+
:join_table => :members,
|
53
|
+
:class => :'Goz::Group',
|
54
|
+
:after_add => proc { |u, g| Goz::Event.member_add(g, u) },
|
55
|
+
:after_remove => proc { |u, g| Goz::Event.member_remove(g, u) }
|
56
|
+
|
57
|
+
|
58
|
+
#
|
59
|
+
# Initialize new (non-persistent) Goz::User object
|
60
|
+
#
|
61
|
+
def initialize(*params)
|
62
|
+
super
|
63
|
+
yield self if block_given?
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Compare equality.
|
69
|
+
#
|
70
|
+
def <=>(other)
|
71
|
+
if self.login < other.login ||
|
72
|
+
self.email < other.email ||
|
73
|
+
self.name < other.name ||
|
74
|
+
self.identifier < other.identifier
|
75
|
+
-1
|
76
|
+
elsif self.login > other.login ||
|
77
|
+
self.email > other.email ||
|
78
|
+
self.name > other.name ||
|
79
|
+
self.identifier > other.identifier
|
80
|
+
1
|
81
|
+
else
|
82
|
+
0
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Create Goz::User or raise +RuntimeError+
|
88
|
+
#
|
89
|
+
def self.create( params = {} )
|
90
|
+
params = {} unless params.kind_of?(Hash)
|
91
|
+
[ :email, :identifier, :login, :name ].each do |k|
|
92
|
+
raise( "invalid #{k.to_s}" ) if ( params[k].nil? || params[k].empty? )
|
93
|
+
end
|
94
|
+
super
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Find Goz::User by login or return +nil+
|
99
|
+
#
|
100
|
+
def self.find_by_login(login)
|
101
|
+
Goz::Database.instance do |db|
|
102
|
+
return User.find( :login => login )
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Synchronize user with external data sources (if relevant).
|
108
|
+
#
|
109
|
+
def sync(force = false)
|
110
|
+
if force || synchronized_at.nil? || synchronized_at < ( Time.now - ( 1 * 60 * 60 ) ) # XXX
|
111
|
+
# XXX Synchronize user with remote source (if necessary)
|
112
|
+
# XXX Synchronize groups
|
113
|
+
# XXX Synchronize memberships
|
114
|
+
self.synchronized_at = Time.now
|
115
|
+
self.save
|
116
|
+
Goz::Event.user_sync(self)
|
117
|
+
return true
|
118
|
+
end
|
119
|
+
false
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Perform model valiations.
|
124
|
+
#
|
125
|
+
def validate
|
126
|
+
super
|
127
|
+
validates_presence [ :email, :identifier, :login, :name ]
|
128
|
+
validates_type Time, [ :created_at, :modified_at, :synchronized_at ]
|
129
|
+
validates_unique [ :email, :identifier, :login ]
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def after_destroy
|
136
|
+
super
|
137
|
+
Event.create :event_type_id => Goz::EventType::USER_REMOVE, :user_id => self.id
|
138
|
+
end
|
139
|
+
|
140
|
+
def after_create
|
141
|
+
super
|
142
|
+
Event.create :event_type_id => Goz::EventType::USER_ADD, :user_id => self.id
|
143
|
+
end
|
144
|
+
|
145
|
+
def before_create
|
146
|
+
super
|
147
|
+
self.created_at ||= Time.now
|
148
|
+
end
|
149
|
+
|
150
|
+
def before_destroy
|
151
|
+
super
|
152
|
+
remove_all_memberships
|
153
|
+
remove_all_groups
|
154
|
+
end
|
155
|
+
|
156
|
+
def before_update
|
157
|
+
super
|
158
|
+
self.modified_at = Time.now
|
159
|
+
end
|
160
|
+
|
161
|
+
end # class User
|
162
|
+
|
163
|
+
end # module Goz
|
164
|
+
|