windows_live_admin 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8c76b690e75a556cdf481186e0eee996e8037a1e
4
+ data.tar.gz: 5e856aac4731760b40e8a63df879cc7e1562e982
5
+ SHA512:
6
+ metadata.gz: 9164b0dc45a5e76108a312a70d66aa26810723b3c7ed6200e8228886d015e1ee7a6e5ea247a963b118712998c6908f019e7cac5d5c8b1d6b7e813851e9a5290c
7
+ data.tar.gz: 0d3e2a82f531f6c2a3fbdd3033834adfec2648f132584a3c8e7b6728e6108265d145c9ecad99a5d9db24628b69f4bb0a5e8546d6bb863cc27e236adc3384596f
@@ -0,0 +1,107 @@
1
+ # This module contains various template methods which return the XML request
2
+ # that needs to be sent to the server to perform corresponding tasks.
3
+ # This module is mixed into the WindowsLiveAdmin class. Hence all the methods
4
+ # defined here can be invoked directly on the objects of WindowsLiveAdmin class
5
+ #
6
+ module Templates
7
+ # Generates the XML required by the get_login_url method.
8
+ # @return [String] Complete XML with username filled in
9
+ def get_login_url_xml
10
+ str = <<-eos
11
+ <?xml version="1.0" encoding="utf-8"?>
12
+ <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
13
+ <soap:Body>
14
+ <GetLoginUrl xmlns="http://domains.live.com/Service/ManageDomain/V1.0">
15
+ <memberNameIn>#{@username}</memberNameIn>
16
+ </GetLoginUrl>
17
+ </soap:Body>
18
+ </soap:Envelope>
19
+ eos
20
+ end
21
+
22
+ # Generates the XML required by the get_login_data_template method.
23
+ # @return [String] XML required to be sent to the server
24
+ def get_login_data_template_xml
25
+ str = <<-eos
26
+ <?xml version="1.0" encoding="utf-8"?>
27
+ <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
28
+ <soap:Body>
29
+ <GetLoginDataTemplate xmlns="http://domains.live.com/Service/ManageDomain/V1.0" />
30
+ </soap:Body>
31
+ </soap:Envelope>
32
+ eos
33
+ end
34
+
35
+ # Generates the XML required by the verify_auth_data method.
36
+ # @return [String] Complete XML with auth_data filled in
37
+ def verify_auth_data_xml
38
+ str = <<-eos
39
+ <?xml version="1.0" encoding="utf-8"?>
40
+ <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
41
+ <soap:Body>
42
+ <VerifyAuthData xmlns="http://domains.live.com/Service/ManageDomain/V1.0">
43
+ <authData>#{@auth_data}</authData>
44
+ </VerifyAuthData>
45
+ </soap:Body>
46
+ </soap:Envelope>
47
+ eos
48
+ end
49
+
50
+ # Generates the XML required by the create_member method.
51
+ # This is a helper function.
52
+ # @param member_name [String] member's complete email id
53
+ # @param password [String] member's desired password
54
+ # @param reset_password [Boolean] a true/false value whether we want member to be forced to change her
55
+ # password on first login.
56
+ # @param first_name [String] first name of member
57
+ # @param last_name [String] last name of member
58
+ # @param lcid [Sting] member's locale ID. Can be blank or nil
59
+ # @return [String] Complete XML with member details filled in
60
+ def create_member_xml(member_name, password, reset_password, first_name, last_name, lcid)
61
+ str = <<-eos
62
+ <?xml version="1.0" encoding="utf-8"?>
63
+ <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
64
+ <soap:Header>
65
+ <ManageDomain2Authorization xmlns="http://domains.live.com/Service/ManageDomain/V1.0">
66
+ <authorizationType>PassportTicket</authorizationType>
67
+ <authorizationData>#{@auth_data}</authorizationData>
68
+ </ManageDomain2Authorization>
69
+ </soap:Header>
70
+ <soap:Body>
71
+ <CreateMember xmlns="http://domains.live.com/Service/ManageDomain/V1.0">
72
+ <memberNameIn>#{member_name}</memberNameIn>
73
+ <password>#{password}</password>
74
+ <resetPassword>#{reset_password}</resetPassword>
75
+ <firstName>#{first_name}</firstName>
76
+ <lastName>#{last_name}</lastName>
77
+ <lcid>#{lcid}</lcid>
78
+ </CreateMember>
79
+ </soap:Body>
80
+ </soap:Envelope>
81
+ eos
82
+ end
83
+
84
+ # Generates the XML required by the delete_member method.
85
+ # This is a helper function.
86
+ # @param member_name [String] email id of the member who is to be deleted
87
+ # @return [String] Complete XML with auth_data and member details filled in
88
+ def delete_member_xml(member_name)
89
+ str = <<-eos
90
+ <?xml version="1.0" encoding="utf-8"?>
91
+ <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
92
+ <soap:Header>
93
+ <ManageDomain2Authorization xmlns="http://domains.live.com/Service/ManageDomain/V1.0">
94
+ <authorizationType>PassportTicket</authorizationType>
95
+ <authorizationData>#{@auth_data}</authorizationData>
96
+ </ManageDomain2Authorization>
97
+ </soap:Header>
98
+ <soap:Body>
99
+ <DeleteMember xmlns="http://domains.live.com/Service/ManageDomain/V1.0">
100
+ <memberNameIn>#{member_name}</memberNameIn>
101
+ </DeleteMember>
102
+ </soap:Body>
103
+ </soap:Envelope>
104
+ eos
105
+ end
106
+
107
+ end # end of module Templates
@@ -0,0 +1,176 @@
1
+ require 'net/http'
2
+ require 'rexml/document'
3
+ require File.dirname(__FILE__) +'/windows_live_admin/templates.rb'
4
+
5
+ # This creates an windows admin live account instance.
6
+ # The object instantiated will have various member/user/email manipulation methods.
7
+ #
8
+ # @author Shivam Patel
9
+ class WindowsLiveAdmin
10
+ include Templates # include the XML templates that various calls require
11
+
12
+ # Constructor of the WindowsLiveAdmin class.
13
+ # Inits class variables @username and @password and makes HTTP calls
14
+ # to get login url and login template. Thereafter obtains auth_data by get_auth_data call
15
+ def initialize(username, password)
16
+ @username = username
17
+ @password = password
18
+
19
+ begin
20
+ login_url = get_login_url
21
+ login_template = get_login_data_template
22
+ @auth_data = get_auth_data(login_url, login_template)
23
+ rescue
24
+ @auth_data = nil # nil auth_data signifies there was an error in the login process
25
+ end
26
+ end
27
+
28
+ # Fetches the login URl where the template needs to be posted to obtain the auth_data (token)
29
+ # @return [String] the login url obtained from the server
30
+ def get_login_url
31
+ http, request = get_request_headers('http://domains.live.com/Service/ManageDomain/V1.0/GetLoginUrl')
32
+ request.body = get_login_url_xml
33
+ #puts @request.body
34
+ response = http.request(request)
35
+ login_url = REXML::XPath.first(REXML::Document.new(response.body), "//GetLoginUrlResult").text
36
+
37
+ end
38
+
39
+ # Fetches the login template from the server and replaces it with admin's username and password
40
+ # @return [String] login template with admin username and password filled in.
41
+ def get_login_data_template
42
+ http, request = get_request_headers("http://domains.live.com/Service/ManageDomain/V1.0/GetLoginDataTemplate")
43
+ request.body = get_login_data_template_xml
44
+ #puts @request.inspect
45
+ response = http.request(request)
46
+ # puts response.body
47
+ template = REXML::XPath.first(REXML::Document.new(response.body), "//GetLoginDataTemplateResult").text
48
+ template.gsub!(/%NAME%/, @username)
49
+ template.gsub!(/%PASSWORD%/, @password)
50
+ end
51
+
52
+ # Fetches auth data by posting the login_template (got from call to get_login_template)
53
+ # to login_url (got from call to get_login_url)
54
+ # @param login_url [String] The login_url obtained from a previous call to get_login_url
55
+ # @param login_template [String] The login_template obtained from a previous call to get_login_template
56
+ # @return [String] The auth_data received from server.
57
+ def get_auth_data(login_url, login_template)
58
+ uri = URI.parse(login_url)
59
+ http = Net::HTTP.new(uri.host, uri.port)
60
+ http.use_ssl = true
61
+ request = Net::HTTP::Post.new(login_url)
62
+
63
+ request.body = login_template
64
+ response = http.request(request)
65
+ @auth_data = REXML::XPath.first(REXML::Document.new(response.body), "//Redirect").text
66
+ @auth_data.gsub!(/&/, "&amp;") # rexml converts &amp; to &. Convert them back to &amp;
67
+ end
68
+
69
+ # Verifies if the auth_data obtained from the previous calls to get_auth_data is valid
70
+ # @return [String] returns true if auth_data is valid, nil otherwise
71
+ def verify_auth_data
72
+ http, request = get_request_headers("http://domains.live.com/Service/ManageDomain/V1.0/VerifyAuthData")
73
+ request.body = verify_auth_data_xml
74
+
75
+ # puts request.body
76
+ response = http.request(request)
77
+ # puts response.body
78
+ begin
79
+ authorized = REXML::XPath.first(REXML::Document.new(response.body), "//VerifyAuthDataResult").text
80
+ end
81
+ return authorized
82
+ end
83
+
84
+ # This method will add a member to the specified domain and provision an email account
85
+ # The member name is a email id of the member.
86
+ # Note that the corresponding domain should be already manually added and configured in the
87
+ # windows admin live center by logging on to the web interface.
88
+ #
89
+ # @param member_name [String] the complete email id of the member. eg. someone@example.com
90
+ # Note that this domain should be already added and activated via the web interface at http://domains.live.com
91
+ # @param password [String] the desired password for the user/member.
92
+ # @param reset_password [Boolean] a true/false value whether we want member to be forced to change her
93
+ # password on first login.
94
+ # @param first_name [String] first name of member
95
+ # @param last_name [String] last name of member
96
+ # @param lcid [Sting] member's locale ID. Can be blank or nil
97
+ # @return [Array] An [status, message] array where status is a true/false boolean indicating if create_member was
98
+ # successful or not. message contains relevant error message if the status is false.
99
+ #
100
+ def create_member(member_name, password, reset_password, first_name, last_name, lcid=nil)
101
+ http, request = get_request_headers("http://domains.live.com/Service/ManageDomain/V1.0/CreateMember")
102
+
103
+ request.body = create_member_xml(member_name, password, reset_password, first_name, last_name, lcid)
104
+ #puts request.body
105
+ response = http.request(request)
106
+ # puts response.body
107
+
108
+ error = is_error?(response.body) # if response is an error xml, error string describes the error
109
+
110
+ if error # Response XML had in error node called ErrorDescription
111
+ return ["false", error]
112
+ else # Absence of ErrorDescription node is taken as success
113
+ return ["true", "Member #{first_name} #{last_name} (#{member_name}) successfully created."]
114
+ end
115
+
116
+ end # end method create_member
117
+
118
+ # This method will delete a member given her member_name (email id)
119
+ # @param member_name [String] email id of the member
120
+ # @return [Array] An [status, message] array. status is the true/false boolean indicating if delete_member was
121
+ # successful or not. message contains relevant error message if the status if false.
122
+ def delete_member(member_name)
123
+ http, request = get_request_headers("http://domains.live.com/Service/ManageDomain/V1.0/DeleteMember")
124
+
125
+ request.body = delete_member_xml(member_name)
126
+ #puts request.body
127
+ response = http.request(request)
128
+ # puts response.body
129
+
130
+ error = is_error?(response.body) # if response is an error, error is a string describing the error
131
+
132
+ if error # Response XML had in error node called ErrorDescription
133
+ return ["false", error]
134
+ else # Absence of ErrorDescription node is taken as success
135
+ return ["true", "Member #{member_name} successfully deleted."]
136
+ end
137
+
138
+ end # end method create_member
139
+
140
+ private
141
+ # Parses the response XML from the API calls and checks for the existence of error/fault nodes
142
+ # The presence of such nodes indicates there was a error. Error strings are extracted and returned
143
+ # in the response.
144
+ # This is an internal helper function
145
+ # @param [String] XML containing the response from the server for a particular request
146
+ # @return [String] returns false if this is not an error response, returns the error string otherwise
147
+ def is_error?(response_xml)
148
+ is_error_response = REXML::XPath.first(REXML::Document.new(response_xml), "//faultstring")
149
+ if response_xml.nil?
150
+ return "Response is nil"
151
+ elsif is_error_response # Response XML has a error node called ErrorDescription
152
+ error = is_error_response.text
153
+ # check if there is an ErrorCode node
154
+ errorcode_node = REXML::XPath.first(REXML::Document.new(response_xml), "//ErrorCode")
155
+ error = (errorcode_node.text + ": " + error) if errorcode_node # if there exists a errorcode node, append error code in error message
156
+ return error
157
+ else
158
+ return false # the response xml is not a error response
159
+ end
160
+ end # end is_error? method
161
+
162
+ # Generates the request headers for the HTTP request made by the API
163
+ # This is an internal helper function
164
+ # @param [String] Action URL of the API endpoint
165
+ # @return [Object, Object] returns the http and request object
166
+ def get_request_headers(action_url)
167
+ uri = URI.parse("https://domains.live.com")
168
+ http = Net::HTTP.new(uri.host, uri.port)
169
+ http.use_ssl = true
170
+ request = Net::HTTP::Post.new("/service/managedomain2.asmx")
171
+ request.add_field('Content-Type', 'text/xml; charset=utf-8')
172
+ request.add_field('SOAPAction', action_url)
173
+ return http, request
174
+ end
175
+
176
+ end# end of class
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: windows_live_admin
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Shivam Patel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Easy ruby wrapper of the Windows Live Admin API to easily domains, users
14
+ and their services (eg. outlook email inboxes).
15
+ email: shivam@shivampatel.net
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/windows_live_admin.rb
21
+ - lib/windows_live_admin/templates.rb
22
+ homepage: http://msdn.microsoft.com/en-us/library/bb259710.aspx
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.0.6
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Windows Live Admin API wrapper
46
+ test_files: []
47
+ has_rdoc: