respoke 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 196657fbadbddac896125b5633e9a41ddc6ba4b5
4
+ data.tar.gz: ee0fd8872889c7868049130640092baa13f34294
5
+ SHA512:
6
+ metadata.gz: 15c8773001b7e574b8841fbb58190067f2d97f46a7b55be273ef008710d8b4210c4c2b4e323b100c4948952ec70d75dfa43cde995026e8fea51ee95cb8432926
7
+ data.tar.gz: 8380b37f0d43ffd581d77389d8f5cbb6fbe8eb89c23283e85810102013ab09197e5eb2fbc41969b2ed77e209c0b292786d0f323a607786b743c4f0feaba0c307
@@ -0,0 +1,17 @@
1
+ # EditorConfig is awesome: http://EditorConfig.org
2
+
3
+ # top-most EditorConfig file
4
+ root = true
5
+
6
+ # Unix-style newlines with a newline ending every file
7
+ [*]
8
+ end_of_line = lf
9
+ insert_final_newline = true
10
+ trim_trailing_whitespace = true
11
+ max_line_length = 80
12
+
13
+ # Set default charset
14
+ [*.{rb,gemspec}, Gemfile]
15
+ charset = utf-8
16
+ indent_style = space
17
+ indent_size = 2
@@ -0,0 +1,7 @@
1
+ Gemfile.lock
2
+ .bundle
3
+ coverage
4
+ doc
5
+ .yardoc
6
+ test/test_config*.yml
7
+ !test/test_config.example.yml
@@ -0,0 +1,6 @@
1
+
2
+ SimpleCov.start do
3
+ add_filter '/test/'
4
+ add_filter '.bundle'
5
+ add_filter 'coverage'
6
+ end
@@ -0,0 +1,17 @@
1
+ script: bundle exec rake test
2
+ rvm:
3
+ - 2.1
4
+ notifications:
5
+ email:
6
+ recipients:
7
+ - monitoring@respoke.io
8
+ email:
9
+ on_success: change
10
+ on_failure: always
11
+ cache: bundler
12
+ os:
13
+ - linux
14
+ - osx
15
+ before_install:
16
+ - openssl aes-256-cbc -K $encrypted_4e4ac21e4bd9_key -iv $encrypted_4e4ac21e4bd9_iv
17
+ -in test/test_config.yml.enc -out test/test_config.yml -d
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in respoke-admin.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Digium, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,93 @@
1
+ [![Gem Version](https://badge.fury.io/rb/respoke.svg)](http://badge.fury.io/rb/respoke)
2
+ [![Build Status](https://travis-ci.org/pho3nixf1re/ruby-respoke.svg?branch=master)](https://travis-ci.org/pho3nixf1re/ruby-respoke)
3
+ [![Dependency Status](https://gemnasium.com/pho3nixf1re/ruby-respoke.svg)](https://gemnasium.com/pho3nixf1re/ruby-respoke)
4
+
5
+ # Respoke
6
+
7
+ ruby-respoke is a wrapper for the Respoke API. For more information on the
8
+ Respoke service and API see [docs.respoke.io](http://docs.respoke.io).
9
+
10
+ ## Installation
11
+
12
+ Using bundler, add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'respoke'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ For details on the ruby-respoke API please refer to the [full documentation].
23
+
24
+ [full documentation]: http://www.rubydoc.info/github/pho3nixf1re/ruby-respoke/master
25
+
26
+ ## Running the tests
27
+
28
+ The test suite uses VCR to record API requests and responses once. After the
29
+ first run it caches these and works offline. These cached files are checked into
30
+ Git and can be found in the `test/vcr_cassettes` directory. To run the tests
31
+ against the live API just delete the `test/vcr_cassettes` directory. Please note
32
+ that this will change the expected input of the encrypted
33
+ `test/test_config.yml.enc` file used by Travis and that will need to be updated
34
+ if you intend to commit the new VCR cache. Otherwise just omit the new cache
35
+ files when making your tests.
36
+
37
+ ### Units
38
+
39
+ Note that the unit tests do not use the VCR cache in favor of stubbing.
40
+
41
+ ```sh
42
+ rake test:unit
43
+ ```
44
+
45
+ ### Specs
46
+
47
+ Before you can run the specs yourself you will need to remove the VCR cache
48
+ files and provide your Respoke API credentials. Copy the `test/test_config.yml`
49
+ file and replace the example values with the ones in the Respoke
50
+ [developer portal].
51
+
52
+ [developer portal]: https://portal.respoke.io
53
+
54
+ ```
55
+ cp test/test_config.example.yml test/test_config.yml
56
+ ```
57
+
58
+ Fill in the test_config.yml values then run the spec rake task.
59
+
60
+ ```sh
61
+ rake test:spec
62
+ ```
63
+
64
+ ## Building the documentation
65
+
66
+ The documentation is marked up using Yard + Markdown. The easiest way to build
67
+ the included docs is to use the rake task.
68
+
69
+ ```sh
70
+ rake yard
71
+ ```
72
+
73
+ ## Contributing
74
+
75
+ If you wish to submit an issue use the [issue tracker].
76
+
77
+ [issue tracker]: https://github.com/pho3nixf1re/ruby-respoke/issues
78
+
79
+ 1. Fork it ( https://github.com/[my-github-username]/ruby-respoke/fork )
80
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
81
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
82
+ 4. Push to the branch (`git push origin my-new-feature`)
83
+ 5. Create a new Pull Request
84
+
85
+ ## License
86
+
87
+ Copyright 2014, Digium, Inc.
88
+ All rights reserved.
89
+
90
+ This source code is licensed under The MIT License found in the
91
+ [LICENSE](LICENSE) file in the root directory of this source tree.
92
+
93
+ For all details and documentation: https://www.respoke.io
@@ -0,0 +1,32 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ require 'yard'
4
+ require 'bundler/version'
5
+
6
+ namespace :test do
7
+ Rake::TestTask.new(:spec) do |t|
8
+ t.libs << "test"
9
+ t.test_files = FileList['test/spec/*_spec.rb']
10
+ end
11
+
12
+ Rake::TestTask.new(:unit) do |t|
13
+ t.libs << "test"
14
+ t.test_files = FileList['test/unit/**/*_test.rb']
15
+ end
16
+ end
17
+
18
+ task :test => ['test:spec', 'test:unit']
19
+
20
+ task :default => :test
21
+
22
+ YARD::Rake::YardocTask.new do |t|
23
+ t.options = ['-m', 'markdown']
24
+ end
25
+
26
+ task :build do
27
+ system "gem build respoke.gemspec"
28
+ end
29
+
30
+ task :release => :build do
31
+ system "gem push respoke-#{Respoke::VERSION}.gem"
32
+ end
@@ -0,0 +1,7 @@
1
+ require "respoke/version"
2
+ require "respoke/client"
3
+ require "respoke/role"
4
+
5
+ # The respoke gem top level namespace.
6
+ module Respoke
7
+ end
@@ -0,0 +1,265 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ require 'respoke/errors'
5
+ require 'respoke/response'
6
+
7
+ # Contains methods to make API calls.
8
+ #
9
+ # @example One-step endpoint authentication
10
+ #
11
+ # require 'respoke'
12
+ #
13
+ # client = Respoke::Client.new(app_secret: '77269d84-d7f3-49da-8eab-bd6686160035')
14
+ # client.app_token(
15
+ # appId: '0cdf7bc1-45d1-420a-963e-c797a6f7ba61',
16
+ # roleId: '47ea573f-5a78-42f4-927c-fe658bc00f91',
17
+ # endpointId: 'foo-bar-user'
18
+ # )
19
+ # #=> '3c022dbd-0a82-4382-bd0d-5af6e11b8d67'
20
+ #
21
+ # @example Manual endpoint authentication
22
+ #
23
+ # require 'respoke'
24
+ #
25
+ # client = Respoke::Client.new(app_secret: '77269d84-d7f3-49da-8eab-bd6686160035')
26
+ #
27
+ # session_id_response = client.request_session_token_id(
28
+ # appId: '0cdf7bc1-45d1-420a-963e-c797a6f7ba61',
29
+ # roleId: '47ea573f-5a78-42f4-927c-fe658bc00f91',
30
+ # endpointId: 'foo-bar-user'
31
+ # )
32
+ # session = client.request_session_token(
33
+ # appId: session_id_response.appId,
34
+ # tokenId: session_id_response.tokenId
35
+ # )
36
+ #
37
+ # session.token #=> '3c022dbd-0a82-4382-bd0d-5af6e11b8d67'
38
+ #
39
+ # # OR you can just use Client#app_token since Client#request_session_token
40
+ # # sets `@app_token`.
41
+ # client.app_token #=> '3c022dbd-0a82-4382-bd0d-5af6e11b8d67'
42
+ #
43
+ # @attr_reader app_token
44
+ #
45
+ class Respoke::Client
46
+
47
+ # Default base_url
48
+ DEFAULT_BASE_URL = 'https://api.respoke.io/v1'
49
+
50
+ # Base URL used for API requests
51
+ attr_reader :base_url
52
+
53
+ # Sets the App-Secret token
54
+ attr_reader :app_secret
55
+
56
+ # Creates a new Client instance.
57
+ #
58
+ # @param app_secret [String] The application App-Secret token.
59
+ # (Defaults to nil)
60
+ # @param base_url [String] Overrides the {DEFAULT_BASE_URL} constant.
61
+ # (Defaults to {DEFAULT_BASE_URL})
62
+ #
63
+ # @return [Respoke::Client]
64
+ def initialize(app_secret: nil, base_url: DEFAULT_BASE_URL)
65
+ @base_url = base_url
66
+ @app_secret = app_secret
67
+ end
68
+
69
+ # Either returns the current `@app_token` or sets it based on the parameter
70
+ # Hash `token_request_params`.
71
+ #
72
+ # @param token_request_params [Hash] parameters for
73
+ # {#request_session_token_id}.
74
+ # @option token_request_params [String] appId The application ID.
75
+ # @option token_request_params [String] roleId Role ID to use for permissions
76
+ # on given endpoint ID.
77
+ # @option token_request_params [String] endpointId The endpoint ID to
78
+ # authenticate.
79
+ # @option token_request_params [Number] ttl (86400) Length of time token is
80
+ # valid.
81
+ #
82
+ # @return [String] App-Token value.
83
+ def app_token(token_request_params={})
84
+ @app_token ||= (
85
+ if token_request_params
86
+ response = request_session_token_id(token_request_params)
87
+ request_session_token(
88
+ appId: response.appId,
89
+ tokenId: response.tokenId
90
+ ).token
91
+ end
92
+ )
93
+ end
94
+
95
+ # Request a token ID for use in requesting the App-Token value.
96
+ #
97
+ # @todo test return value
98
+ #
99
+ # @param appId [String] The application ID that matches the App-Secret.
100
+ # @param roleId [String] The role ID to use for the given endpoint.
101
+ # @param endpointId [String] The endpoint ID that is being authenticated.
102
+ # @param ttl [Number] The amount of time in seconds the App-Token is
103
+ # valid. (Defaults to 86400)
104
+ #
105
+ # @return [Respoke::Response::SessionTokenId] The API response object.
106
+ def request_session_token_id(appId:, roleId:, endpointId:, ttl: 86400)
107
+ response = connection.post 'tokens' do |request|
108
+ request.body = {
109
+ appId: appId,
110
+ endpointId: endpointId,
111
+ roleId: roleId,
112
+ ttl: 86400
113
+ }
114
+ end
115
+
116
+ if response.status != 200
117
+ raise Respoke::Errors::UnexpectedServerError, <<-ERR
118
+ request failed with status #{response.status}:
119
+ #{response.body}
120
+ ERR
121
+ else
122
+ Respoke::Response::SessionTokenId.new(response.body)
123
+ end
124
+ end
125
+
126
+ # Request the session token using the tokenId retrived with
127
+ # {#request_session_token_id}. This method sets the `app_token` attribute.
128
+ #
129
+ # @todo test setting of `@app_token`.
130
+ #
131
+ # @param appId [String] The application ID used in the token request.
132
+ # @param tokenId [String] The token ID requested from
133
+ # {#request_session_token_id}.
134
+ #
135
+ # @return [Respoke::Response::SessionToken] The API response object.
136
+ def request_session_token(appId:, tokenId:)
137
+ response = connection.post 'session-tokens' do |request|
138
+ request.body = {
139
+ appId: appId,
140
+ tokenId: tokenId
141
+ }
142
+ end
143
+ @app_token = response.body.fetch('token', nil)
144
+
145
+ if response.status != 200
146
+ raise Respoke::Errors::UnexpectedServerError, <<-ERR
147
+ request failed with status #{response.status}:
148
+ #{response.body}
149
+ ERR
150
+ else
151
+ Respoke::Response::SessionToken.new(response.body)
152
+ end
153
+ end
154
+
155
+ # Get the roles
156
+ #
157
+ # @return [Array<Respoke::Role>] An array of role objects
158
+ # @raise [Respoke::Errors::UnexpectedServerError] if errors occur
159
+ def roles()
160
+ response = connection.get 'roles'
161
+
162
+ if response.status != 200
163
+ raise Respoke::Errors::UnexpectedServerError, <<-ERR
164
+ request failed with status #{response.status}:
165
+ #{response.body}
166
+ ERR
167
+ else
168
+ response.body.map { |r| Respoke::Role.new(connection, r.each_with_object({}) { |(k,v), h| h[k.to_sym] = v} ) }
169
+ end
170
+ end
171
+
172
+ # Create a role
173
+ #
174
+ # @param name [String] The name of the role
175
+ # @param rules [Hash] The permissions for the role
176
+ #
177
+ # @return [Respoke::Role] The role that was created
178
+ # @raise [Respoke::Errors::UnexpectedServerError] if errors occur
179
+ def create_role(name:, rules: {})
180
+ response = connection.post 'roles' do |request|
181
+ request.body = rules.merge( name: name )
182
+ end
183
+
184
+ if response.status != 200
185
+ raise Respoke::Errors::UnexpectedServerError, <<-ERR
186
+ request failed with status #{response.status}:
187
+ #{response.body}
188
+ ERR
189
+ else
190
+ Respoke::Role.new(self, response.body.each_with_object({}) { |(k,v), h| h[k.to_sym] = v} )
191
+ end
192
+ end
193
+
194
+
195
+ # Find a role
196
+ #
197
+ # @param id [String] The id of the role to retrieve
198
+ #
199
+ # @return [Respoke::Role] The role that was retrieved, nil if none found
200
+ # @raise [Respoke::Errors::UnexpectedServerError] if errors occur
201
+ def find_role(id:)
202
+ response = connection.get "roles/#{id}"
203
+
204
+ if response.status == 404
205
+ nil
206
+ elsif !response.success?
207
+ raise Respoke::Errors::UnexpectedServerError, <<-ERR
208
+ request failed with status #{response.status}:
209
+ #{response.body}
210
+ ERR
211
+ else
212
+ Respoke::Role.new(self, response.body.each_with_object({}) { |(k,v), h| h[k.to_sym] = v} )
213
+ end
214
+ end
215
+
216
+ # Update a role
217
+ #
218
+ # @param id [String] The id of the role to update
219
+ # @param rules [Hash] The new permissions for the role
220
+ #
221
+ # @return [Boolean] true if successfully updated
222
+ # @raise [Respoke::Errors::UnexpectedServerError] if errors occur
223
+ def update_role(id:, rules:)
224
+ response = connection.put "roles/#{id}" do |request|
225
+ request.body = rules
226
+ end
227
+
228
+ if !response.success?
229
+ raise Respoke::Errors::UnexpectedServerError, <<-ERR
230
+ request failed with status #{response.status}:
231
+ #{response.body}
232
+ ERR
233
+ else
234
+ true
235
+ end
236
+ end
237
+
238
+ # Delete a role
239
+ #
240
+ # @param id [String] The id of the role to retrieve
241
+ #
242
+ # @return [Boolean] true if the role was deleted, false otherwise
243
+ def delete_role(id:)
244
+ response = connection.delete "roles/#{id}"
245
+ response.success?
246
+ end
247
+
248
+ private
249
+
250
+ # Creates a Faraday connection object to make requests with.
251
+ #
252
+ # @return [Faraday::Connection] The connection object for making API requests.
253
+ def connection
254
+ @connection ||= Faraday.new(
255
+ url: @base_url,
256
+ headers: { :'App-Secret' => @app_secret }
257
+ ) do |faraday|
258
+ faraday.request :json
259
+
260
+ faraday.response :json, :content_type => 'application/json'
261
+
262
+ faraday.adapter Faraday.default_adapter
263
+ end
264
+ end
265
+ end