google_apps_api 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,41 +10,20 @@ module GoogleAppsApi #:nodoc:
10
10
  super(:provisioning, *args)
11
11
  end
12
12
 
13
- def retrieve_user(username)
14
- request(:retrieve_user, :username => username)
13
+ def retrieve_user(user, *args)
14
+ username = user.kind_of?(UserEntity) ? user.id : user
15
+
16
+ options = args.extract_options!.merge(:username => username)
17
+ request(:retrieve_user, options)
15
18
  end
16
19
 
17
20
 
18
- def retrieve_all_users
19
- request(:retrieve_all_users)
21
+ def retrieve_all_users(*args)
22
+ options = args.extract_options!
23
+ request(:retrieve_all_users, options)
20
24
  end
21
- #
22
- # # Returns a UserEntry array populated with 100 users, starting from a username
23
- # # ex :
24
- # # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
25
- # # list= myapps.retrieve_page_of_users("jsmtih")
26
- # # list.each{ |user| puts user.username}
27
- # def retrieve_page_of_users(start_username)
28
- # param='?startUsername='+start_username
29
- # response = request(:user_retrieve_all,param,@headers)
30
- # user_feed = Feed.new(response.elements["feed"], UserEntry)
31
- # end
32
- #
33
- #
34
- # def contacts_retrieve_all()
35
- # response = request(:contacts_retrieve_all,nil, @headers)
36
- # end
37
- #
38
- # Creates an account in your domain, returns a UserEntry instance
39
- # params :
40
- # username, given_name, family_name and password are required
41
- # passwd_hash_function (optional) : nil (default) or "SHA-1"
42
- # quota (optional) : nil (default) or integer for limit in MB
43
- # ex :
44
- # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
45
- # user = myapps.create('jsmith', 'John', 'Smith', 'p455wD')
46
- #
47
- # By default, a new user must change his password at first login. Please use update_user if you want to change this just after the creation.
25
+
26
+
48
27
  def create_user(username, *args)
49
28
  options = args.extract_options!
50
29
  options.each { |k,v| options[k] = escapeXML(v)}
@@ -52,243 +31,88 @@ module GoogleAppsApi #:nodoc:
52
31
  res = <<-DESCXML
53
32
  <?xml version="1.0" encoding="UTF-8"?>
54
33
  <atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
55
- xmlns:apps="http://schemas.google.com/apps/2006">
56
- <atom:category scheme="http://schemas.google.com/g/2005#kind"
57
- term="http://schemas.google.com/apps/2006#user"/>
58
- <apps:login userName="#{escapeXML(username)}"
59
- password="#{options[:password]}" suspended="false"/>
60
- <apps:name familyName="#{options[:family_name]}" givenName="#{options[:given_name]}"/>
34
+ xmlns:apps="http://schemas.google.com/apps/2006">
35
+ <atom:category scheme="http://schemas.google.com/g/2005#kind"
36
+ term="http://schemas.google.com/apps/2006#user"/>
37
+ <apps:login userName="#{escapeXML(username)}"
38
+ password="#{options[:password]}" suspended="false"/>
39
+ <apps:name familyName="#{options[:family_name]}" givenName="#{options[:given_name]}"/>
61
40
  </atom:entry>
62
41
 
63
42
  DESCXML
64
43
 
65
-
66
- request(:create_user, :body => res.strip)
44
+
45
+ request(:create_user, options.merge(:body => res.strip))
67
46
  end
68
- #
69
- # # Updates an account in your domain, returns a UserEntry instance
70
- # # params :
71
- # # username is required and can't be updated.
72
- # # given_name and family_name are required, may be updated.
73
- # # if set to nil, every other parameter won't update the attribute.
74
- # # passwd_hash_function : string "SHA-1", "MD5" or nil (default)
75
- # # admin : string "true" or string "false" or nil (no boolean : true or false).
76
- # # suspended : string "true" or string "false" or nil (no boolean : true or false)
77
- # # change_passwd : string "true" or string "false" or nil (no boolean : true or false)
78
- # # quota : limit en MB, ex : string "2048"
79
- # # ex :
80
- # # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
81
- # # user = myapps.update('jsmith', 'John', 'Smith', nil, nil, "true", nil, "true", nil)
82
- # # puts user.admin => "true"
47
+
48
+
83
49
  def update_user(username, *args)
