mauth-client 4.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,41 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ mauth-client (3.1.4)
5
+ coderay (~> 1.0)
6
+ dice_bag (>= 0.9, < 2.0)
7
+ faraday (~> 0.7)
8
+ faraday_middleware (~> 0.9)
9
+ rack
10
+ term-ansicolor (~> 1.0)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ coderay (1.1.1)
16
+ dice_bag (1.1.1)
17
+ diff-lcs (~> 1.0)
18
+ rake
19
+ thor (~> 0.0)
20
+ diff-lcs (1.2.5)
21
+ faraday (0.9.2)
22
+ multipart-post (>= 1.2, < 3)
23
+ faraday_middleware (0.10.0)
24
+ faraday (>= 0.7.4, < 0.10)
25
+ multipart-post (2.0.0)
26
+ rack (2.0.1)
27
+ rake (11.2.2)
28
+ term-ansicolor (1.3.2)
29
+ tins (~> 1.0)
30
+ thor (0.19.1)
31
+ tins (1.11.0)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ faraday (~> 0.9.0)
38
+ mauth-client!
39
+
40
+ BUNDLED WITH
41
+ 1.12.5
@@ -0,0 +1,33 @@
1
+ # Examples
2
+
3
+ ## Configuration
4
+
5
+ After obtaining valid credentials you need to edit the `config.yml` file and set the `app_uuid` accordingly.
6
+ You also need to provide a mauth key and put it in the `mauth_key` file.
7
+ See [the mauth config file doc](../doc/mauth.yml.md) for more information.
8
+
9
+ This folder contains its own Gemfile and Gemfile.lock files to manage dependencies so you need to run
10
+ ```
11
+ bundle install
12
+ ```
13
+ before trying any of the scripts.
14
+
15
+
16
+ ## Fetching a given user's info
17
+
18
+ Simply run the provided shell script by passing an user's UUID, for instance:
19
+ ```
20
+ ./get_user_info.rb 4735d013-8d78-4980-8846-fbecf0db0b8e
21
+ ```
22
+
23
+ This should print the user's info, something along the lines of:
24
+ ```
25
+ {
26
+ "user": {
27
+ "login": "name",
28
+ "email": "the.email.address@example.com",
29
+ "uuid": "4735d013-8d78-4980-8846-fbecf0db0b8e",
30
+ ...
31
+ }
32
+ }
33
+ ```
@@ -0,0 +1,8 @@
1
+ imedidata:
2
+ host: https://innovate.imedidata.com
3
+
4
+ mauth:
5
+ mauth_baseurl: https://mauth-innovate.imedidata.com
6
+ mauth_api_version: v1
7
+ app_uuid: <APP UUID>
8
+ private_key_file: ./mauth_key
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ abort "USAGE: ./#{__FILE__} <USER UUID>" unless ARGV.size == 1
4
+
5
+ require 'bundler/setup'
6
+ Bundler.require(:default)
7
+
8
+ def config
9
+ @conf ||= YAML.load(File.open("./config.yml"))
10
+ end
11
+
12
+ # get user information
13
+ def get_user_info_mauth(user_uuid)
14
+ get_data_from_imedidata "users/#{user_uuid}.json"
15
+ end
16
+
17
+ # fetch data from iMedidata
18
+ def get_data_from_imedidata(resource_name)
19
+ puts "fetching #{resource_name}..."
20
+ begin
21
+ connection = Faraday::Connection.new(url: config["imedidata"]["host"]) do |builder|
22
+ builder.use MAuth::Faraday::RequestSigner, config["mauth"]
23
+ builder.adapter Faraday.default_adapter
24
+ end
25
+
26
+ # get the data
27
+ response = connection.get "/api/v2/#{resource_name}"
28
+ puts "HTTP #{response.status}"
29
+
30
+ # return the user info
31
+ if response.status == 200
32
+ result = JSON.parse(response.body)
33
+ puts JSON.pretty_generate(result)
34
+ result
35
+ else
36
+ puts response.body
37
+ nil
38
+ end
39
+ rescue JSON::ParserError => e
40
+ puts "Error parsing data from imedidata: #{e.inspect}"
41
+ puts e.backtrace.join("\n")
42
+ end
43
+ end
44
+
45
+ get_user_info_mauth(ARGV[0])
46
+
47
+
48
+ ### OTHER EXAMPLES
49
+
50
+ #### get study groups for an user
51
+ def get_study_groups_mauth(user_uuid)
52
+ get_data_from_imedidata "users/#{user_uuid}/study_groups.json"
53
+ end
54
+
55
+ #### get roles for a user in an application study
56
+ def get_user_study_roles_mauth(user_uuid, study_uuid)
57
+ get_data_from_imedidata "users/#{user_uuid}/studies/#{study_uuid}/apps/#{config["mauth"]["app_uuid"]}/roles.json"
58
+ end
File without changes
data/exe/mauth-client ADDED
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
4
+
5
+ require 'rubygems'
6
+ require 'faraday'
7
+ require 'faraday_middleware'
8
+ require 'logger'
9
+ require 'mauth/client'
10
+ require 'mauth/faraday'
11
+ require 'yaml'
12
+ require 'term/ansicolor'
13
+
14
+ # OPTION PARSER
15
+
16
+ require 'optparse'
17
+
18
+ # $options default values
19
+ $options = {
20
+ :authenticate_response => true,
21
+ :verbose => true,
22
+ :color => nil,
23
+ :no_ssl_verify => false,
24
+ }
25
+
26
+ additional_headers = []
27
+ opt_parser = OptionParser.new do |opts|
28
+ opts.banner = "Usage: mauth-client [options] <verb> <url> [body]"
29
+
30
+ opts.on("-v", "--[no-]verbose", "Run verbosely - output is like curl -v (this is the default)") do |v|
31
+ $options[:verbose] = v
32
+ end
33
+ opts.on("-q", "Run quietly - only outputs the response body (same as --no-verbose)") do |v|
34
+ $options[:verbose] = !v
35
+ end
36
+ opts.on("--[no-]authenticate", "Authenticate the response received") do |v|
37
+ $options[:authenticate_response] = v
38
+ end
39
+ opts.on("--[no-]color", "Color the output (defaults to color if the output device is a TTY)") do |v|
40
+ $options[:color] = v
41
+ end
42
+ opts.on("-t", "--content-type CONTENT-TYPE", "Sets the Content-Type header of the request") do |v|
43
+ $options[:content_type] = v
44
+ end
45
+ opts.on("-H", "--header LINE", "accepts a json string of additional headers to included. IE 'cache-expirey: 10, other: value") do |v|
46
+ additional_headers << v
47
+ end
48
+ opts.on("--no-ssl-verify", "Disables SSL verification - use cautiously!") do
49
+ $options[:no_ssl_verify] = true
50
+ end
51
+ $options[:additional_headers] =additional_headers
52
+ end
53
+ opt_parser.parse!
54
+ abort(opt_parser.help) unless (2..3).include?(ARGV.size)
55
+
56
+ # FIND MAUTH CONFIG
57
+
58
+ possible_mauth_config_files = [
59
+ # whoops, I called this MAUTH_CONFIG_YML in one place and MAUTH_CONFIG_YAML in another. supporting both for now.
60
+ ENV['MAUTH_CONFIG_YML'],
61
+ ENV['MAUTH_CONFIG_YAML'],
62
+ '~/.mauth_config.yml',
63
+ './config/mauth.yml',
64
+ './mauth.yml',
65
+ ].compact
66
+
67
+ mauth_config_yml = possible_mauth_config_files.detect do |filename|
68
+ File.exists?(File.expand_path(filename))
69
+ end
70
+ unless mauth_config_yml
71
+ message = "could not find mauth config. giving up. please place a mauth config in one of the standard places, " +
72
+ "or point the MAUTH_CONFIG_YML environment variable at an existing one. standard places are:" +
73
+ possible_mauth_config_files.map{|f| "\n\t#{f}" }.join
74
+ abort message
75
+ end
76
+
77
+ mauth_config = MAuth::Client.default_config(:mauth_config_yml => File.expand_path(mauth_config_yml))
78
+
79
+ # INSTANTIATE MAUTH CLIENT
80
+
81
+ logger = Logger.new(STDERR)
82
+ mauth_client = MAuth::Client.new(mauth_config.merge('logger' => logger))
83
+
84
+ # OUTPUTTERS FOR FARADAY THAT SHOULD MOVE TO A LIB SOMEWHERE
85
+
86
+ # outputs the response body to the given output device (defaulting to STDOUT)
87
+ class FaradayOutputter < Faraday::Middleware
88
+ def initialize(app, outdev=STDOUT)
89
+ @app=app
90
+ @outdev = outdev
91
+ end
92
+
93
+ def call(request_env)
94
+ @app.call(request_env).on_complete do |response_env|
95
+ @outdev.puts(response_env[:body] || '')
96
+ end
97
+ end
98
+ end
99
+
100
+ # this is to approximate `curl -v`s output. but it's all faked, whereas curl gives you
101
+ # the real text written and read for request and response. whatever, close enough.
102
+ class FaradayCurlVOutputter < FaradayOutputter
103
+
104
+ # defines a method with the given name, applying coloring defined by any additional arguments.
105
+ # if $options[:color] is set, respects that; otherwise, applies color if the output device is a tty.
106
+ def self.color(name, *color_args)
107
+ define_method(name) do |arg|
108
+ if color?
109
+ color_args.inject(arg) do |result, color_arg|
110
+ Term::ANSIColor.send(color_arg, result)
111
+ end
112
+ else
113
+ arg
114
+ end
115
+ end
116
+ end
117
+
118
+ color :info, :intense_yellow
119
+ color :info_body, :yellow
120
+ color :protocol
121
+
122
+ color :request, :intense_cyan
123
+ color :request_verb, :bold
124
+ color :request_header
125
+ color :request_blankline, :intense_cyan, :bold
126
+
127
+ color :response, :intense_green
128
+ color :response_status, :bold, :green
129
+ color :response_header
130
+ color :response_blankline, :intense_green, :bold
131
+
132
+ def call(request_env)
133
+ @outdev.puts "#{info('*')} #{info_body("connect to #{request_env[:url].host} on port #{request_env[:url].port}")}"
134
+ @outdev.puts "#{info('*')} #{info_body("getting our SSL on")}" if request_env[:url].scheme=='https'
135
+ @outdev.puts "#{request('>')} #{request_verb(request_env[:method].to_s.upcase)} #{request_env[:url].path} #{protocol('HTTP/1.1' || 'or something - TODO')}"
136
+ request_env[:request_headers].each do |k, v|
137
+ @outdev.puts "#{request('>')} #{request_header(k)}#{request(':')} #{v}"
138
+ end
139
+ @outdev.puts "#{request_blankline('>')} "
140
+ request_body = color_body_by_content_type(request_env[:body], request_env[:request_headers]['Content-Type'])
141
+ (request_body || '').split("\n", -1).each do |line|
142
+ @outdev.puts "#{request('>')} #{line}"
143
+ end
144
+ @app.call(request_env).on_complete do |response_env|
145
+ @outdev.puts "#{response('<')} #{protocol('HTTP/1.1' || 'or something - TODO')} #{response_status(response_env[:status].to_s)}"
146
+ request_env[:response_headers].each do |k, v|
147
+ @outdev.puts "#{response('<')} #{response_header(k)}#{response(':')} #{v}"
148
+ end
149
+ @outdev.puts "#{response_blankline ('<')} "
150
+ response_body = color_body_by_content_type(response_env[:body], response_env[:response_headers]['Content-Type'])
151
+ (response_body || '').split("\n", -1).each do |line|
152
+ @outdev.puts "#{response('<')} #{line}"
153
+ end
154
+ end
155
+ end
156
+
157
+ # whether to use color
158
+ def color?
159
+ $options[:color].nil? ? @outdev.tty? : $options[:color]
160
+ end
161
+
162
+ # a mapping for each registered CodeRay scanner to the Media Types which represent
163
+ # that language. extremely incomplete!
164
+ CodeRayForMediaTypes = {
165
+ :c => [],
166
+ :cpp => [],
167
+ :clojure => [],
168
+ :css => ['text/css', 'application/css-stylesheet'],
169
+ :delphi => [],
170
+ :diff => [],
171
+ :erb => [],
172
+ :groovy => [],
173
+ :haml => [],
174
+ :html => ['text/html'],
175
+ :java => [],
176
+ :java_script => ['application/javascript', 'text/javascript', 'application/x-javascript'],
177
+ :json => ['application/json', %r(\Aapplication/.*\+json\z)],
178
+ :php => [],
179
+ :python => ['text/x-python'],
180
+ :ruby => [],
181
+ :sql => [],
182
+ :xml => ['text/xml', 'application/xml', %r(\Aapplication/.*\+xml\z)],
183
+ :yaml => [],
184
+ }
185
+
186
+ # takes a body and a content type; returns the body, with coloring (ansi colors for terminals)
187
+ # possibly added, if it's a recognized content type and #color? is true
188
+ def color_body_by_content_type(body, content_type)
189
+ if body && color?
190
+ # kinda hacky way to get the media_type. faraday should supply this ...
191
+ require 'rack'
192
+ media_type = ::Rack::Request.new({'CONTENT_TYPE' => content_type}).media_type
193
+ coderay_scanner = CodeRayForMediaTypes.reject{|k,v| !v.any?{|type| type === media_type} }.keys.first
194
+ if coderay_scanner
195
+ require 'coderay'
196
+ if coderay_scanner == :json
197
+ body = begin
198
+ JSON.pretty_generate(JSON.parse(body))
199
+ rescue JSON::ParserError
200
+ body
201
+ end
202
+ end
203
+ body = CodeRay.scan(body, coderay_scanner).encode(:terminal)
204
+ end
205
+ end
206
+ body
207
+ end
208
+ end
209
+
210
+ # CONFIGURE THE FARADAY CONNECTION
211
+ faraday_options = {}
212
+ if $options[:no_ssl_verify]
213
+ faraday_options[:ssl] = {:verify => false}
214
+ end
215
+ connection = Faraday.new(faraday_options) do |builder|
216
+ builder.use MAuth::Faraday::MAuthClientUserAgent, "MAuth-Client CLI"
217
+ builder.use MAuth::Faraday::RequestSigner, :mauth_client => mauth_client
218
+ if $options[:authenticate_response]
219
+ builder.use MAuth::Faraday::ResponseAuthenticator, :mauth_client => mauth_client
220
+ end
221
+ builder.use $options[:verbose] ? FaradayCurlVOutputter : FaradayOutputter
222
+ builder.adapter Faraday.default_adapter
223
+ end
224
+
225
+ httpmethod, url, body = *ARGV
226
+
227
+ unless Faraday::Connection::METHODS.map{|m| m.to_s.downcase }.include?(httpmethod.downcase)
228
+ abort "Unrecognized HTTP method given: #{httpmethod}\n\n" + opt_parser.help
229
+ end
230
+
231
+ headers = {}
232
+ if $options[:content_type]
233
+ headers['Content-Type'] = $options[:content_type]
234
+ else
235
+ if body
236
+ # I'd rather not have a default content-type, but if none is set then the HTTP adapter sets this to
237
+ # application/x-www-form-urlencoded anyway. application/json is a better default for our purposes.
238
+ headers['Content-Type'] = 'application/json'
239
+ end
240
+ end
241
+
242
+ if $options[:additional_headers]
243
+ $options[:additional_headers].each do |cur|
244
+ raise "Headers must be in the format of [key]:[value]" unless cur.include?(':')
245
+ key, throw_away ,value = cur.partition(':')
246
+ headers[key] = value
247
+ end
248
+ end
249
+
250
+ # OH LOOK IT'S FINALLY ACTUALLY CONNECTING TO SOMETHING
251
+
252
+ begin
253
+ response = connection.run_request(httpmethod.downcase.to_sym, url, body, headers)
254
+ rescue MAuth::InauthenticError, MAuth::UnableToAuthenticateError => e
255
+ if $options[:color].nil? ? STDERR.tty? : $options[:color]
256
+ class_color = Term::ANSIColor.method(e.is_a?(MAuth::InauthenticError) ? :intense_red : :intense_yellow)
257
+ message_color = Term::ANSIColor.method(e.is_a?(MAuth::InauthenticError) ? :red : :yellow)
258
+ else
259
+ class_color = proc{|s| s }
260
+ message_color = proc{|s| s }
261
+ end
262
+ STDERR.puts(class_color.call(e.class.to_s))
263
+ STDERR.puts(message_color.call(e.message))
264
+ end
data/exe/mauth-proxy ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
4
+
5
+ require 'rubygems'
6
+ require 'mauth/proxy'
7
+ require 'rack'
8
+
9
+ headers = []
10
+ headers_index = ARGV.find_index('--header')
11
+ while(headers_index) do
12
+ headers << ARGV[headers_index + 1]
13
+ ARGV.delete_at(headers_index + 1)
14
+ ARGV.delete_at(headers_index)
15
+ headers_index = ARGV.find_index('--header')
16
+ end
17
+
18
+ authenticate_responses = !ARGV.delete('--no-authenticate')
19
+ browser_proxy = !(ARGV.delete('--browser_proxy').nil?)
20
+
21
+ target_uri = browser_proxy ? ARGV : ARGV.pop
22
+
23
+ if !target_uri || target_uri.empty?
24
+ abort("Usage: mauth-proxy [rack options] --browser_proxy [--no-authenticate] <target URI> <target URI> ...\n" +
25
+ "or: mauth-proxy [rack options] <target URI>")
26
+ end
27
+
28
+ rack_server_options = Rack::Server::Options.new.parse!(ARGV)
29
+
30
+ # for security, this rack server will only accept local connections, so override Host
31
+ # to 127.0.0.1 (from the default of 0.0.0.0)
32
+ #
33
+ # this means that the '-o' / '--host' option to Rack::Server::Options is ignored.
34
+ rack_server_options[:Host] = "127.0.0.1"
35
+
36
+ rack_server_options[:app] = MAuth::Proxy.new(target_uri, :authenticate_responses => authenticate_responses,
37
+ :browser_proxy => browser_proxy, :headers => headers)
38
+
39
+ mauth_proxy_server = Rack::Server.new(rack_server_options)
40
+ mauth_proxy_server.start
@@ -0,0 +1,8 @@
1
+ module MAuth
2
+ autoload :Client, 'mauth/client'
3
+ autoload :Middleware, 'mauth/middleware'
4
+ autoload :Faraday, 'mauth/faraday'
5
+ autoload :Rack, 'mauth/rack'
6
+ autoload :Request, 'mauth/request_and_response'
7
+ autoload :Response, 'mauth/request_and_response'
8
+ end