nginx_omniauth_adapter 0.2.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: da45545a31a51031b94607551c7296f3011c3769
4
- data.tar.gz: 79f17b771dffb86ff9527b78a7fbbe14d1a71bf1
2
+ SHA256:
3
+ metadata.gz: 66f14d6c854ca770e18ee0898ed71488b40d74dca518e543035cef0940d9f228
4
+ data.tar.gz: 23e54318a5efbd0f6dd2b020b4454d16b8e6f847982d9a379256244e48edbdc9
5
5
  SHA512:
6
- metadata.gz: 84be2b3d973d457a98b52ba75498b3dd84557012dd8fc9ddadeb5e2873fd9a80efb146f2177024214eadbaf1524814869f250c5ce972fce3e5bad3f61aad7714
7
- data.tar.gz: 432c64e9ec6b1953947d6a8ed72e6c4eb019db5cf984cd62de39361c4d594ca7800be2686f25caae168c9b14f5ec24ccf8ae58ff951916ab049129a613687a6d
6
+ metadata.gz: f893093f330d8b3cbacec6d3a1366f44da12cc0fe9eb75b68f0c2ff075ba7cdeb6c0a71a52e4d4283642562e8c6b4b79f7378b490bc78d2eea1668374617fbc8
7
+ data.tar.gz: bb19421a7885cfa989da7fdb84ee88246efa55662fd05438aeb17c608631a018445eb9e98d500434e41f0fff9f9f3e4275af053a556bf7c3ad9a9c14a1bc5c95
@@ -0,0 +1,78 @@
1
+ name: ci
2
+ on:
3
+ pull_request:
4
+ branches: [master]
5
+ push:
6
+ branches: [master, ci-test]
7
+
8
+ env:
9
+ DOCKER_REPO: 'sorah/acmesmith'
10
+
11
+ jobs:
12
+ test:
13
+ name: rspec
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby-version: ['2.7', '3.0', '3.1']
19
+ container:
20
+ image: public.ecr.aws/sorah/ruby:${{ matrix.ruby-version }}-dev
21
+ steps:
22
+ - name: Cache bundled gems
23
+ uses: actions/cache@v3
24
+ id: rspec-bundle
25
+ with:
26
+ path: ~/bundle
27
+ key: ${{ runner.os }}-${{ matrix.ruby-version }}
28
+ - uses: actions/checkout@v3
29
+ - run: 'apt-get update && apt-get install -y --no-install-recommends nginx'
30
+ - run: 'bundle install --path ~/bundle'
31
+ - run: 'bundle exec rspec -fd'
32
+
33
+ #docker-build:
34
+ # name: docker-build
35
+ # runs-on: ubuntu-latest
36
+ # steps:
37
+ # - uses: actions/checkout@master
38
+ # - run: 'echo $GITHUB_SHA > REVISION'
39
+
40
+ # - run: "docker pull ${DOCKER_REPO}:latest || :"
41
+ # - name: "docker tag ${DOCKER_REPO}:${TAG} ${DOCKER_REPO}:latest"
42
+ # run: |
43
+ # TAG=$(basename "${{ github.ref }}")
44
+ # docker pull ${DOCKER_REPO}:${TAG} || :
45
+ # docker tag ${DOCKER_REPO}:${TAG} ${DOCKER_REPO}:latest || :
46
+ # if: "${{ startsWith(github.ref, 'refs/tags/v') }}"
47
+
48
+ # - run: "docker pull ${DOCKER_REPO}:builder || :"
49
+
50
+ # - run: "docker build --pull --cache-from ${DOCKER_REPO}:builder --target builder -t ${DOCKER_REPO}:builder -f Dockerfile ."
51
+ # - run: "docker build --pull --cache-from ${DOCKER_REPO}:builder --cache-from ${DOCKER_REPO}:latest -t ${DOCKER_REPO}:${GITHUB_SHA} -f Dockerfile ."
52
+
53
+ # - run: "echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u sorah --password-stdin"
54
+ # if: "${{ github.event_name != 'pull_request' }}"
55
+
56
+ # - run: "docker push ${DOCKER_REPO}:builder"
57
+ # if: "${{ github.ref == 'refs/heads/master' }}"
58
+ # - run: "docker push ${DOCKER_REPO}:${GITHUB_SHA}"
59
+ # if: "${{ github.event_name != 'pull_request' }}"
60
+
61
+ #docker-push:
62
+ # name: docker-push
63
+ # needs: [test, integration-pebble, docker-build]
64
+ # if: "${{ github.event_name == 'push' || github.event_name == 'create' }}"
65
+ # runs-on: ubuntu-latest
66
+ # steps:
67
+ # - run: "echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u sorah --password-stdin"
68
+ # - run: "docker pull ${DOCKER_REPO}:${GITHUB_SHA}"
69
+
70
+ # - run: |
71
+ # docker tag ${DOCKER_REPO}:${GITHUB_SHA} ${DOCKER_REPO}:latest
72
+ # docker push ${DOCKER_REPO}:latest
73
+ # if: "${{ github.ref == 'refs/heads/master' }}"
74
+ # - run: |
75
+ # TAG=$(basename "${{ github.ref }}")
76
+ # docker tag ${DOCKER_REPO}:${GITHUB_SHA} ${DOCKER_REPO}:${TAG}
77
+ # docker push ${DOCKER_REPO}:${TAG}
78
+ # if: "${{ startsWith(github.ref, 'refs/tags/v') }}"
data/Dockerfile CHANGED
@@ -12,6 +12,7 @@ RUN cd /tmp && bundle install -j4 --path vendor/bundle --without 'development te
12
12
  WORKDIR /app