84
50
  options = args.extract_options!
85
51
  options.each { |k,v| options[k] = escapeXML(v)}
86
-
52
+
87
53
  res = <<-DESCXML
88
54
  <?xml version="1.0" encoding="UTF-8"?>
89
55
  <atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
90
- xmlns:apps="http://schemas.google.com/apps/2006">
91
- <atom:category scheme="http://schemas.google.com/g/2005#kind"
92
- term="http://schemas.google.com/apps/2006#user"/>
93
- <apps:name familyName="#{options[:family_name]}" givenName="#{options[:given_name]}"/>
56
+ xmlns:apps="http://schemas.google.com/apps/2006">
57
+ <atom:category scheme="http://schemas.google.com/g/2005#kind"
58
+ term="http://schemas.google.com/apps/2006#user"/>
59
+ <apps:name familyName="#{options[:family_name]}" givenName="#{options[:given_name]}"/>
94
60
  </atom:entry>
95
-
61
+
96
62
  DESCXML
97
- request(:update_user, :username => username, :body => res.strip)
63
+ request(:update_user, options.merge(:username => username, :body => res.strip))
98
64
  end
99
- #
100
- # # Renames a user, returns a UserEntry instance
101
- # # ex :
102
- # #
103
- # # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
104
- # # user = myapps.rename_user('jsmith','jdoe')
105
- # #
106
- # # It is recommended to log out rhe user from all browser sessions and service before renaming.
107
- # # Once renamed, the old username becomes a nickname of the new username.
108
- # # Note from Google: Google Talk will lose all remembered chat invitations after renaming.
109
- # # The user must request permission to chat with friends again.
110
- # # Also, when a user is renamed, the old username is retained as a nickname to ensure continuous mail delivery in the case of email forwarding settings.
111
- # # To remove the nickname, you should issue an HTTP DELETE to the nicknames feed after renaming.
112
- # def rename_user(username, new_username)
113
- # msg = RequestMessage.new
114
- # msg.about_login(new_username)
115
- # msg.add_path('https://'+@@google_host+@action[:user_rename][:path]+username)
116
- # response = request(:user_update,username,@headers, msg.to_s)
117
- # end
118
- #
119
- # # Suspends an account in your domain, returns a UserEntry instance
120
- # # ex :
121
- # # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
122
- # # user = myapps.suspend('jsmith')
123
- # # puts user.suspended => "true"
124
- # def suspend_user(username)
125
- # msg = RequestMessage.new
126
- # msg.about_login(username,nil,nil,nil,"true")
127
- # msg.add_path('https://'+@@google_host+@action[:user_update][:path]+username)
128
- # response = request(:user_update,username,@headers, msg.to_s)
129
- # user_entry = UserEntry.new(response.elements["entry"])
130
- # end
131
- #
132
- # # Restores a suspended account in your domain, returns a UserEntry instance
133
- # # ex :
134
- # # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
135
- # # user = myapps.restore('jsmith')
136
- # # puts user.suspended => "false"
137
- # def restore_user(username)
138
- # msg = RequestMessage.new
139
- # msg.about_login(username,nil,nil,nil,"false")
140
- # msg.add_path('https://'+@@google_host+@action[:user_update][:path]+username)
141
- # response = request(:user_update,username,@headers, msg.to_s)
142
- # user_entry = UserEntry.new(response.elements["entry"])
143
- # end
144
- #
145
- # # Deletes an account in your domain
146
- # # ex :
147
- # # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
148
- # # myapps.delete('jsmith')
149
- def delete_user(username)
150
- response = request(:delete_user, :username => username)
65
+
66
+
67
+ def delete_user(username, *args)
68
+ options = args.extract_options!.merge(:username => username)
69
+ request(:delete_user, options)
151
70
  end
152
71
 
153
72
 
154
73
  end
155
74
 
