google_apps 0.4.5 → 0.4.6
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/lib/google_apps/atom/atom.rb +21 -0
- data/lib/google_apps/atom/group_member.rb +8 -17
- data/lib/google_apps/atom/nickname.rb +148 -0
- data/lib/google_apps/atom/node.rb +59 -0
- data/lib/google_apps/transport.rb +11 -21
- data/lib/google_apps.rb +3 -1
- metadata +23 -25
@@ -2,9 +2,30 @@ require 'libxml'
|
|
2
2
|
require 'openssl'
|
3
3
|
require 'base64'
|
4
4
|
|
5
|
+
class String
|
6
|
+
def camel_up
|
7
|
+
self.split('_').map(&:capitalize).join('')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
module GoogleApps
|
6
12
|
module Atom
|
7
13
|
include LibXML
|
14
|
+
|
8
15
|
HASH_FUNCTION = "SHA-1"
|
16
|
+
DOCUMENTS = %w(user export group group_member message_attributes public_key)
|
17
|
+
|
18
|
+
NAMESPACES = {
|
19
|
+
atom: 'http://www.w3.org/2005/Atom',
|
20
|
+
apps: 'http://schemas.google.com/apps/2006',
|
21
|
+
gd: 'http://schemas.google.com/g/2005'
|
22
|
+
}
|
23
|
+
|
24
|
+
# The idea is to make document distribution more dynamic.
|
25
|
+
# Might be pointless but it's here for now.
|
26
|
+
DOCUMENTS.each do |doc|
|
27
|
+
eval "def #{doc}\n #{doc.camel_up}.new\nend"
|
28
|
+
module_function doc.to_sym
|
29
|
+
end
|
9
30
|
end
|
10
31
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module GoogleApps
|
2
2
|
module Atom
|
3
3
|
class GroupMember
|
4
|
+
include GoogleApps::Atom::Node
|
4
5
|
attr_accessor :member
|
5
6
|
|
6
7
|
def initialize
|
@@ -37,28 +38,12 @@ module GoogleApps
|
|
37
38
|
#
|
38
39
|
# set_member returns the value of @member
|
39
40
|
def set_member(member)
|
40
|
-
@document.root <<
|
41
|
+
@document.root << create_node(type: 'apps:property', attrs: [['name', 'memberId'], ['value', member]])
|
41
42
|
|
42
43
|
@member = member
|
43
44
|
end
|
44
45
|
|
45
46
|
|
46
|
-
# build_node creates an apps:property element
|
47
|
-
# for memberId with the provided argument as
|
48
|
-
# the value.
|
49
|
-
#
|
50
|
-
# build_node 'test_user@cnm.edu'
|
51
|
-
#
|
52
|
-
# build_node returns an apps:property XML Node.
|
53
|
-
def build_node(member)
|
54
|
-
node = Atom::XML::Node.new('apps:property')
|
55
|
-
node.attributes['name'] = 'memberId'
|
56
|
-
node.attributes['value'] = member
|
57
|
-
|
58
|
-
node
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
47
|
# change_member changes the value attribute of the
|
63
48
|
# apps:property element in @document to the value
|
64
49
|
# of the provided argument. It also sets @member
|
@@ -77,6 +62,12 @@ module GoogleApps
|
|
77
62
|
@member = member
|
78
63
|
end
|
79
64
|
|
65
|
+
# parse_doc parses the current @document so that it can
|
66
|
+
# be searched with find.
|
67
|
+
def parse_doc(document = @document)
|
68
|
+
Atom::XML::Parser.document(document).parse
|
69
|
+
end
|
70
|
+
|
80
71
|
|
81
72
|
# add_header sets the root element of @document
|
82
73
|
def add_header
|
@@ -0,0 +1,148 @@
|
|
1
|
+
module GoogleApps
|
2
|
+
module Atom
|
3
|
+
class Nickname
|
4
|
+
include GoogleApps::Atom::Node
|
5
|
+
attr_reader :nickname, :user, :document
|
6
|
+
|
7
|
+
ELEMENTS = { nick: ['apps:nickname', 'name'], user: ['apps:login', 'userName'] }
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@document = Atom::XML::Document.new
|
11
|
+
@document.root = header
|
12
|
+
@document.root << category
|
13
|
+
end
|
14
|
+
|
15
|
+
# nickname= sets the nickname value on the object and in the
|
16
|
+
# underlying XML document. It takes a string as an argument.
|
17
|
+
#
|
18
|
+
# nickname = 'Timmy'
|
19
|
+
#
|
20
|
+
# nickname= returns the new nickname value
|
21
|
+
def nickname=(nick)
|
22
|
+
@nickname.nil? ? set_nickname(nick) : change_nickname(nick)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# user= sets the username value on the object and in the
|
27
|
+
# underlying XML document. It takes a string (default/current username)
|
28
|
+
# as an argument.
|
29
|
+
#
|
30
|
+
# user = 'tom'
|
31
|
+
#
|
32
|
+
# user= returns the new username value
|
33
|
+
def user=(username)
|
34
|
+
@user.nil? ? set_user(username) : change_user(username)
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# to_s returns the underlying XML document as a string.
|
39
|
+
def to_s
|
40
|
+
@document.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
|
48
|
+
# header returns an atom:entry node with the appropriate
|
49
|
+
# namespaces for a GoogleApps nickname document
|
50
|
+
def header
|
51
|
+
node = Atom::XML::Node.new('atom:entry')
|
52
|
+
|
53
|
+
Atom::XML::Namespace.new(node, 'atom', 'http://www.w3.org/2005/Atom')
|
54
|
+
Atom::XML::Namespace.new(node, 'apps', 'http://schemas.google.com/apps/2006')
|
55
|
+
|
56
|
+
node
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# category constructs an atom:category node with the
|
61
|
+
# appropriate attributes for a GoogleApps nickname
|
62
|
+
# document.
|
63
|
+
def category
|
64
|
+
node = Atom::XML::Node.new('atom:category')
|
65
|
+
node.attributes['scheme'] = 'http://schemas.google.com/g/2005#kind'
|
66
|
+
node.attributes['term'] = 'http://schemas.google.com/apps/2006#nickname'
|
67
|
+
|
68
|
+
node
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# set_nickname adds an apps:nickname node to the
|
73
|
+
# underlying XML document and sets @nickname.
|
74
|
+
# It takes a nickname in string form for its
|
75
|
+
# argument.
|
76
|
+
#
|
77
|
+
# set_nickname 'Timmy'
|
78
|
+
#
|
79
|
+
# set_nickname returns the new nickname value.
|
80
|
+
def set_nickname(nick)
|
81
|
+
@document.root << create_node(type: 'apps:nickname', attrs: [['name', nick]])
|
82
|
+
|
83
|
+
@nickname = nick
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
# set_user adds an apps:login node to the underlying
|
88
|
+
# XML document and sets @user. It takes a username
|
89
|
+
# (current/default username) in string form for its
|
90
|
+
# argument.
|
91
|
+
#
|
92
|
+
# set_user 'bob'
|
93
|
+
#
|
94
|
+
# set_user returns the new user value.
|
95
|
+
def set_user(username)
|
96
|
+
@document.root << create_node(type: 'apps:login', attrs: [['userName', username]])
|
97
|
+
|
98
|
+
@user = username
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# change_nickname changes the name attribute for the
|
103
|
+
# apps:nickname node in the underlying XML document.
|
104
|
+
# It takes a nickname in string form.
|
105
|
+
#
|
106
|
+
# change_nickname 'Timmy'
|
107
|
+
#
|
108
|
+
# change_nickname returns the new nickname.
|
109
|
+
def change_nickname(nick)
|
110
|
+
@document.root.each do |node|
|
111
|
+
node.attributes['name'] = nick if node.attributes['name'] == @nickname
|
112
|
+
end
|
113
|
+
|
114
|
+
@nickname = nick
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
# change_user changes the userName attribute for the
|
119
|
+
# apps:login node in the underlying XML document. It
|
120
|
+
# takes a username (Email format) in string form.
|
121
|
+
#
|
122
|
+
# change_user 'bob@work.com'
|
123
|
+
#
|
124
|
+
# change_user returns the new user value.
|
125
|
+
def change_user(username)
|
126
|
+
@document.root.each do |node|
|
127
|
+
node.attributes['userName'] = username if node.attributes['userName'] == @user
|
128
|
+
end
|
129
|
+
|
130
|
+
@user = username
|
131
|
+
end
|
132
|
+
|
133
|
+
# :nodoc:
|
134
|
+
def change_element(type, value)
|
135
|
+
@document.root.each do |node|
|
136
|
+
node.attributes[ELEMENTS[type][1]] = value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# parse_document takes an XML document and returns
|
142
|
+
# a parsed copy of that document.
|
143
|
+
def parse_document(document = @document)
|
144
|
+
Atom::XML::Parser.document(document).parse
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module GoogleApps
|
2
|
+
module Atom
|
3
|
+
module Node
|
4
|
+
|
5
|
+
# create_node takes a hash of properties from which to
|
6
|
+
# build the XML node. The properties hash must have
|
7
|
+
# a :type key, it is also possible to pass an :attrs
|
8
|
+
# key with an array of attribute name, value pairs.
|
9
|
+
#
|
10
|
+
# create_node type: 'apps:property', attrs: [['name', 'Tim'], ['userName', 'tim@bob.com']]
|
11
|
+
#
|
12
|
+
# create_node returns an Atom::XML::Node with the specified
|
13
|
+
# properties.
|
14
|
+
def create_node(properties)
|
15
|
+
if properties[:attrs]
|
16
|
+
add_attributes Atom::XML::Node.new(properties[:type]), properties[:attrs]
|
17
|
+
else
|
18
|
+
Atom::XML::Node.new properties[:type]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# add_attributes adds the specified attributes to the
|
24
|
+
# given node. It takes a LibXML::XML::Node and an
|
25
|
+
# array of name, value attribute pairs.
|
26
|
+
#
|
27
|
+
# add_attribute node, [['title', 'emperor'], ['name', 'Napoleon']]
|
28
|
+
#
|
29
|
+
# add_attribute returns the modified node.
|
30
|
+
def add_attributes(node, attributes)
|
31
|
+
attributes.each do |attribute|
|
32
|
+
node.attributes[attribute[0]] = attribute[1]
|
33
|
+
end
|
34
|
+
|
35
|
+
node
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# update_node updates the values for the specified
|
40
|
+
# attributes on the node specified by the given xpath
|
41
|
+
# value. It is ill behaved and will change any
|
42
|
+
# matching attributes in any node returned using the
|
43
|
+
# given xpath.
|
44
|
+
#
|
45
|
+
# update_node takes a document (must be parsed), an
|
46
|
+
# xpath value and a hash of attribute names with
|
47
|
+
# current and new value pairs.
|
48
|
+
#
|
49
|
+
# update_node document, '/apps:nickname', name: ['Bob', 'Tom']
|
50
|
+
def find_and_update(document, xpath, attributes)
|
51
|
+
document.find(xpath).each do |node|
|
52
|
+
attributes.each_key do |attrib|
|
53
|
+
node.attributes[attrib.to_s] = attributes[attrib][1] if node.attributes[attrib.to_s] == attributes[attrib][0]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -6,7 +6,7 @@ require 'rexml/document'
|
|
6
6
|
module GoogleApps
|
7
7
|
class Transport
|
8
8
|
attr_reader :request, :response, :domain
|
9
|
-
attr_accessor :auth, :user, :group, :nickname
|
9
|
+
attr_accessor :auth, :user, :group, :nickname, :export
|
10
10
|
|
11
11
|
BOUNDARY = "=AaB03xDFHT8xgg"
|
12
12
|
|
@@ -16,7 +16,7 @@ module GoogleApps
|
|
16
16
|
@pubkey = targets[:pubkey] || "https://apps-apis.google.com/a/feeds/compliance/audit/publickey/#{domain}"
|
17
17
|
@migration = targets[:migration] || "https://apps-apis.google.com/a/feeds/migration/2.0/#{domain}"
|
18
18
|
@group = targets[:group] || "https://apps-apis.google.com/a/feeds/group/2.0/#{domain}"
|
19
|
-
@nickname = targets[:nickname]
|
19
|
+
@nickname = targets[:nickname] || "https://apps-apis.google.com/a/feeds/#{domain}/nickname/2.0"
|
20
20
|
@export = targets[:export] || "https://apps-apis.google.com/a/feeds/compliance/audit/mail/export/#{domain}"
|
21
21
|
@domain = domain
|
22
22
|
@token = nil
|
@@ -39,7 +39,7 @@ module GoogleApps
|
|
39
39
|
@request.body = auth_body(account, pass)
|
40
40
|
set_headers :auth
|
41
41
|
|
42
|
-
@response = request
|
42
|
+
@response = request uri
|
43
43
|
|
44
44
|
set_auth_token
|
45
45
|
|
@@ -56,12 +56,7 @@ module GoogleApps
|
|
56
56
|
# request_export returns the HTTP response received
|
57
57
|
# from Google.
|
58
58
|
def request_export(username, document)
|
59
|
-
|
60
|
-
@request = Net::HTTP::Post.new uri.path
|
61
|
-
@request.body = document.to_s
|
62
|
-
set_headers :user
|
63
|
-
|
64
|
-
@response = request(uri)
|
59
|
+
add(@export + "/#{username}", document)
|
65
60
|
end
|
66
61
|
|
67
62
|
# export_status checks the status of a mailbox export
|
@@ -70,15 +65,10 @@ module GoogleApps
|
|
70
65
|
#
|
71
66
|
# export_status 'username', 847576
|
72
67
|
#
|
73
|
-
# export_status will return the
|
68
|
+
# export_status will return the status of the HTTP
|
74
69
|
# response from Google
|
75
70
|
def export_status(username, req_id)
|
76
|
-
|
77
|
-
@request = Net::HTTP::Get.new uri.path
|
78
|
-
set_headers :user
|
79
|
-
|
80
|
-
# TODO: Return actual status not whole body.
|
81
|
-
(@response = request(uri)).body
|
71
|
+
get(@export + "/#{username}", req_id)
|
82
72
|
end
|
83
73
|
|
84
74
|
def fetch_export(username, req_id, filename) # :nodoc:
|
@@ -124,7 +114,7 @@ module GoogleApps
|
|
124
114
|
@request = Net::HTTP::Get.new(uri.path)
|
125
115
|
set_headers :user
|
126
116
|
|
127
|
-
@response = request
|
117
|
+
@response = request uri
|
128
118
|
end
|
129
119
|
|
130
120
|
|
@@ -165,7 +155,7 @@ module GoogleApps
|
|
165
155
|
@request.body = document.to_s
|
166
156
|
set_headers :user
|
167
157
|
|
168
|
-
@response = request
|
158
|
+
@response = request uri
|
169
159
|
end
|
170
160
|
|
171
161
|
# update is a generic target for method_missing. It is
|
@@ -184,7 +174,7 @@ module GoogleApps
|
|
184
174
|
@request.body = document.to_s
|
185
175
|
set_headers :user
|
186
176
|
|
187
|
-
@response = request
|
177
|
+
@response = request uri
|
188
178
|
end
|
189
179
|
|
190
180
|
# delete is a generic target for method_missing. It is
|
@@ -200,7 +190,7 @@ module GoogleApps
|
|
200
190
|
@request = Net::HTTP::Delete.new(uri.path)
|
201
191
|
set_headers :user
|
202
192
|
|
203
|
-
@response = request
|
193
|
+
@response = request uri
|
204
194
|
end
|
205
195
|
|
206
196
|
# migration performs mail migration from a local
|
@@ -217,7 +207,7 @@ module GoogleApps
|
|
217
207
|
@request.body = multi_part(properties.to_s, message)
|
218
208
|
set_headers :migrate
|
219
209
|
|
220
|
-
@response = request
|
210
|
+
@response = request uri
|
221
211
|
end
|
222
212
|
|
223
213
|
|
data/lib/google_apps.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'google_apps/transport'
|
2
2
|
require 'google_apps/atom/atom'
|
3
|
+
require 'google_apps/atom/node'
|
3
4
|
require 'google_apps/atom/user'
|
4
5
|
require 'google_apps/atom/group'
|
5
6
|
require 'google_apps/atom/public_key'
|
6
7
|
require 'google_apps/atom/export'
|
7
8
|
require 'google_apps/atom/message'
|
8
9
|
require 'google_apps/atom/message_attributes'
|
9
|
-
require 'google_apps/atom/group_member'
|
10
|
+
require 'google_apps/atom/group_member'
|
11
|
+
require 'google_apps/atom/nickname'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google_apps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: libxml-ruby
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,33 +21,30 @@ dependencies:
|
|
21
21
|
version: 2.2.2
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.2.2
|
25
30
|
description: Library for interfacing with Google Apps' Domain and Application APIs
|
26
31
|
email:
|
27
32
|
executables: []
|
28
33
|
extensions: []
|
29
34
|
extra_rdoc_files: []
|
30
35
|
files:
|
31
|
-
-
|
32
|
-
|
33
|
-
-
|
34
|
-
|
35
|
-
-
|
36
|
-
|
37
|
-
-
|
38
|
-
|
39
|
-
-
|
40
|
-
|
41
|
-
-
|
42
|
-
|
43
|
-
- !binary |-
|
44
|
-
bGliL2dvb2dsZV9hcHBzL2F0b20vcHVibGljX2tleS5yYg==
|
45
|
-
- !binary |-
|
46
|
-
bGliL2dvb2dsZV9hcHBzL2F0b20vdXNlci5yYg==
|
47
|
-
- !binary |-
|
48
|
-
bGliL2dvb2dsZV9hcHBzL3RyYW5zcG9ydC5yYg==
|
49
|
-
- !binary |-
|
50
|
-
bGliL2dvb2dsZV9hcHBzLnJi
|
36
|
+
- lib/google_apps/atom/atom.rb
|
37
|
+
- lib/google_apps/atom/export.rb
|
38
|
+
- lib/google_apps/atom/group.rb
|
39
|
+
- lib/google_apps/atom/group_member.rb
|
40
|
+
- lib/google_apps/atom/message.rb
|
41
|
+
- lib/google_apps/atom/message_attributes.rb
|
42
|
+
- lib/google_apps/atom/nickname.rb
|
43
|
+
- lib/google_apps/atom/node.rb
|
44
|
+
- lib/google_apps/atom/public_key.rb
|
45
|
+
- lib/google_apps/atom/user.rb
|
46
|
+
- lib/google_apps/transport.rb
|
47
|
+
- lib/google_apps.rb
|
51
48
|
homepage: https://github.com/LeakyBucket/google_apps
|
52
49
|
licenses: []
|
53
50
|
post_install_message:
|
@@ -68,8 +65,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
65
|
version: '0'
|
69
66
|
requirements: []
|
70
67
|
rubyforge_project:
|
71
|
-
rubygems_version: 1.8.
|
68
|
+
rubygems_version: 1.8.23
|
72
69
|
signing_key:
|
73
70
|
specification_version: 3
|
74
71
|
summary: Google Apps APIs
|
75
72
|
test_files: []
|
73
|
+
has_rdoc:
|