13
13
  ADD . /app
14
14
  RUN cp -a /tmp/.bundle /tmp/vendor /app/
15
+ RUN rm -f /app/.ruby-version
15
16
 
16
17
  EXPOSE 8080
17
18
  ENV RACK_ENV=production
data/Gemfile CHANGED
@@ -4,4 +4,5 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'omniauth-github'
7
- gem 'omniauth-google-oauth2'
7
+ gem 'omniauth-google-oauth2', '>= 0.3.1'
8
+ gem 'unicorn'
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # NginxOmniauthAdapter - Use omniauth for nginx `auth_request`
2
2
 
3
+ [![ci](https://github.com/sorah/nginx_omniauth_adapter/actions/workflows/ci.yml/badge.svg)](https://github.com/sorah/nginx_omniauth_adapter/actions/workflows/ci.yml)
4
+
3
5
  Use [omniauth](https://github.com/intridea/omniauth) for your nginx's authentication via ngx_http_auth_request_module.
4
6
 
5
7
  NginxOmniauthAdapter provides small Rack app (built with Sinatra) for `auth_request`.
@@ -17,7 +19,7 @@ $ cd example/
17
19
  $ foreman start
18
20
  ```
19
21
 
20
- http://ngx-auth-test.127.0.0.1.xip.io:18080/
22
+ http://ngx-auth-test.lo.nkmiusercontent.com:18080/
21
23
 
22
24
  (make sure to have nginx on your PATH)
23
25
 
@@ -40,13 +42,19 @@ Then write `config.ru` then deploy it. (see ./config.ru for example)
40
42
 
41
43
  ### Using docker
42
44
 
43
- TBD
45
+ - Prebuilt: https://quay.io/repository/sorah/nginx_omniauth_adapter
46
+ - Own your risk.
47
+ - They're built at circleci
48
+ - Build manually: checkout this repo and run `docker build .`.
49
+ - Much safer.
50
+ - But if you can't trust upstream image `quay.io/sorah/rbenv:2.2`, write your own Dockerfile. This is just a simple Rack app.
44
51
 
45
52
  ## Configuration
46
53
 
47
54
  environment variable is available only on included config.ru (or Docker image).
48
55
 
49
56
  - `:providers`: omniauth provider names.
57
+ - `:provider_http_header` `$NGX_OMNIAUTH_PROVIDER_HTTP_HEADER` (string): Name of HTTP header to specify OmniAuth provider to be used (see below). Defaults to 'x-ngx-omniauth-provider`.
50
58
  - `:secret` `$NGX_OMNIAUTH_SESSION_SECRET`: Rack session secret. Should be set when not on dev mode
51
59
  - `:host` `$NGX_OMNIAUTH_HOST`: URL of adapter. This is used for redirection. Should include protocol (e.g. `http://example.com`.)
52
60
  - If this is not specified, adapter will perform redirect using given `Host` header.
@@ -55,6 +63,11 @@ environment variable is available only on included config.ru (or Docker image).
55
63
  - `:app_refresh_interval` `NGX_OMNIAUTH_APP_REFRESH_INTERVAL` (integer): Interval to require refresh session cookie on app domain (in second, default 1 day).
56
64
  - `:adapter_refresh_interval` `NGX_OMNIAUTH_ADAPTER_REFRESH_INTERVAL` (integer): Interval to require re-logging in on adapter domain (in second, default 3 days).
57
65
 
66
+ ### Working with multiple OmniAuth providers
67
+
68
+ When multiple providers are passed to `:providers`, nginx_omniauth_adapter defaults to the first one in list.
69
+ Other providers in list will only be activated for requests with `x-ngx-omniauth-provider` header (key is configurable via `:provider_http_header`).
70
+
58
71
  ### Included config.ru (or Docker)
59
72
 
60
73
  You can set configuration via environment variables.
@@ -94,6 +107,8 @@ run NginxOmniauthAdapter.app(
94
107
 
95
108
  ## How it works
96
109
 
110
+ ![](http://img.sorah.jp/2015-10-08_22.55_2s4hy.png)
111
+
97
112
  1. _browser_ access to restricted area (where `auth_request` has enabled)
98
113
  2. _nginx_ sends subrequest to `/_auth/challenge`. It will be proxied to _adapter app_ (`GET /test`)
99
114
  3. _adapter app_ `/test` returns 401 when _request (browser)_ doesn't have valid cookie
data/config.ru CHANGED
@@ -74,6 +74,7 @@ end
74
74
 
75
75
  run NginxOmniauthAdapter.app(
76
76
  providers: providers,
77
+ provider_http_header: ENV['NGX_OMNIAUTH_PROVIDER_HTTP_HEADER'] || 'x-ngx-omniauth-provider',
77
78
  secret: ENV['NGX_OMNIAUTH_SECRET'],
78
79
  host: ENV['NGX_OMNIAUTH_HOST'],
79
80
  allowed_app_callback_url: allowed_app_callback_url,
data/example/Procfile CHANGED
@@ -1,3 +1,3 @@
1
1
  nginx: nginx -c `pwd`/nginx.conf
2
- adapter: bundle exec env RACK_ENV=development NGX_OMNIAUTH_HOST=http://ngx-auth.127.0.0.1.xip.io:18080 rackup -p 18081 -o 127.0.0.1 ../config.ru
2
+ adapter: bundle exec env RACK_ENV=development NGX_OMNIAUTH_HOST=http://ngx-auth.lo.nkmiusercontent.com:18080 rackup -p 18081 -o 127.0.0.1 ../config.ru
3
3
  app: bundle exec ruby test_backend.rb -p 18082 -o 127.0.0.1
@@ -6,7 +6,7 @@ upstream auth_adapter {
6
6
  }
7
7
  server {
8
8
  listen 127.0.0.1:18080;
9
- server_name ngx-auth.127.0.0.1.xip.io;
9
+ server_name ngx-auth.lo.nkmiusercontent.com;
10
10
 
11
11
  location / {
12
12
  proxy_pass http://auth_adapter;
@@ -20,12 +20,13 @@ upstream app {
20
20
  }
21
21
  server {
22
22
  listen 127.0.0.1:18080;
23
- server_name ngx-auth-test.127.0.0.1.xip.io;
23
+ server_name ngx-auth-test.lo.nkmiusercontent.com;
24
24
 
25
25
  # Restricted area
26
26
  location / {
27
27
  auth_request /_auth/challenge;
28
28
  # Trick - do internal redirection when auth_request says "need auth".
29
+ proxy_intercept_errors off;
29
30
  error_page 401 = /_auth/initiate;
30
31
 
31
32
  # Receive user info from adapter
data/example/nginx.conf CHANGED
@@ -1,6 +1,7 @@
1
1
  # vim: ft=nginx
2
2
  worker_processes 1;
3
3
  daemon off;
4
+ pid /tmp/nginx_omniauth_adapter-nginx.pid;
4
5
 
5
6
  error_log stderr;
6
7
 
@@ -13,5 +14,7 @@ http {
13
14
 
14
15
  server_names_hash_bucket_size 128;
15
16
 
17
+ access_log off;
18
+
16
19
  include nginx-site.conf;
17
20
  }
@@ -7,7 +7,7 @@ get '/' do
7
7
  {
8
8
  provider: request.env['HTTP_X_NGX_OMNIAUTH_PROVIDER'],
9
9
  user: request.env['HTTP_X_NGX_OMNIAUTH_USER'],
10
- info: JSON.parse(request.env['HTTP_X_NGX_OMNIAUTH_INFO'].unpack('m*')[0]),
10
+ info: JSON.parse(request.env['HTTP_X_NGX_OMNIAUTH_INFO'].unpack('m0')[0]),
11
11
  }.to_json
12
12
  end
13
13
 
@@ -3,6 +3,7 @@ require 'uri'
3
3
  require 'time'
4
4
  require 'openssl'
5
5
  require 'json'
6
+ require 'securerandom'
6
7
 
7
8
  module NginxOmniauthAdapter
8
9
  class App < Sinatra::Base
@@ -44,6 +45,10 @@ module NginxOmniauthAdapter
44
45
  adapter_config[:providers]
45
46
  end
46
47
 
48
+ def provider_http_header
49
+ adapter_config[:provider_http_header] || 'x-ngx-omniauth-provider'
50
+ end
51
+
47
52
  def allowed_back_to_url
48
53
  adapter_config[:allowed_back_to_url] || /./
49
54
  end
@@ -60,13 +65,30 @@ module NginxOmniauthAdapter
60
65
  adapter_config[:policy_proc] || proc { true }
61
66
  end
62
67
 
68
+ def log(h={})
69
+ h = {
70
+ time: Time.now.xmlschema,
71
+ severity: :info,
72
+ logged_in: (!!current_user).inspect,
73
+ provider: current_user && current_user[:provider],
74
+ uid: current_user && current_user[:uid],
75
+ flow_id: current_flow_id,
76
+ }.merge(h)
77
+
78
+ str = h.map { |*kv| kv.join(?:) }.join(?\t)
79
+
80
+ puts str
81
+ if h[:severity] == :warning || h[:severity] == :error
82
+ $stderr.puts str
83
+ end
84
+ end
85
+
63
86
  def default_back_to
64
87
  # TODO:
65
88
  '/'
66
89
  end
67
90
 
68
91
  def sanitized_back_to_param
69
- p params[:back_to]
70
92
  if allowed_back_to_url === params[:back_to]
71
93
  params[:back_to]
72
94
  else
@@ -75,7 +97,6 @@ module NginxOmniauthAdapter
75
97
  end
76
98
 
77
99
  def sanitized_app_callback_param
78
- p params[:callback]
79
100
  if allowed_app_callback_url === params[:callback]
80
101
  params[:callback]
81
102
  else
@@ -83,6 +104,14 @@ module NginxOmniauthAdapter
83
104
  end
84
105
  end
85
106
 
107
+ def set_flow_id!
108
+ session[:flow_id] = SecureRandom.uuid
109
+ end
110
+
111
+ def current_flow_id
112
+ session[:flow_id]
113
+ end
114
+
86
115
  def current_user
87
116
  session[:user]
88
117
  end
@@ -117,6 +146,7 @@ module NginxOmniauthAdapter
117
146
 
118
147
  def update_session!(auth = nil)
119
148
  unless session[:app_callback]
149
+ log severity: :error, message: 'missing app_callback'
120
150
  raise '[BUG] app_callback is missing'
121
151
  end
122
152
 
@@ -148,7 +178,12 @@ module NginxOmniauthAdapter
148
178
  session.merge!(adapter_session)
149
179
 
150
180
  session_param = encrypt_session_param(app_session)
181
+
182
+ log(message: 'update_session', app_callback: session[:app_callback])
183
+
151
184
  redirect "#{session.delete(:app_callback)}?session=#{session_param}"
185
+ ensure
186
+ session[:flow_id] = nil
152
187
  end
153
188
 
154
189
  def secret_key
@@ -212,10 +247,12 @@ module NginxOmniauthAdapter
212
247
 
213
248
  get '/test' do
214
249
  unless current_user
250
+ log(message: 'test_not_logged_in', original_uri: request.env['HTTP_X_NGX_OMNIAUTH_ORIGINAL_URI'])
215
251
  halt 401
216
252
  end
217
253
 
218
254
  if app_authorization_expired?
255
+ log(message: 'test_app_authorization_expired', original_uri: request.env['HTTP_X_NGX_OMNIAUTH_ORIGINAL_URI'])
219
256
  halt 401
220
257
  end
221
258
 
@@ -226,7 +263,7 @@ module NginxOmniauthAdapter
226
263
  headers(
227
264
  'x-ngx-omniauth-provider' => current_user[:provider],
228
265
  'x-ngx-omniauth-user' => current_user[:uid],
229
- 'x-ngx-omniauth-info' => [current_user[:info].to_json].pack('m*'),
266
+ 'x-ngx-omniauth-info' => [current_user[:info].to_json].pack('m0'),
230
267
  )
231
268
 
232
269
  content_type :text
@@ -238,34 +275,58 @@ module NginxOmniauthAdapter
238
275
  callback = URI.encode_www_form_component(request.env['HTTP_X_NGX_OMNIAUTH_INITIATE_CALLBACK'])
239
276
 
240
277
  if back_to == '' || callback == '' || back_to.nil? || callback.nil?
278
+ log(severity: :error, message: 'initiate_no_required_params', back_to: back_to, callback: callback)
241
279
  halt 400, {'Content-Type' => 'text/plain'}, 'x-ngx-omniauth-initiate-back-to and x-ngx-omniauth-initiate-callback header are required'
242
280
  end
243
281
 
282
+ log(message: 'initiate', adapter_host: adapter_host, back_to: back_to, callback: callback)
283
+
244
284
  redirect "#{adapter_host}/auth?back_to=#{back_to}&callback=#{callback}"
245
285
  end
246
286
 
247
287
  get '/auth' do
248
- # TODO: choose provider
288
+ set_flow_id!
289
+
290
+ provider_requested = request.env["HTTP_#{provider_http_header.gsub('-', '_').upcase}"]
291
+ if provider_requested
292
+ if providers.include?(provider_requested.to_sym)
293
+ provider = provider_requested.to_sym
294
+ else
295
+ halt 401, {'Content-Type' => 'text/plain'}, 'requested provider not available'
296
+ end
297
+ else
298
+ # default to the first provider in list
299
+ provider = providers[0]
300
+ end
301
+
249
302
  session[:back_to] = sanitized_back_to_param
250
303
  session[:app_callback] = sanitized_app_callback_param
251
- p [:auth, session]
304
+
305
+ if session[:back_to] == '' || session[:app_callback] == '' || session[:back_to].nil? || session[:app_callback].nil?
306
+ log(severity: :error, message: 'auth_invalid_params', back_to: params[:back_to], callback: params[:callback])
307
+ halt 400, {'Content-Type' => 'text/plain'}, 'back_to or/and app_callback is invalid'
308
+ end
252
309
 
253
310
  if current_user && !adapter_authorization_expired?
254
- p [:auth, :update]
311
+ log(message: 'auth_refresh_app', back_to: params[:back_to], callback: params[:callback])
255
312
  update_session!
256
313
  else
257
- p [:auth, :redirect]
258
- redirect "#{adapter_host}/auth/#{providers[0]}"
314
+ log(message: 'auth', provider: provider, back_to: params[:back_to], callback: params[:callback])
315
+ redirect "#{adapter_host}/auth/#{provider}"
259
316
  end
260
317
  end
261
318
 
262
319
  omniauth_callback = proc do
320
+
263
321
  session[:user_data] = {}
264
322
 
265
323
  unless instance_eval(&on_login_proc)
324
+ log(severity: :warning, message: 'omniauth_callback_forbidden', new_uid: env['omniauth.auth'][:uid])
266
325
  halt 403, {'Content-Type' => 'text/plain'}, 'Forbidden (on_login_proc policy)'
267
326
  end
268
327
 
328
+ log(message: 'omniauth_callback', new_uid: env['omniauth.auth'][:uid])
329
+
269
330
  session[:logged_in_at] = Time.now.xmlschema
270
331
  update_session! env['omniauth.auth']
271
332
  end
@@ -275,6 +336,7 @@ module NginxOmniauthAdapter
275
336
  get '/callback' do # app side
276
337
  app_session = decrypt_session_param(params[:session])
277
338
  session.merge!(app_session)
339
+ log(message: 'app_callback', back_to: session[:back_to])
278
340
  redirect session.delete(:back_to)
279
341
  end
280
342
  end
@@ -1,3 +1,3 @@
1
1
  module NginxOmniauthAdapter
2
- VERSION = "0.2.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "sinatra"
22
- spec.add_dependency "omniauth"
22
+ spec.add_dependency "omniauth", '< 2'
23
23
 
24
24
  spec.add_development_dependency "bundler"
25
25
  spec.add_development_dependency "rake"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nginx_omniauth_adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shota Fukumori (sora_h)
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-02 00:00:00.000000000 Z
11
+ date: 2022-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: omniauth
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "<"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,13 +108,14 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description:
111
+ description:
112
112
  email:
113
113
  - her@sorah.jp
114
114
  executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
+ - ".github/workflows/ci.yml"
118
119
  - ".gitignore"
119
120
  - ".rspec"
120
121
  - ".travis.yml"
@@ -138,7 +139,7 @@ homepage: https://github.com/sorah/nginx_omniauth_adapter
138
139
  licenses:
139
140
  - MIT
140
141
  metadata: {}
141
- post_install_message:
142
+ post_install_message:
142
143
  rdoc_options: []
143
144
  require_paths:
144
145
  - lib
@@ -153,9 +154,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
154
  - !ruby/object:Gem::Version
154
155
  version: '0'
155
156
  requirements: []
156
- rubyforge_project:
157
- rubygems_version: 2.5.0
158
- signing_key:
157
+ rubygems_version: 3.4.0.dev
158
+ signing_key:
159
159
  specification_version: 4
160
160
  summary: omniauth adapter for ngx_http_auth_request_module
161
161
  test_files: []