156
-
157
- #
158
- #
159
- # class RequestMessage < Document #:nodoc:
160
- # # Request message constructor.
161
- # # parameter type : "user", "nickname" or "emailList"
162
- #
163
- # # creates the object and initiates the construction
164
- # def initialize
165
- # super '<?xml version="1.0" encoding="UTF-8"?>'
166
- # self.add_element "atom:entry", {"xmlns:apps" => "http://schemas.google.com/apps/2006",
167
- # "xmlns:gd" => "http://schemas.google.com/g/2005",
168
- # "xmlns:atom" => "http://www.w3.org/2005/Atom"}
169
- #
170
- # self.elements["atom:entry"].add_element "atom:category", {"scheme" => "http://schemas.google.com/g/2005#kind"}
171
- #
172
- # end
173
- #
174
- # # adds <atom:id> element in the message body. Url is inserted as a text.
175
- # def add_path(url)
176
- # self.elements["atom:entry"].add_element "atom:id"
177
- # self.elements["atom:entry/atom:id"].text = url
178
- # end
179
- #
180
- # # adds <apps:emailList> element in the message body.
181
- # def about_email_list(email_list)
182
- # self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#emailList")
183
- # self.elements["atom:entry"].add_element "apps:emailList", {"name" => email_list }
184
- # end
185
- #
186
- # # adds <apps:property> element in the message body for a group.
187
- # def about_group(group_id, properties)
188
- # self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#emailList")
189
- # self.elements["atom:entry"].add_element "apps:property", {"name" => "groupId", "value" => group_id }
190
- # self.elements["atom:entry"].add_element "apps:property", {"name" => "groupName", "value" => properties[0] }
191
- # self.elements["atom:entry"].add_element "apps:property", {"name" => "description", "value" => properties[1] }
192
- # self.elements["atom:entry"].add_element "apps:property", {"name" => "emailPermission", "value" => properties[2] }
193
- # end
194
- #
195
- # # adds <apps:property> element in the message body for a member.
196
- # def about_member(email_address)
197
- # self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#user")
198
- # self.elements["atom:entry"].add_element "apps:property", {"name" => "memberId", "value" => email_address }
199
- # end
200
- #
201
- # # adds <apps:property> element in the message body for an owner.
202
- # def about_owner(email_address)
203
- # self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#user")
204
- # self.elements["atom:entry"].add_element "apps:property", {"name" => "email", "value" => email_address }
205
- # end
206
- #
207
- #
208
- # # adds <apps:login> element in the message body.
209
- # # warning : if valued admin, suspended, or change_passwd_at_next_login must be the STRINGS "true" or "false", not the boolean true or false
210
- # # when needed to construct the message, should always been used before other "about_" methods so that the category tag can be overwritten
211
- # # only values permitted for hash_function_function_name : "SHA-1", "MD5" or nil
212
- # def about_login(user_name, passwd=nil, hash_function_name=nil, admin=nil, suspended=nil, change_passwd_at_next_login=nil)
213
- # self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#user")
214
- # self.elements["atom:entry"].add_element "apps:login", {"userName" => user_name }
215
- # self.elements["atom:entry/apps:login"].add_attribute("password", passwd) if not passwd.nil?
216
- # self.elements["atom:entry/apps:login"].add_attribute("hashFunctionName", hash_function_name) if not hash_function_name.nil?
217
- # self.elements["atom:entry/apps:login"].add_attribute("admin", admin) if not admin.nil?
218
- # self.elements["atom:entry/apps:login"].add_attribute("suspended", suspended) if not suspended.nil?
219
- # self.elements["atom:entry/apps:login"].add_attribute("changePasswordAtNextLogin", change_passwd_at_next_login) if not change_passwd_at_next_login.nil?
220
- # return self
221
- # end
222
- #
223
- # # adds <apps:quota> in the message body.
224
- # # limit in MB: integer
225
- # def about_quota(limit)
226
- # self.elements["atom:entry"].add_element "apps:quota", {"limit" => limit }
227
- # return self
228
- # end
229
- #
230
- # # adds <apps:name> in the message body.
231
- # def about_name(family_name, given_name)
232
- # self.elements["atom:entry"].add_element "apps:name", {"familyName" => family_name, "givenName" => given_name }
233
- # return self
234
- # end
235
- #
236
- # # adds <apps:nickname> in the message body.
237
- # def about_nickname(name)
238
- # self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#nickname")
239
- # self.elements["atom:entry"].add_element "apps:nickname", {"name" => name}
240
- # return self
241
- # end
242
- #
243
- # # adds <gd:who> in the message body.
244
- # def about_who(email)
245
- # self.elements["atom:entry"].add_element "gd:who", {"email" => email }
246
- # return self
247
- # end
248
- #
249
- # end
250
- # end
251
75
  end
