nakamura 0.1

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.
@@ -0,0 +1,92 @@
1
+ require 'test/unit.rb'
2
+ require 'nakamura'
3
+ require 'nakamura/users'
4
+ require 'nakamura/file'
5
+ require 'nakamura/search'
6
+ require 'tempfile'
7
+ require 'logger'
8
+
9
+ module SlingTest
10
+
11
+ @@log_level = Logger::DEBUG
12
+
13
+ def SlingTest.setLogLevel(level)
14
+ @@log_level = level
15
+ end
16
+
17
+ def setup
18
+ @s = SlingInterface::Sling.new()
19
+ @um = SlingUsers::UserManager.new(@s)
20
+ @search = SlingSearch::SearchManager.new(@s)
21
+ @created_nodes = []
22
+ @created_users = []
23
+ @created_groups = []
24
+ @delete = true
25
+ @log = Logger.new(STDOUT)
26
+ @log.level = @@log_level
27
+ end
28
+
29
+ def teardown
30
+ if ( @delete ) then
31
+ @s.switch_user(SlingUsers::User.admin_user)
32
+ @created_nodes.reverse.each { |n| @s.delete_node(n) }
33
+ @created_groups.each { |g| @um.delete_group(g) }
34
+ @created_users.each { |u| @um.delete_user(u.name) }
35
+ end
36
+ end
37
+
38
+ def create_node(path, props={})
39
+ #puts "Path is #{path}"
40
+ res = @s.create_node(path, props)
41
+ assert_not_equal("500", res.code, "Expected to be able to create node "+res.body)
42
+ @created_nodes << path
43
+ return path
44
+ end
45
+
46
+ def create_file_node(path, fieldname, filename, data, content_type="text/plain")
47
+ res = @s.create_file_node(path, fieldname, filename, data, content_type)
48
+ @created_nodes << path unless @created_nodes.include?(path)
49
+ return res
50
+ end
51
+
52
+ def create_user(username, firstname = nil, lastname = nil)
53
+ u = @um.create_user(username, firstname, lastname)
54
+ assert_not_nil(u, "Expected user to be created: #{username}")
55
+ @created_users << u
56
+ return u
57
+ end
58
+
59
+ def create_test_user(i)
60
+ u = @um.create_test_user(i)
61
+ assert_not_nil(u, "Expected user to be created: #{i}")
62
+ @created_users << u
63
+ return u
64
+ end
65
+
66
+ def create_group(groupname, title = nil)
67
+ g = @um.create_group(groupname, title)
68
+ assert_not_nil(g, "Expected group to be created: #{groupname}")
69
+ @created_groups << groupname
70
+ return g
71
+ end
72
+
73
+ def wait_for_indexer()
74
+ magic_content = "#{Time.now().to_i}_#{rand(1000).to_s}"
75
+ filename = "wait_for_indexer_#{magic_content}"
76
+
77
+ fm = SlingFile::FileManager.new(@s)
78
+ fm.upload_pooled_file(filename, magic_content, 'text/plain')
79
+
80
+ # Give the indexer up to 20 seconds to catch up, but stop waiting early if
81
+ # we find our test item has landed in the index.
82
+ 20.times do
83
+ res = @s.execute_get(@s.url_for("/var/search/files/allfiles.json?q=#{filename}"))
84
+ if JSON.parse(res.body)["total"] != 0
85
+ break
86
+ end
87
+ sleep(1)
88
+ end
89
+ end
90
+
91
+ end
92
+
@@ -0,0 +1,312 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'digest/sha1'
4
+ require 'logger'
5
+
6
+ $USERMANAGER_URI="system/userManager/"
7
+ $GROUP_URI="#{$USERMANAGER_URI}group.create.html"
8
+ $USER_URI="#{$USERMANAGER_URI}user.create.html"
9
+ $DEFAULT_PASSWORD="testuser"
10
+
11
+ module SlingUsers
12
+
13
+ class Principal
14
+
15
+ attr_accessor :name
16
+
17
+ def initialize(name)
18
+ @name = name
19
+ end
20
+
21
+
22
+ # Get the public path for a user
23
+ def public_path_for(sling)
24
+ return home_path_for(sling) + "/public"
25
+ end
26
+
27
+ # Get the private path for a user
28
+ def private_path_for(sling)
29
+ return home_path_for(sling) + "/private"
30
+ end
31
+
32
+ def message_path_for(sling,messageid,mailbox)
33
+ #return home_path_for(sling) + "/message/"+messageid[0,2]+"/"+messageid[2,2]+"/"+messageid[4,2]+"/"+messageid[6,2]+"/"+messageid
34
+ return home_path_for(sling) + "/message/#{mailbox}/#{messageid}"
35
+ end
36
+
37
+ end
38
+
39
+
40
+ class Group < Principal
41
+ def to_s
42
+ return "Group: #{@name}"
43
+ end
44
+
45
+ def update_properties(sling, props)
46
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"), props)
47
+ end
48
+
49
+ def add_member(sling, principal, type)
50
+ principal_path = "/#{$USERMANAGER_URI}#{type}/#{principal}"
51
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
52
+ { ":member" => principal_path })
53
+ end
54
+
55
+ def add_members(sling, principals)
56
+ principal_paths = principals.collect do |principal|
57
+ if principal.index("g-") == 0
58
+ type = "group"
59
+ else
60
+ type = "user"
61
+ end
62
+ "/#{$USERMANAGER_URI}#{type}/#{principal}"
63
+ end
64
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
65
+ { ":member" => principal_paths })
66
+ end
67
+
68
+ def add_manager(sling, principal)
69
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
70
+ { ":manager" => principal })
71
+ end
72
+
73
+ def add_viewer(sling, principal)
74
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
75
+ { ":viewer" => principal })
76
+ end
77
+
78
+ def details(sling)
79
+ return sling.get_node_props(group_url)
80
+ end
81
+
82
+ def remove_member(sling, principal, type)
83
+ principal_path = "/#{$USERMANAGER_URI}#{type}/#{principal}"
84
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
85
+ { ":member@Delete" => principal_path })
86
+ end
87
+
88
+ def has_member(sling, principal)
89
+ detail = self.details(sling)
90
+ members = detail["members"]
91
+ if (members == nil)
92
+ return false
93
+ end
94
+ return members.include?(principal)
95
+ end
96
+
97
+ def remove_member_viewer(sling, principal)
98
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
99
+ { ":member@Delete" => principal, ":viewer@Delete" => principal })
100
+ end
101
+
102
+ def add_member_viewer(sling, principal)
103
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
104
+ { ":member" => principal, ":viewer" => principal })
105
+ end
106
+
107
+ def remove_manager(sling, principal)
108
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
109
+ { ":manager@Delete" => principal })
110
+ end
111
+
112
+ def remove_viewer(sling, principal)
113
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
114
+ { ":viewer@Delete" => principal })
115
+ end
116
+
117
+ def remove_members(sling, principals)
118
+ principal_paths = principals.collect do |principal|
119
+ if principal.index("g-") == 0
120
+ type = "group"
121
+ else
122
+ type = "user"
123
+ end
124
+ "/#{$USERMANAGER_URI}#{type}/#{principal}"
125
+ end
126
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"),
127
+ { ":member@Delete" => principal_paths })
128
+ end
129
+
130
+ def set_joinable(sling, joinable)
131
+ return sling.execute_post(sling.url_for("#{group_url}.update.html"), "sakai:joinable" => joinable)
132
+ end
133
+
134
+ def members(sling)
135
+ props = sling.get_node_props(group_url)
136
+ return props["members"]
137
+ end
138
+
139
+ # Get the home folder of a group.
140
+ def home_path_for(sling)
141
+ return "/~#{@name}"
142
+ end
143
+
144
+ def self.url_for(name)
145
+ return "#{$USERMANAGER_URI}group/#{name}"
146
+ end
147
+
148
+ private
149
+ def group_url
150
+ return Group.url_for(@name)
151
+ end
152
+ end
153
+
154
+
155
+ class User < Principal
156
+ attr_accessor :password
157
+
158
+ def initialize(username, password=$DEFAULT_PASSWORD)
159
+ super(username)
160
+ @password = password
161
+ end
162
+
163
+ def self.admin_user
164
+ return User.new("admin", "admin")
165
+ end
166
+
167
+ def self.anonymous
168
+ return AnonymousUser.new
169
+ end
170
+
171
+ def do_request_auth(req)
172
+ req.basic_auth(@name, @password)
173
+ end
174
+
175
+ def do_curl_auth(c)
176
+ c.userpwd = "#{@name}:#{@password}"
177
+ end
178
+
179
+ def to_s
180
+ return "User: #{@name} (pass: #{@password})"
181
+ end
182
+
183
+ def update_properties(sling, props)
184
+ return sling.execute_post(sling.url_for("#{user_url}.update.html"), props)
185
+ end
186
+
187
+
188
+ def change_password(sling, newpassword)
189
+ return sling.execute_post(sling.url_for("#{user_url}.changePassword.html"), "oldPwd" => @password, "newPwd" => newpassword, "newPwdConfirm" => newpassword)
190
+ end
191
+
192
+
193
+ # Get the home folder of a group.
194
+ def home_path_for(sling)
195
+ return "/~#{@name}"
196
+ end
197
+
198
+
199
+ def self.url_for(name)
200
+ return "#{$USERMANAGER_URI}user/#{name}"
201
+ end
202
+
203
+ private
204
+ def user_url
205
+ return User.url_for(@name)
206
+ end
207
+ end
208
+
209
+ class AnonymousUser < User
210
+
211
+ def initialize()
212
+ super("anonymous", "none")
213
+ end
214
+
215
+ def do_curl_auth(c)
216
+ # do nothing
217
+ end
218
+
219
+ def do_request_auth(r)
220
+ # do nothing
221
+ end
222
+
223
+ end
224
+
225
+ class UserManager
226
+
227
+ attr_accessor :log
228
+
229
+ def initialize(sling)
230
+ @sling = sling
231
+ @date = Time.now().strftime("%Y%m%d%H%M%S%3N")
232
+ @log = Logger.new(STDOUT)
233
+ @log.level = Logger::WARN
234
+ end
235
+
236
+ def delete_test_user(id)
237
+ return delete_user("testuser#{@date}-#{id}")
238
+ end
239
+
240
+ def delete_user(username)
241
+ result = @sling.execute_post(@sling.url_for("#{User.url_for(username)}.delete.html"),
242
+ { "go" => 1 })
243
+ if (result.code.to_i > 299)
244
+ @log.info "Error deleting user"
245
+ return false
246
+ end
247
+ return true
248
+ end
249
+
250
+ def delete_group(groupname)
251
+ result = @sling.execute_post(@sling.url_for("#{Group.url_for(groupname)}.delete.html"),
252
+ { "go" => 1 })
253
+ if (result.code.to_i > 299)
254
+ @log.info "Error deleting group"
255
+ return false
256
+ end
257
+ return true
258
+ end
259
+
260
+ def create_test_user(id)
261
+ return create_user("testuser#{@date}-#{id}")
262
+ end
263
+
264
+ def create_user(username, firstname = nil, lastname = nil)
265
+ @log.info "Creating user: #{username}"
266
+ user = User.new(username)
267
+ data = { ":name" => user.name,
268
+ "pwd" => user.password,
269
+ "pwdConfirm" => user.password
270
+ }
271
+ if (!firstname.nil? and !lastname.nil?)
272
+ data[":sakai:profile-import"] = "{'basic': {'access': 'everybody', 'elements': {'email': {'value': '#{username}@sakai.invalid'}, 'firstName': {'value': '#{firstname}'}, 'lastName': {'value': '#{lastname}'}}}}"
273
+ # data[":sakai:pages-template"] = "/var/templates/site/defaultuser"
274
+ end
275
+ result = @sling.execute_post(@sling.url_for("#{$USER_URI}"), data)
276
+ if (result.code.to_i > 299)
277
+ @log.info "Error creating user"
278
+ return nil
279
+ end
280
+ return user
281
+ end
282
+
283
+ def create_group(groupname, title = nil)
284
+ @log.info "Creating group: #{groupname}"
285
+ group = Group.new(groupname)
286
+ params = { ":name" => group.name }
287
+ if (title)
288
+ params['sakai:group-title'] = title
289
+ end
290
+ params['sakai:group-description'] = ''
291
+ params['sakai:group-id'] = groupname
292
+ # params[':sakai:pages-template'] = '/var/templates/site/defaultgroup'
293
+ params['sakai:pages-visible'] = 'public'
294
+ params['sakai:group-joinable'] = 'yes'
295
+ result = @sling.execute_post(@sling.url_for($GROUP_URI), params)
296
+ if (result.code.to_i > 299)
297
+ return nil
298
+ end
299
+ return group
300
+ end
301
+
302
+ def get_user_props(name)
303
+ return @sling.get_node_props(User.url_for(name))
304
+ end
305
+
306
+ def get_group_props(name)
307
+ return @sling.get_node_props(Group.url_for(name))
308
+ end
309
+
310
+ end
311
+
312
+ end