mauth-client 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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