252
-
253
76
 
254
77
 
255
- class UserEntry < Entry
256
- attr_accessor :given_name, :family_name, :username, :suspended, :ip_whitelisted, :admin, :change_password_at_next_login, :agreed_to_terms, :quota_limit
257
-
258
- def initialize(xml = nil)
259
- if xml
260
- @family_name = xml.at_xpath("//apps:name").attribute("familyName").content
261
- @given_name = xml.at_xpath("//apps:name").attribute("givenName").content
262
- @username = xml.at_xpath("//apps:login").attribute("userName").content
263
- @suspended = xml.at_xpath("//apps:login").attribute("suspended").content
264
- @ip_whitelisted = xml.at_xpath("//apps:login").attribute("ipWhitelisted").content
265
- @admin = xml.at_xpath("//apps:login").attribute("admin").content
266
- @change_password_at_next_login = xml.at_xpath("//apps:login").attribute("changePasswordAtNextLogin").content
267
- @agreed_to_terms = xml.at_xpath("//apps:login").attribute("agreedToTerms").content
268
- @quota_limit = xml.at_xpath("//apps:quota").attribute("limit").content
78
+ class UserEntity < Entity
79
+ attr_accessor :given_name, :family_name, :username, :suspended, :ip_whitelisted, :admin, :change_password_at_next_login, :agreed_to_terms, :quota_limit, :domain
80
+
81
+ def initialize(*args)
82
+ options = args.extract_options!
83
+ if (_xml = options[:xml])
84
+ xml = _xml.at_css("entry") || _xml
85
+ @kind = "user"
86
+ @id = xml.at_css("apps|login").attribute("userName").content
87
+ @domain = xml.at_css("id").content.gsub(/^.+\/feeds\/([^\/]+)\/.+$/,"\\1")
88
+
89
+ @family_name = xml.at_css("apps|name").attribute("familyName").content
90
+ @given_name = xml.at_css("apps|name").attribute("givenName").content
91
+ @suspended = xml.at_css("apps|login").attribute("suspended").content
92
+ @ip_whitelisted = xml.at_css("apps|login").attribute("ipWhitelisted").content
93
+ @admin = xml.at_css("apps|login").attribute("admin").content
94
+ @change_password_at_next_login = xml.at_css("apps|login").attribute("changePasswordAtNextLogin").content
95
+ @agreed_to_terms = xml.at_css("apps|login").attribute("agreedToTerms").content
96
+ @quota_limit = xml.at_css("apps|quota").attribute("limit").content
97
+ else
98
+ if args.first.kind_of?(String)
99
+ super(:user => args.first)
100
+ else
101
+ super(options.merge(:kind => "user"))
102
+ end
269
103
  end
270
104
  end
271
-
272
- def to_s
273
- username
105
+
106
+ def entity_for_base_calendar
107
+ CalendarEntity.new(self.full_id)
274
108
  end
275
-
276
- def inspect
277
- "<UserEntry: #{username} : #{given_name} #{family_name}>"
109
+
110
+ def get_base_calendar(c_api, *args)
111
+ c_api.retrieve_calendar_for_user(self.entity_for_base_calendar, self, *args)
278
112
  end
279
-
280
- def create_message(*args)
281
-
113
+
114
+ def get_calendars(c_api, *args)
115
+ c_api.retrieve_calendars_for_user(self, *args)
282
116
  end
283
- #
284
- # def add_message
285
- # Nokogiri::XML::Builder.new { |xml|
286
- # xml.entry(:xmlns => "http://www.w3.org/2005/Atom") {
287
- # xml.id_ {
288
- # xml.text id.to_s
289
- # }
290
- # }
291
- # }.to_xml
292
- # end
293
117
  end
