nextcloud-client 0.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,223 @@
1
+ module NextcloudClient
2
+ module Ocs
3
+ # File sharing base class used for interfering with sharing, included federated
4
+ #
5
+ # @!attribute [rw] meta
6
+ # @return [Hash] Information about API response
7
+ # @!attribute [rw] shareid
8
+ # @return [Integer] Share identifier
9
+ class FileSharingApi < OcsApi
10
+ include Helpers
11
+
12
+ attr_accessor :meta
13
+ attr_reader :share_url
14
+
15
+ # Initializes API with user credentials
16
+ #
17
+ # @param [Hash] args authentication credentials.
18
+ # @option args [String] :url Nextcloud instance URL
19
+ # @option args [String] :username Nextcloud instance user username
20
+ # @option args [String] :password Nextcloud instance user password
21
+ def initialize(args)
22
+ super(args)
23
+
24
+ @url = URI(
25
+ @url.scheme + "://" + @url.host + "/ocs/v2.php/apps/files_sharing/api/v1/"
26
+ )
27
+ end
28
+
29
+ # Get information about specific share
30
+ #
31
+ # @param shareid [Integer]
32
+ # @return [Hash] Information about share with meta
33
+ def find(shareid)
34
+ response = request(:get, "shares/#{shareid}")
35
+ h = doc_to_hash(response, "//data/element").try(:[], "element")
36
+ add_meta(response, h)
37
+ end
38
+
39
+ # Get all shares
40
+ #
41
+ # @return [Array] All shares of authenticated user
42
+ def all
43
+ response = request(:get, "shares")
44
+ h = doc_to_hash(response, "//data").try(:[], "data").try(:[], "element")
45
+ h = [h] if h.class == Hash
46
+ add_meta(response, h)
47
+ end
48
+
49
+ # Get shares for a file or directory
50
+ # optionally get shares including re-shares on a resource
51
+ # or get shares for all the files in a directory
52
+ #
53
+ # @param path [String]
54
+ # @param reshares [Boolean,nil]
55
+ # @param subfiles [Boolean,nil]
56
+ # @return [Array] Shares (may include re-shares for a file or directory) of a resource or all reshares of
57
+ # directory contents
58
+ def specific(path, reshares = nil, subfiles = nil)
59
+ response = request(:get, "shares?path=#{path}&reshares=#{reshares}&subfiles=#{subfiles}")
60
+ h = doc_to_hash(response, "//data").try(:[], "data").try(:[], "element")
61
+ h = [h] if h.class == Hash
62
+ add_meta(response, h)
63
+ end
64
+
65
+ # Share an item
66
+ #
67
+ # @param path [String] Path of a file or directory to share
68
+ # @param shareType [Integer] One of four possible values. 0 means an user, 1 means a group, 3 means a public link
69
+ # 6 stands for federated cloud share
70
+ # @param shareWith [String,nil] User or group identifier, can be omitted if shareType is neither 0, nor 1
71
+ # @param publicUpload [Boolean,nil] If true, permits public uploads in directories shared by link
72
+ # @param password [String,nil] Password-protects a share
73
+ # @param permissions [Integer,nil] Sets permissions on a resource. 1 gives read rights, 2 update, 4 create,
74
+ # 8 delete
75
+ # 16 share, 31 all rights. Value should be one of previously listed.
76
+ # @return [Object] Instance including meta response and share URL if any
77
+ def create(path, shareType, shareWith = nil, publicUpload = nil, password = nil, permissions = nil)
78
+ args = local_variables.reduce({}) { |c, i| c[i] = binding.local_variable_get(i); c }
79
+ response = request(:post, "/shares", args)
80
+ @share_url = response.xpath("//url").text
81
+ (@meta = get_meta(response)) && self
82
+ end
83
+
84
+ # Unshare an item
85
+ #
86
+ # @param shareid [Integer] Share ID
87
+ # @return [Object] Instance with meta response
88
+ def destroy(shareid)
89
+ response = request(:delete, "/shares/#{shareid}")
90
+ (@meta = get_meta(response)) && self
91
+ end
92
+
93
+ # Update permissions for a resource
94
+ #
95
+ # @param shareid [Integer] Share identifier
96
+ # @param permissions [Integer] Must be one of the following: 1: read, 2: update, 4: create, 8: delete, 16: share,
97
+ # 31: all rights.
98
+ # @return [Object] Instance with meta response
99
+ def update_permissions(shareid, permissions)
100
+ update(shareid, "permissions", permissions)
101
+ end
102
+
103
+ # Update a password for a resource
104
+ #
105
+ # @param shareid [Integer] Share identifier
106
+ # @param password [String] Password string
107
+ # @return [Object] Instance with meta response
108
+ def update_password(shareid, password)
109
+ update(shareid, "password", password)
110
+ end
111
+
112
+ # Allow or disallow public uploads in a directory
113
+ #
114
+ # @param shareid [Integer] Share identifier
115
+ # @param publicUpload [Boolean] True to permit public uploads in a directory, false to disallow
116
+ # @return [Object] Instance with meta response
117
+ def update_public_upload(shareid, publicUpload)
118
+ update(shareid, "publicUpload", publicUpload)
119
+ end
120
+
121
+ # Update resource expiration date
122
+ #
123
+ # @param shareid [Integer] Share identifier
124
+ # @param expireDate [String] Expiration date of a resource. Has to be in format of "YYYY-DD-MM"
125
+ # @return [Object] Instance with meta response
126
+ def update_expire_date(shareid, expireDate)
127
+ update(shareid, "expireDate", expireDate)
128
+ end
129
+
130
+ # Wrapper to Federated Cloud Sharing API
131
+ #
132
+ # @!attribute [rw] meta
133
+ # @return [Hash] Information about API response
134
+ class FederatedCloudShares
135
+ include Helpers
136
+
137
+ attr_accessor :meta
138
+
139
+ # Creates Federated Cloud Sharing class instance
140
+ #
141
+ # @param api [Object] Api object
142
+ def initialize(api)
143
+ @api = api
144
+ end
145
+
146
+ # List accepted Federated Cloud Shares
147
+ #
148
+ # @return [Array] List of accepted Federated Cloud Shares
149
+ def accepted
150
+ response = @api.request(:get, "/remote_shares")
151
+ h = doc_to_hash(response, "//data").try(:[], "data").try(:[], "element")
152
+ h = [h] if h.class == Hash
153
+ add_meta(response, h)
154
+ end
155
+
156
+ # List pending requests of Federated Cloud Shares
157
+ #
158
+ # @return [Array] List of pending Federated Cloud Shares
159
+ def pending
160
+ response = @api.request(:get, "/remote_shares/pending")
161
+ h = doc_to_hash(response, "//data").try(:[], "data").try(:[], "element")
162
+ h = [h] if h.class == Hash
163
+ add_meta(response, h)
164
+ end
165
+
166
+ # Accept a request of a Federated Cloud Share
167
+ #
168
+ # @param shareid [Integer] Federated Cloud Share identifier
169
+ # @return [Object] Instance with meta response
170
+ def accept(shareid)
171
+ response = @api.request(:post, "/remote_shares/pending/#{shareid}")
172
+ (@meta = get_meta(response)) && self
173
+ end
174
+
175
+ # Decline a request of a Federated Cloud Share
176
+ #
177
+ # @param shareid [Integer] Federated Cloud Share identifier
178
+ # @return [Object] Instance with meta response
179
+ def decline(shareid)
180
+ response = @api.request(:delete, "/remote_shares/pending/#{shareid}")
181
+ (@meta = get_meta(response)) && self
182
+ end
183
+
184
+ # Delete an accepted Federated Cloud Share
185
+ #
186
+ # @param shareid [Integer] Federated Cloud Share identifier
187
+ # @return [Object] Instance with meta response
188
+ def destroy(shareid)
189
+ response = @api.request(:delete, "/remote_shares/#{shareid}")
190
+ (@meta = get_meta(response)) && self
191
+ end
192
+
193
+ # Information about accepted Federated Cloud Share
194
+ #
195
+ # @param shareid [Integer] Federated Cloud Share identifier
196
+ # @return [Hash] Information about Federated Cloud Share with meta response
197
+ def find(shareid)
198
+ response = @api.request(:get, "/remote_shares/#{shareid}")
199
+ h = doc_to_hash(response, "//data").try(:[], "data")
200
+ add_meta(response, h)
201
+ end
202
+ end
203
+
204
+ # Initiates a Federated Cloud Sharing class
205
+ def federated
206
+ FederatedCloudShares.new(self)
207
+ end
208
+
209
+ private
210
+
211
+ # Update a resource
212
+ #
213
+ # @param shareid [Integer] Share identifier
214
+ # @param key [String] Option to update
215
+ # @param value [String] Setting to update to
216
+ # @return [Object] Instance with meta information
217
+ def update(shareid, key, value)
218
+ response = request(:put, "/shares/#{shareid}", "#{key}": value)
219
+ (@meta = get_meta(response)) && self
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,89 @@
1
+ module NextcloudClient
2
+ module Ocs
3
+ # Class with Nextcloud group operation features
4
+ #
5
+ # @!attribute [rw] meta
6
+ # @return [Hash] Information about API response
7
+ # @!attribute [rw] groupid
8
+ # @return [String,nil] Group identifier
9
+ class Group < OcsApi
10
+ include Helpers
11
+
12
+ attr_accessor :meta, :groupid
13
+
14
+ # Initializes a class
15
+ #
16
+ # @param api [Object] Api instance
17
+ # @param groupid [String,nil] Group identifier
18
+ def initialize(args, groupid = nil)
19
+ @groupid = groupid if groupid
20
+
21
+ if args.class == NextcloudClient::OcsApi
22
+ @api = args
23
+ else
24
+ super(args)
25
+ @api = self
26
+ end
27
+ end
28
+
29
+ # Sets group (useful if class is initiated without OcsApi.group)
30
+ #
31
+ # @param groupid [String] Group identifier
32
+ # @return [Obeject] self
33
+ def set(groupid)
34
+ @groupid = groupid
35
+ self
36
+ end
37
+
38
+ # Search for a group
39
+ #
40
+ # @param str [String] Search query
41
+ # @return [Array] Found groups list
42
+ def search(str)
43
+ response = @api.request(:get, "groups?search=#{str}")
44
+ parse_with_meta(response, "//data/groups/element")
45
+ end
46
+
47
+ # List all groups
48
+ #
49
+ # @return [Array] All groups
50
+ def all
51
+ search("")
52
+ end
53
+
54
+ # Create a group
55
+ #
56
+ # @param groupid [String] Group identifier
57
+ # @return [Object] Instance with meta information
58
+ def create(groupid)
59
+ response = @api.request(:post, "groups", groupid: groupid)
60
+ (@meta = get_meta(response)) && self
61
+ end
62
+
63
+ # Get members of a group
64
+ #
65
+ # @return [Array] List of group members
66
+ def members
67
+ response = @api.request(:get, "groups/#{@groupid}")
68
+ parse_with_meta(response, "//data/users/element")
69
+ end
70
+
71
+ # Get sub-admins of a group
72
+ #
73
+ # @return [Array] List of group sub-admins
74
+ def subadmins
75
+ response = @api.request(:get, "groups/#{@groupid}/subadmins")
76
+ parse_with_meta(response, "//data/element")
77
+ end
78
+
79
+ # Remove a group
80
+ #
81
+ # @param groupid [String] Group identifier
82
+ # @return [Object] Instance with meta information
83
+ def destroy(groupid)
84
+ response = @api.request(:delete, "groups/#{groupid}")
85
+ (@meta = get_meta(response)) && self
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,146 @@
1
+ module NextcloudClient
2
+ module Ocs
3
+ # Group Folder class used for interfering with group folders
4
+ #
5
+ # @!attribute [rw] meta
6
+ # @return [Hash] Information about API response
7
+ class GroupFolder < OcsApi
8
+ include Helpers
9
+
10
+ attr_accessor :meta
11
+
12
+ # Application initializer
13
+ #
14
+ # @param [Hash] args authentication credentials.
15
+ # @option args [String] :url Nextcloud instance URL
16
+ # @option args [String] :username Nextcloud instance user username
17
+ # @option args [String] :password Nextcloud instance user password
18
+ def initialize(args)
19
+ super(args)
20
+
21
+ @url = URI(
22
+ @url.scheme + "://" + @url.host + "/apps/groupfolders/"
23
+ )
24
+ end
25
+
26
+ # List all folders
27
+ #
28
+ # @return [Array] All group folders
29
+ def folders
30
+ response = request(:get, "folders")
31
+ h = doc_to_hash(response, "//data").try(:[], "data").try(:[], "element")
32
+ h = [h] if h.class == Hash
33
+ add_meta(response, h)
34
+ end
35
+
36
+ # Return ID of folder given by name
37
+ #
38
+ # @param name [String] Folder name
39
+ # @return [Integer] Folder ID
40
+ def get_folder_id(name)
41
+ response = request(:get, "folders")
42
+ h = doc_to_hash(response, "//data").try(:[], "data").try(:[], "element")
43
+ group = h.select { |folder| folder["mount_point"] == name }&.first
44
+ unless group.nil?
45
+ return group["id"]
46
+ end
47
+ end
48
+
49
+ # Get information about a group folder
50
+ #
51
+ # @param folderid [Integer]
52
+ # @return [Hash] Information about a group folder
53
+ def find(folderid)
54
+ response = request(:get, "folders/#{folderid}")
55
+ h = doc_to_hash(response, "//data").try(:[], "data")
56
+ add_meta(response, h)
57
+ end
58
+
59
+ # Create a group folder
60
+ #
61
+ # @param mountpoint [String] Mountpoint
62
+ # @return [Hash] Hash with created group folder
63
+ def create(mountpoint)
64
+ args = local_variables.reduce({}) { |c, i| c[i] = binding.local_variable_get(i); c }
65
+ response = request(:post, "folders", args)
66
+ h = doc_to_hash(response, "//data").try(:[], "data")
67
+ add_meta(response, h)
68
+ end
69
+
70
+ # Destroy a group folder
71
+ #
72
+ # @param mountpoint [String] Mountpoint
73
+ # @return [Bool] True on success
74
+ def destroy(folderid)
75
+ response = request(:delete, "folders/#{folderid}")
76
+ h = doc_to_hash(response, "//data").try(:[], "data")
77
+ return h == "1"
78
+ end
79
+
80
+ # Give a group access to a folder
81
+ #
82
+ # @param folderid [Integer] FolderId to modify
83
+ # @param group [String] Group which should get access to the folder
84
+ # @return [Bool] True on success
85
+ def give_access(folderid, group)
86
+ args = local_variables.reduce({}) { |c, i| c[i] = binding.local_variable_get(i); c }
87
+ response = request(:post, "folders/#{folderid}/groups", args)
88
+ h = doc_to_hash(response, "//data").try(:[], "data")
89
+ return h == "1"
90
+ end
91
+
92
+ # Remove access from a group to a folder
93
+ # @param folderid [Integer] FolderId to modify
94
+ # @param group [String] Group which should be removed to get access to the folder
95
+ # @return [Bool] True on success
96
+ def remove_access(folderid, group)
97
+ response = request(:delete, "folders/#{folderid}/groups/#{group}")
98
+ h = doc_to_hash(response, "//data").try(:[], "data")
99
+ return h == "1"
100
+ end
101
+
102
+ # Set the permissions a group has in a folder
103
+ # PERMISSION_CREATE = 4;
104
+ # PERMISSION_READ = 1;
105
+ # PERMISSION_UPDATE = 2;
106
+ # PERMISSION_DELETE = 8;
107
+ # PERMISSION_SHARE = 16;
108
+ # PERMISSION_ALL = 31;
109
+ #
110
+ # @param folderid [Integer] FolderId to modify
111
+ # @param group [String] Group for which the permissions should be changed
112
+ # @param permissions [String] The new permissions for the group as bitmask of permissions constants
113
+ # @return [Bool] True on success
114
+ def set_permissions(folderid, group, permissions)
115
+ args = local_variables.reduce({}) { |c, i| c[i] = binding.local_variable_get(i); c }
116
+ response = request(:post, "folders/#{folderid}/groups/#{group}", args)
117
+ h = doc_to_hash(response, "//data").try(:[], "data")
118
+ return h == "1"
119
+ end
120
+
121
+ # Set the quota for a folder
122
+ #
123
+ # @param folderid [Integer] FolderId to modify
124
+ # @param quota [Integer] The new quota for the folder in bytes, use -3 for unlimited
125
+ # @return [Bool] True on success
126
+ def set_quota(folderid, quota)
127
+ args = local_variables.reduce({}) { |c, i| c[i] = binding.local_variable_get(i); c }
128
+ response = request(:post, "folders/#{folderid}/quota", args)
129
+ h = doc_to_hash(response, "//data").try(:[], "data")
130
+ return h == "1"
131
+ end
132
+
133
+ # Change the name of a folder
134
+ #
135
+ # @param folderid [Integer] FolderId to modify
136
+ # @param mountpoint [String] The new folder name
137
+ # @return [Bool] True on success
138
+ def rename_folder(folderid, mountpoint)
139
+ args = local_variables.reduce({}) { |c, i| c[i] = binding.local_variable_get(i); c }
140
+ response = request(:post, "folders/#{folderid}/mountpoint", args)
141
+ h = doc_to_hash(response, "//data").try(:[], "data")
142
+ return h == "1"
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,225 @@
1
+ module NextcloudClient
2
+ module Ocs
3
+ # Class includes User provisioning fetures, including User group operations
4
+ #
5
+ # @!attribute [rw] meta
6
+ # @return [Hash] Information about API response
7
+ # @!attribute [rw] userid
8
+ # @return [String,nil] User identifier
9
+ class User < OcsApi
10
+ include Helpers
11
+
12
+ attr_accessor :meta, :userid
13
+
14
+ # Class initializer
15
+ #
16
+ # @param api [Object] Api instance
17
+ # @param userid [String,nil] User identifier
18
+ def initialize(args, userid = nil)
19
+ @userid = userid if userid
20
+
21
+ if args.class == NextcloudClient::OcsApi
22
+ @api = args
23
+ else
24
+ super(args)
25
+ @api = self
26
+ end
27
+ end
28
+
29
+ # Sets user (useful if class is initiated without OcsApi.user)
30
+ #
31
+ # @param userid [String] User identifier
32
+ # @return [Obeject] self
33
+ def set(userid)
34
+ @userid = userid
35
+ self
36
+ end
37
+
38
+ # Retrieve information about an user
39
+ #
40
+ # @param userid [String]
41
+ # @return [Object] User instance
42
+ def find(userid)
43
+ response = @api.request(:get, "users/#{userid}")
44
+
45
+ enabled = response.xpath("//data/enabled").text
46
+ id = response.xpath("//data/id").text
47
+ quota = response.xpath("//data/quota/*").each_with_object({}) do |node, quota|
48
+ quota[node.name] = node.text
49
+ end
50
+ email = response.xpath("//data/email").text
51
+ displayname = response.xpath("//data/displayname").text
52
+ phone = response.xpath("//data/phone").text
53
+ address = response.xpath("//data/address").text
54
+ website = response.xpath("//data/website").text
55
+ twitter = response.xpath("//data/twitter").text
56
+ groups = []
57
+ response.xpath("//data/groups/element").each do |prop|
58
+ groups << prop.text
59
+ end
60
+
61
+ language = response.xpath("//data/language").text
62
+
63
+ user = NextcloudClient::Models::User.new(enabled: enabled, id: id, quota: quota, email: email,
64
+ displayname: displayname, phone: phone, address: address, website: website,
65
+ twitter: twitter, groups: groups, language: language)
66
+ (user.meta = get_meta(response)) && user
67
+ end
68
+
69
+ # Retrieve all users
70
+ #
71
+ # @return [Array] List of all users
72
+ def all
73
+ response = @api.request(:get, "users")
74
+
75
+ users = [].tap do |users|
76
+ response.xpath("//element").each do |prop|
77
+ id = prop.text
78
+ users << NextcloudClient::Models::User.new(id: id)
79
+ end
80
+ end
81
+
82
+ meta = get_meta(response)
83
+
84
+ users.send(:define_singleton_method, :meta) { meta } && users
85
+ end
86
+
87
+ # Add a new user
88
+ #
89
+ # @param userid [String] User identifier
90
+ # @param password [String] User password
91
+ # @return [Object] Instance with meta response
92
+ def create(userid, password)
93
+ response = @api.request(:post, "users", userid: userid, password: password)
94
+ (@meta = get_meta(response)) && self
95
+ end
96
+
97
+ # Update a parameter of an user
98
+ #
99
+ # @param userid [String] User identifier
100
+ # @param key [String] Parameter to update. Can be quota, displayname, phone, address, website, twitter or password
101
+ # @param value [String] Value to update to
102
+ # @return [Object] Instance with meta information
103
+ def update(userid, key, value)
104
+ response = @api.request(:put, "users/#{userid}", key: key, value: value)
105
+ (@meta = get_meta(response)) && self
106
+ end
107
+
108
+ # Disable an user
109
+ #
110
+ # @param userid [String] User identifier
111
+ # @return [Object] Instance with meta information
112
+ def disable(userid)
113
+ response = @api.request(:put, "users/#{userid}/disable")
114
+ (@meta = get_meta(response)) && self
115
+ end
116
+
117
+ # Enable an user
118
+ #
119
+ # @param userid [String] User identifier
120
+ # @return [Object] Instance with meta information
121
+ def enable(userid)
122
+ response = @api.request(:put, "users/#{userid}/enable")
123
+ (@meta = get_meta(response)) && self
124
+ end
125
+
126
+ # Remove an user account
127
+ #
128
+ # @param userid [String] User identifier
129
+ # @return [Object] Instance with meta information
130
+ def destroy(userid)
131
+ response = @api.request(:delete, "users/#{userid}")
132
+ (@meta = get_meta(response)) && self
133
+ end
134
+
135
+ # Class covering User group operations
136
+ #
137
+ # @!attribute [rw] meta
138
+ # @return [Hash] Information about API response
139
+ # @!attribute [rw] groupid
140
+ # @return [String,nil] Group identifier
141
+ class Group < User
142
+ include Helpers
143
+
144
+ attr_accessor :userid, :groupid, :meta
145
+
146
+ # Initializes an User Group instance
147
+ #
148
+ # @param api [Object] Api instance
149
+ # @param userid [String] User identifier
150
+ # @param groupid [String,nil] Group identifier
151
+ def initialize(api, userid, groupid = nil)
152
+ @api = api
153
+ @userid = userid
154
+ @groupid = groupid if groupid
155
+ end
156
+
157
+ # Add an user to a group
158
+ #
159
+ # @param groupid [String] Group to add user to
160
+ # @return [Object] Instance with meta information
161
+ def create(groupid)
162
+ response = @api.request(:post, "users/#{@userid}/groups", groupid: groupid)
163
+ (@meta = get_meta(response)) && self
164
+ end
165
+
166
+ # Remove user from a group
167
+ #
168
+ # @param groupid [String] Group to remove user from
169
+ # @return [Object] Instance with meta information
170
+ def destroy(groupid)
171
+ response = @api.request(:delete, "users/#{@userid}/groups", groupid: groupid)
172
+ (@meta = get_meta(response)) && self
173
+ end
174
+
175
+ # Make an user subadmin of a group
176
+ #
177
+ # @return [Object] Instance with meta information
178
+ def promote
179
+ response = @api.request(:post, "users/#{@userid}/subadmins", groupid: @groupid)
180
+ (@meta = get_meta(response)) && self
181
+ end
182
+
183
+ # Remove an user from group subadmins
184
+ #
185
+ # @return [Object] Instance with meta information
186
+ def demote
187
+ response = @api.request(:delete, "users/#{@userid}/subadmins", groupid: @groupid)
188
+ (@meta = get_meta(response)) && self
189
+ end
190
+ end
191
+
192
+ # Initialize a group class
193
+ #
194
+ # @param groupid [String,nil] Group identifier
195
+ def group(groupid = nil)
196
+ Group.new(@api, @userid, groupid)
197
+ end
198
+
199
+ # List groups that user belongs to
200
+ #
201
+ # @return [Array] User groups
202
+ def groups
203
+ response = @api.request(:get, "users/#{@userid}/groups")
204
+ parse_with_meta(response, "//data/groups/element")
205
+ end
206
+
207
+ # List groups that user sub-admins
208
+ #
209
+ # @return [Array] User sub-admin groups
210
+ def subadmin_groups
211
+ response = @api.request(:get, "users/#{@userid}/subadmins")
212
+ parse_with_meta(response, "//data/element")
213
+ end
214
+
215
+ # Resend welcome e-mail letter to a user
216
+ #
217
+ # @param userid [String]
218
+ # @return [Object] Instance with meta information
219
+ def resend_welcome(userid)
220
+ response = @api.request(:post, "users/#{userid}/welcome")
221
+ (@meta = get_meta(response)) && self
222
+ end
223
+ end
224
+ end
225
+ end