google_apps_api 0.1.0 → 0.2.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.
@@ -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