294
118
  end
@@ -0,0 +1,4 @@
1
+ apps_ocelot:
2
+ domain: ocelot.cul.columbia.edu
3
+ admin_user: adminuserhere
4
+ admin_password: adminpasswordhere
@@ -0,0 +1,76 @@
1
+ require 'test_helper'
2
+
3
+ class GoogleAppsApiBaseApiTest < Test::Unit::TestCase
4
+ include GoogleAppsApi
5
+
6
+ context "given an example entity" do
7
+ setup do
8
+ @en = Entity.new(:kind => "user", :id => "test1", :domain => "ocelot.cul.columbia.edu")
9
+ @c_en = Entity.new(:kind => "calendar", :id => "js235", :domain => "ocelot.cul.columbia.edu")
10
+ @d_en = Entity.new(:kind => "domain", :id => "ocelot.cul.columbia.edu")
11
+ @co_en = Entity.new(:kind => "contact", :id => "12345")
12
+ end
13
+
14
+
15
+ should "reject items without kind and id" do
16
+ assert_raises ArgumentError do
17
+ Entity.new(:id => "test1", :domain => "oc")
18
+ end
19
+
20
+ assert_raises ArgumentError do
21
+ Entity.new(:kind => "user", :domain => "oc")
22
+ end
23
+ end
24
+
25
+ should "accept a user argument" do
26
+ u_en = Entity.new(:user => "test1", :domain => "ocelot.cul.columbia.edu")
27
+
28
+ assert_equal @en, u_en
29
+ end
30
+
31
+ should "split domains out" do
32
+ u_en = Entity.new(:user => "test1@ocelot.cul.columbia.edu")
33
+
34
+ assert_equal @en, u_en
35
+ end
36
+
37
+
38
+ should "split encoded domains out" do
39
+ u_en = Entity.new(:user => "test1%40ocelot.cul.columbia.edu")
40
+
41
+ assert_equal @en, u_en
42
+ end
43
+
44
+ should "be able to display the encoded and non-encoded versions" do
45
+ assert_equal "test1@ocelot.cul.columbia.edu", @en.full_id
46
+ assert_equal "test1%40ocelot.cul.columbia.edu", @en.full_id_escaped
47
+ assert_equal "ocelot.cul.columbia.edu", @d_en.full_id
48
+ assert_equal "ocelot.cul.columbia.edu", @d_en.full_id_escaped
49
+ end
50
+
51
+ should "be able to create user entities" do
52
+ assert_equal @en, UserEntity.new("test1@ocelot.cul.columbia.edu")
53
+ assert_equal @en, UserEntity.new("test1%40ocelot.cul.columbia.edu")
54
+ assert_equal @en, UserEntity.new(:id => "test1", :domain => "ocelot.cul.columbia.edu")
55
+ end
56
+
57
+
58
+ should "be able to create calendar entities" do
59
+ assert_equal @c_en, CalendarEntity.new("js235@ocelot.cul.columbia.edu")
60
+ assert_equal @c_en, CalendarEntity.new("js235%40ocelot.cul.columbia.edu")
61
+ assert_equal @c_en, CalendarEntity.new(:id => "js235", :domain => "ocelot.cul.columbia.edu")
62
+ end
63
+
64
+ should "be able to derive a calendar entity from a user entity" do
65
+ assert_equal @c_en, UserEntity.new("js235@ocelot.cul.columbia.edu").entity_for_base_calendar
66
+ end
67
+
68
+ should "be able to display the qualified id, escape and nonescaped" do
69
+ assert_equal "user:test1@ocelot.cul.columbia.edu", @en.qualified_id
70
+ assert_equal "user%3Atest1%40ocelot.cul.columbia.edu", @en.qualified_id_escaped
71
+ assert_equal "domain:ocelot.cul.columbia.edu", @d_en.qualified_id
72
+ assert_equal "domain%3Aocelot.cul.columbia.edu", @d_en.qualified_id_escaped
73
+ end
74
+ end
75
+
76
+ end