heimdall_auth_bw 2.0.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.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +140 -0
  4. data/Rakefile +27 -0
  5. data/app/controllers/heimdall_auth/sessions_controller.rb +39 -0
  6. data/lib/generators/heimdall_auth/cancan/cancan_generator.rb +19 -0
  7. data/lib/generators/heimdall_auth/cancan/templates/ability.rb +39 -0
  8. data/lib/generators/heimdall_auth/dotenv/dotenv_generator.rb +24 -0
  9. data/lib/generators/heimdall_auth/dotenv/templates/dot-env.example +3 -0
  10. data/lib/generators/heimdall_auth/install/install_generator.rb +12 -0
  11. data/lib/generators/heimdall_auth/sessions/sessions_generator.rb +26 -0
  12. data/lib/generators/heimdall_auth/standard_pages/standard_pages_generator.rb +23 -0
  13. data/lib/generators/heimdall_auth/standard_pages/templates/admin_controller.rb +5 -0
  14. data/lib/generators/heimdall_auth/standard_pages/templates/admin_view.html.erb +2 -0
  15. data/lib/generators/heimdall_auth/standard_pages/templates/invalid_user_data.html.erb +2 -0
  16. data/lib/generators/heimdall_auth/standard_pages/templates/login_button.html.erb +3 -0
  17. data/lib/generators/heimdall_auth/standard_pages/templates/not_enough_rights.html.erb +2 -0
  18. data/lib/heimdall_auth/authentication_additions.rb +48 -0
  19. data/lib/heimdall_auth/controller_additions.rb +41 -0
  20. data/lib/heimdall_auth/engine.rb +28 -0
  21. data/lib/heimdall_auth/rails/routes.rb +38 -0
  22. data/lib/heimdall_auth/railtie.rb +4 -0
  23. data/lib/heimdall_auth/route_constraint.rb +57 -0
  24. data/lib/heimdall_auth/user.rb +29 -0
  25. data/lib/heimdall_auth/version.rb +3 -0
  26. data/lib/heimdall_auth_bw.rb +16 -0
  27. data/lib/omniauth/stategies/heimdall.rb +47 -0
  28. data/lib/tasks/puma_dev_link.rake +12 -0
  29. data/lib/tasks/register.rake +84 -0
  30. metadata +151 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 897e838e92686bdc993d3528f0907ab07d894c9f2962f6ca601ba79bc4b4552d
4
+ data.tar.gz: d6abc328c02dfd3c278db93384755844e2a2e8a34f5af6209a971e53aa847546
5
+ SHA512:
6
+ metadata.gz: 3e97a168649f24437530649f4401a39948a27138f73453415953c160ee6a1ccc42b09c6598d22251bb4d37c7300731fdb09d81292d73f822f1f83887ff233086
7
+ data.tar.gz: 7a48c02ea680b9029746c840d8a3d044f16e34f814a81bed5256095c88cc4e68a123e56dca1a500f648b3fc52c74b1d19501c385f5a593a7ff4a07734c721a64
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2019 René Meye
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # HeimdallAuth
2
+ This makes it easy to equip an empty rails application with our Heimdall Auth features.
3
+
4
+ ## New Feature: Secure Sidekiq (and other mounts)
5
+ Use it like so in `config/routes.rb`:
6
+ ```
7
+ mount_heimdall_auth_secured Sidekiq::Web => '/sidekiq', :manage => :sidekiq
8
+
9
+ or
10
+
11
+ # The /sidekiq/stats path gets available for services like Datadog
12
+ mount_heimdall_auth_secured Sidekiq::Web => '/sidekiq', :manage => :sidekiq, accessible_via_token: {'/sidekiq/stats': ENV['SIDEKIQ_STATS_TOKEN_FOR_WATCHDOG']}
13
+ ```
14
+ instead of the known:
15
+ ```
16
+ mount Sidekiq::Web => '/sidekiq'
17
+ ```
18
+
19
+ Additionally you need to add the rights to your `app/models/ability.rb`:
20
+ ```
21
+ if user.is_admin
22
+ can :manage, :sidekiq
23
+ end
24
+ ```
25
+
26
+ and the password in `.env` and `.env.example` if you used it:
27
+ ```
28
+ SIDEKIQ_STATS_TOKEN_FOR_WATCHDOG=halloweltrandomstring
29
+ ```
30
+
31
+ Options:
32
+ - mount_heimdall_auth_secured ENGINE => PATH, ACTION => RESOURCE, accessible_via_token: {EXCEPTION_PATH: EXCEPTION_PASSWORD, EXCEPTION_PATH2: EXCEPTION_PASSWORD2}
33
+ - ENGINE - any mountable Engine like `Sidekiq::Web`
34
+ - PATH - where to mount the engine
35
+ - ACTION & RESOURCE - like any action and resource in cancancan
36
+ - :accessible_via_token -> Defines paths that are available via a particular token. e.g. for Watchdog services like Datadog
37
+ - URL needs then to have the token as `?token=secretpassword` in the query params. Like: `https://webhook.vesputi-abc.de/sidekiq/stats?token=secretpassword`
38
+
39
+ ## Installation and Usage
40
+
41
+ Example: https://gitlab.vesputi.com/netzmap/nanna
42
+
43
+ 0) Commit the empty rails application (and mention the command you used for generating the app)
44
+
45
+ 1) Add this line to your application's Gemfile:
46
+
47
+ ```ruby
48
+ gem 'heimdall_auth'
49
+ ```
50
+
51
+ 2) and afterwards do theses commands (yes... second bundle install ist needed, because the install script adds dotenv gem)
52
+ ```bash
53
+ bundle install
54
+ rails puma_dev:link
55
+ rails generate heimdall_auth:install
56
+ rails heimdall:register -- -u"rene@vesputi.com" -p"HeimdallPassword" >> .env
57
+ bundle install
58
+ killall puma-dev
59
+ ```
60
+
61
+ 3) And please commit directly after executing the lines above so you have clean history
62
+
63
+
64
+ ## Linking puma_dev
65
+
66
+ This executes a very simple `ln -s` command in order to link our application with appropriate naming to the local puma_dev server.
67
+ ```bash
68
+ rails puma_dev:link
69
+ ```
70
+
71
+ ## Heimdall-Auth install scripts
72
+ This makes a few steps in order to install heimdall stuff to your app.
73
+ ```bash
74
+ rails generate heimdall_auth:install
75
+ ```
76
+ executes the following generators
77
+ 1. `rails generate heimdall_auth:cancan`
78
+ 2. `rails generate heimdall_auth:sessions`
79
+ 3. `rails generate heimdall_auth:standard_pages`
80
+ 4. `rails generate heimdall_auth:dotenv`
81
+
82
+ ### generate heimdall_auth:cancan
83
+ This adds the ability.rb file of the cancancan gem with default heimdall roles and adds `check_authorization` to the application controller. (For details see the [cancancan gem](https://github.com/CanCanCommunity/cancancan))
84
+
85
+ ### generate heimdall_auth:sessions
86
+ This adds the default heimdall_auth routes for session generation to the routes file, switches the application to https only and lowers the log level.
87
+
88
+ ### generate heimdall_auth:standard_pages
89
+ This adds the default admin page `/admin` and two error pages: for invalid_user_data and not_enough_rights.
90
+
91
+ ### generate heimdall_auth:dotenv
92
+ This adds a default .env.example file (for documentation purposes) to the application and adds the dotenv gem to the gemfile which loads enviroment variables from .env file.
93
+
94
+ ## Register at local heimdall
95
+
96
+ The following command Registeres the service at Heimdall and puts credentials at the end of the `.env` file
97
+
98
+ ```bash
99
+ rails heimdall:register -- -u"rene@vesputi.com" -p"YourHeimdallPassword" >> .env
100
+ ```
101
+ Parameters:
102
+ ```
103
+ -u"rene@vesputi.com" # Username in Heimdall (Needs Admin rights)
104
+ -p"YourHeimdallPassword" # Password in Heimdall
105
+ -h"https://heimdall.vesp" (Optional) - Protocol and Domain the heimdall is found at
106
+ -s"https://foo.vesputi-abc.de" # (Optional) - Protocol and Domain the Service is found at
107
+ ```
108
+
109
+ ## RSpec
110
+ If you want to test your Applications controller than you have to give it a User
111
+ You do so by mocking `current_user` in ApplicationController
112
+
113
+ ```
114
+ RSpec.describe "/foobar", type: :request do
115
+ before { allow_any_instance_of(ApplicationController).to receive(:current_user) { HeimdallAuth::User.new(is_editor: true) } }
116
+ end
117
+ ```
118
+
119
+ # Usage with RSpec
120
+ ## Simulate an Admin user
121
+
122
+ See the example:
123
+ ```ruby
124
+ require 'rails_helper'
125
+
126
+ RSpec.describe "/cards", type: :request do
127
+
128
+ let(:admin_user) {
129
+ HeimdallAuth::User.new(email: "foo@bar.com", is_admin: true)
130
+ }
131
+
132
+ describe "GET /index" do
133
+ before(:each) do
134
+ allow_any_instance_of( HeimdallAuth::ControllerAdditions ).to receive(:current_user).and_return(admin_user)
135
+ end
136
+
137
+ it "renders a successful response" do
138
+ Card.create! valid_attributes
139
+ get cards_url
140
+ ```
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'HeimdallAuth'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'test'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = false
25
+ end
26
+
27
+ task default: :test
@@ -0,0 +1,39 @@
1
+ class HeimdallAuth::SessionsController < ApplicationController
2
+ skip_authorization_check
3
+
4
+ def new
5
+ user_token = params[:user_token].presence
6
+ heimdall_auth_url = auth_provider_url(provider: "heimdall")
7
+
8
+ if user_token
9
+ do_a_signin_precall(user_token, heimdall_auth_url)
10
+ else
11
+ redirect_to heimdall_auth_url, allow_other_host: true
12
+ end
13
+ end
14
+
15
+ def create
16
+ auth = request.env["omniauth.auth"]
17
+ session[:access_token] = auth&.credentials&.token
18
+ redirect_to( session[:last_url] || request.base_url, allow_other_host: true)
19
+ end
20
+
21
+ def destroy
22
+ last_url = session[:last_url]
23
+ reset_session
24
+ redirect_to("#{ENV['HEIMDALL_SERVER_URL']}/signout?redirect_to=#{last_url || request.base_url}", :notice => 'Signed out!', allow_other_host: true)
25
+ end
26
+
27
+ def failure
28
+ redirect_to request.base_url, :alert => "Authentication error: #{params[:message].humanize}", allow_other_host: true
29
+ end
30
+
31
+ def login_button
32
+ end
33
+
34
+ private
35
+ def do_a_signin_precall(user_token, heimdall_auth_url)
36
+ redirect_to "#{ENV['HEIMDALL_SERVER_URL']}/?user_token=#{user_token}&redirect_to=#{heimdall_auth_url}", allow_other_host: true
37
+ end
38
+
39
+ end
@@ -0,0 +1,19 @@
1
+ module HeimdallAuth
2
+ module Generators
3
+ class CancanGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ def add_ability_file
7
+ copy_file "ability.rb", "app/models/ability.rb"
8
+ end
9
+
10
+ def add_check_authorization_method
11
+ inject_into_file 'app/controllers/application_controller.rb', after: "class ApplicationController < ActionController::Base\n" do
12
+ <<-'RUBY'
13
+ check_authorization
14
+ RUBY
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Ability
4
+ include CanCan::Ability
5
+
6
+ def initialize(user)
7
+ if user && not(user.is_invalid)
8
+ can :index, :admin_page
9
+ # if user.is_editor
10
+ # can :manage, :all
11
+ # end
12
+ # if user.is_operator
13
+ # end
14
+ # if user.is_admin
15
+ # end
16
+ # if user.is_user_admin
17
+ # end
18
+ end
19
+
20
+ #
21
+ # The first argument to `can` is the action you are giving the user
22
+ # permission to do.
23
+ # If you pass :manage it will apply to every action. Other common actions
24
+ # here are :read, :create, :update and :destroy.
25
+ #
26
+ # The second argument is the resource the user can perform the action on.
27
+ # If you pass :all it will apply to every resource. Otherwise pass a Ruby
28
+ # class of the resource.
29
+ #
30
+ # The third argument is an optional hash of conditions to further filter the
31
+ # objects.
32
+ # For example, here the user can only update published articles.
33
+ #
34
+ # can :update, Article, :published => true
35
+ #
36
+ # See the wiki for details:
37
+ # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ module HeimdallAuth
2
+ module Generators
3
+ class DotenvGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ def add_dot_env_support
7
+ gem_group :development, :test do
8
+ # Load ENV variables from .env file development and test
9
+ gem 'dotenv-rails'
10
+ end
11
+ end
12
+
13
+ def create_example_file
14
+ copy_file "dot-env.example", ".env.example"
15
+ end
16
+
17
+ def ignore_dot_env_file
18
+ inject_into_file '.gitignore', after: "/.bundle\n" do
19
+ "/.env\n"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ HEIMDALL_SERVER_URL=https://heimdall.vesputi-abc.de/
2
+ HEIMDALL_APPLICATION_ID=foo
3
+ HEIMDALL_APPLICATION_SECRET=bar
@@ -0,0 +1,12 @@
1
+ module HeimdallAuth
2
+ module Generators
3
+ class InstallGenerator < ::Rails::Generators::Base
4
+ def install
5
+ generate "heimdall_auth:cancan"
6
+ generate "heimdall_auth:sessions"
7
+ generate "heimdall_auth:standard_pages"
8
+ generate "heimdall_auth:dotenv"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ module HeimdallAuth
2
+ module Generators
3
+ class SessionsGenerator < ::Rails::Generators::Base
4
+
5
+ def add_session_routes
6
+ route "use_heimdall_auth"
7
+ end
8
+
9
+ def set_https_only
10
+ gsub_file 'config/environments/production.rb', '# config.force_ssl = true', 'config.force_ssl = true'
11
+ inject_into_file 'config/environments/development.rb', after: " config.assets.debug = true\n" do
12
+ <<-'RUBY'
13
+
14
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
15
+ config.force_ssl = true
16
+ RUBY
17
+ end
18
+ end
19
+
20
+ def lower_production_log_level
21
+ gsub_file 'config/environments/production.rb', 'config.log_level = :debug', 'config.log_level = :warn'
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module HeimdallAuth
2
+ module Generators
3
+ class StandardPagesGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ def generate_admin_page
7
+ copy_file "admin_controller.rb", "app/controllers/admin_page_controller.rb"
8
+ copy_file "admin_view.html.erb", "app/views/admin_page/index.html.erb"
9
+ route "get '/admin' => 'admin_page#index'"
10
+ end
11
+
12
+ def generate_error_pages
13
+ copy_file "invalid_user_data.html.erb", "app/views/application/invalid_user_data.html.erb"
14
+ copy_file "not_enough_rights.html.erb", "app/views/application/not_enough_rights.html.erb"
15
+ end
16
+
17
+ def generate_login_pages
18
+ copy_file "login_button.html.erb", "app/views/heimdall_auth/sessions/login_button.html.erb"
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ class AdminPageController < ApplicationController
2
+ def index
3
+ authorize! :index, :admin_page
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ <h1>Admin Page</h1>
2
+ <h3>Hallo: <%=current_user && current_user.name%></h3>
@@ -0,0 +1,2 @@
1
+ <h1>Ungültige Nutzerdaten.</h1>
2
+ <p>Das Authentifizierungssytem hat ungültige Benutzerdaten geliefert. Bitte informieren Sie den Administrator.</p>
@@ -0,0 +1,3 @@
1
+ <%= form_tag('/auth/heimdall', method: 'post', data: {turbo: false}) do %>
2
+ <button type='submit'>Login</button>
3
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <h1>Nicht genügend Rechte.</h1>
2
+ <p>Sie verfügen leider nicht über genügend Rechte um diese Seite zu öffnen. Bei Fragen wenden Sie sich an Ihren Administrator.</p>
@@ -0,0 +1,48 @@
1
+ module HeimdallAuth
2
+ module AuthenticationAdditions
3
+ def current_ability
4
+ @current_ability ||= Ability.new(current_user)
5
+ end
6
+
7
+ def store_location_in_session
8
+ session[:last_url] = request.url if storable_location?
9
+ ::Rails.logger.info("\033[32m session[:last_url] = #{session[:last_url]} \033[0m")
10
+ end
11
+
12
+ def storable_location?
13
+ request.get? && request.format.try(:ref) == :html && !is_a?(SessionsController) && !request.xhr?
14
+ end
15
+
16
+ def current_access_token
17
+ request.session[:access_token] || params[:access_token] || request.headers['HeimdallAccessToken']
18
+ end
19
+
20
+ def current_user
21
+ begin
22
+ @current_user ||= get_user_from_auth_server(current_access_token)
23
+ rescue NoMethodError => e
24
+ User.new(is_invalid: true)
25
+ rescue Exception => e
26
+ nil
27
+ end
28
+ end
29
+
30
+ def current_environment
31
+ begin
32
+ @current_environment ||= current_user.app_environment || params[:environment]
33
+ rescue NoMethodError, Exception => e
34
+ nil
35
+ end
36
+ end
37
+
38
+ def get_user_from_auth_server(access_token)
39
+ client = OAuth2::Client.new(ENV['HEIMDALL_APPLICATION_ID'], ENV['HEIMDALL_APPLICATION_SECRET'], :site => ENV['HEIMDALL_SERVER_URL'])
40
+ user_data = OAuth2::AccessToken.new(client,access_token).get('/me.json').parsed
41
+ User.new(user_data)
42
+ end
43
+
44
+ def user_signed_in?
45
+ return true if current_user
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ require "cancancan"
3
+ require "heimdall_auth/authentication_additions"
4
+
5
+ module HeimdallAuth
6
+ # This module is automatically included into all controllers.
7
+ # It adds methods like current_user but also handles auth-failure redirections
8
+ module ControllerAdditions
9
+ include HeimdallAuth::AuthenticationAdditions
10
+
11
+ def self.included(base)
12
+ base.helper_method :current_user, :current_access_token, :current_environment, :user_signed_in? if base.respond_to? :helper_method
13
+ base.before_action :store_location_in_session
14
+
15
+ base.rescue_from CanCan::AccessDenied do |exception|
16
+ user_token = params[:user_token].presence
17
+
18
+ respond_to do |format|
19
+ format.json { head :forbidden, content_type: 'text/html' }
20
+ format.html {
21
+ if current_user.nil?
22
+ redirect_to new_user_session_path({user_token: user_token})
23
+ elsif current_user.is_invalid
24
+ render 'application/invalid_user_data'
25
+ else
26
+ render 'application/not_enough_rights'
27
+ end
28
+ }
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+
36
+ if defined? ActiveSupport
37
+ ActiveSupport.on_load(:action_controller) do
38
+ include CanCan::ControllerAdditions
39
+ include HeimdallAuth::ControllerAdditions
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ module HeimdallAuth
2
+ class Engine < Rails::Engine
3
+ initializer "heimdall_auth.routes" do
4
+ HeimdallAuth::Rails::Routes.install!
5
+ end
6
+
7
+ initializer "heimdall_auth.middleware" do |app|
8
+ unless [ENV['HEIMDALL_SERVER_URL'], ENV['HEIMDALL_APPLICATION_ID'], ENV['HEIMDALL_APPLICATION_SECRET']].any? &:nil?
9
+ app.config.middleware.use OmniAuth::Builder do
10
+ provider :heimdall,
11
+ ENV['HEIMDALL_APPLICATION_ID'],
12
+ ENV['HEIMDALL_APPLICATION_SECRET'],
13
+ client_options: {
14
+ site: ENV['HEIMDALL_SERVER_URL']
15
+ }
16
+ end
17
+ else
18
+ warn_missing_config
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def warn_missing_config
25
+ puts "Heimdall configuration is missing. Set the follwing ENV-Variables: HEIMDALL_SERVER_URL, HEIMDALL_APPLICATION_ID and HEIMDALL_APPLICATION_SECRET. You might execute `rails heimdall:register -- -u'rene@vesputi.com' -p'YourHeimdallPassword' >> .env`"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ module HeimdallAuth
2
+ module Rails
3
+ class Routes
4
+ module Helper
5
+ def use_heimdall_auth(options = {}, &block)
6
+ get '/auth/:provider' => 'heimdall_auth/sessions#login_button', :as => :auth_provider
7
+ get '/auth/:provider/callback' => 'heimdall_auth/sessions#create', :as => :auth_provider_callback
8
+ get '/auth/failure' => 'heimdall_auth/sessions#failure'
9
+ get '/signin' => 'heimdall_auth/sessions#new', :as => :new_user_session
10
+ get '/signout' => 'heimdall_auth/sessions#destroy', :as => :destroy_user_session
11
+ end
12
+
13
+
14
+ def mount_heimdall_auth_secured(options = {}, &block)
15
+ accessible_via_token = options.extract!(:accessible_via_token)[:accessible_via_token]
16
+
17
+ engine = options.keys.first #Syntax sugar ENGINE => PATH, ACTION => RESOURCE
18
+ path = options.values.first #Syntax sugar ENGINE => PATH, ACTION => RESOURCE
19
+
20
+ action = options.keys.second #Syntax sugar ENGINE => PATH, ACTION => RESOURCE
21
+ resource = options.values.second #Syntax sugar ENGINE => PATH, ACTION => RESOURCE
22
+
23
+ if action.nil? || resource.nil?
24
+ puts "WARNING: It seems you missed the cancancan rights. Use: `mount_heimdall_auth_secured Sidekiq::Web => '/sidekiq', :manage => :sidekiq`"
25
+ end
26
+
27
+ mount engine => path, constraints: HeimdallAuth::RouteConstraint.new(action, resource, accessible_via_token)
28
+ get "#{path}", to: redirect('/signin')
29
+ get "#{path}/*rest", to: redirect('/signin')
30
+ end
31
+ end
32
+
33
+ def self.install!
34
+ ActionDispatch::Routing::Mapper.send :include, HeimdallAuth::Rails::Routes::Helper
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,4 @@
1
+ module HeimdallAuth
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,57 @@
1
+ module HeimdallAuth
2
+
3
+ class AuthenticationChecker
4
+ include HeimdallAuth::AuthenticationAdditions
5
+
6
+ def initialize(request)
7
+ @request = request
8
+ end
9
+
10
+ def request #This allowes the methods in AuthenticationAdditions to use to usually global request
11
+ @request
12
+ end
13
+
14
+ def session #This allowes the methods in AuthenticationAdditions to use to usually global request
15
+ @request.session
16
+ end
17
+
18
+ def can?(action, resource)
19
+ store_location_in_session
20
+ if current_user
21
+ if current_ability.can?(action, resource)
22
+ return true
23
+ else
24
+ session[:last_url] = request.base_url #prevent a redirection loop if users do not have enough rights. So send her to the base_url
25
+ return false
26
+ end
27
+ else
28
+ return false
29
+ end
30
+ end
31
+ end
32
+
33
+ class RouteConstraint
34
+
35
+ def initialize(action, resource, accessible_via_token)
36
+ @action = action
37
+ @resource = resource
38
+ @accessible_via_token = accessible_via_token
39
+ end
40
+
41
+ def matches?(matching_request)
42
+ if @accessible_via_token && matching_request.query_parameters["token"]
43
+ @accessible_via_token.keys.each do |path|
44
+ if path.to_s == matching_request.path.to_s
45
+ expected_token = @accessible_via_token[path]
46
+ if expected_token && ActiveSupport::SecurityUtils.secure_compare(matching_request.query_parameters["token"], expected_token)
47
+ return true
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ AuthenticationChecker.new(matching_request).can?(@action, @resource)
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,29 @@
1
+ class HeimdallAuth::User
2
+ include ActiveModel::Conversion
3
+ extend ActiveModel::Naming
4
+
5
+ attr_accessor :is_invalid
6
+ attr_accessor :id, :name, :app_type, :app_environment, :app_id, :email, :is_editor, :is_operator, :is_admin, :is_user_admin, :is_police, :is_ride_on_demand_provider, :is_ride_on_demand_accounting, :raw_data
7
+
8
+ def initialize(attributes = {})
9
+ attributes.each do |name, value|
10
+ setter_method = "#{name}="
11
+ send(setter_method, value) if self.respond_to? setter_method
12
+ end
13
+ self.raw_data = attributes.to_json
14
+ end
15
+
16
+ def key_type
17
+ Rails.logger.warn("key_type is deprecated, please use app_type")
18
+ app_type
19
+ end
20
+
21
+ def key_environment
22
+ Rails.logger.warn("key_environment is deprecated, please use app_environment")
23
+ app_environment
24
+ end
25
+
26
+ def persisted?
27
+ false
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module HeimdallAuth
2
+ VERSION = '2.0.0'
3
+ end
@@ -0,0 +1,16 @@
1
+ require "heimdall_auth/railtie" if defined?(Rails)
2
+
3
+ require "heimdall_auth/engine"
4
+ require "heimdall_auth/rails/routes"
5
+
6
+ require "heimdall_auth/user"
7
+ require "omniauth/stategies/heimdall"
8
+
9
+ require "heimdall_auth/authentication_additions"
10
+ require "heimdall_auth/controller_additions"
11
+
12
+ require "heimdall_auth/route_constraint"
13
+
14
+ module HeimdallAuthBw
15
+ # Your code goes here...
16
+ end
@@ -0,0 +1,47 @@
1
+ require 'omniauth-oauth2'
2
+ require 'omniauth/rails_csrf_protection'
3
+
4
+ module OmniAuth
5
+ module Strategies
6
+ class Heimdall < OmniAuth::Strategies::OAuth2
7
+ option :name, :heimdall
8
+
9
+ uid {
10
+ raw_info['id']
11
+ }
12
+
13
+ info do
14
+ {
15
+ name: raw_info['name'],
16
+ email: raw_info['email'],
17
+ }
18
+ end
19
+
20
+ extra do
21
+ { raw_info: raw_info }
22
+ end
23
+
24
+ def raw_info
25
+ @raw_info ||= access_token.get('/me.json').parsed
26
+ end
27
+
28
+ def callback_url
29
+ # If redirect_uri is configured in token_params, use that
30
+ # value.
31
+ token_params.to_hash(:symbolize_keys => true)[:redirect_uri] || super
32
+ end
33
+
34
+ def query_string
35
+ # This method is called by callback_url, only if redirect_uri
36
+ # is omitted in token_params.
37
+ if request.params["code"]
38
+ # If this is a callback, ignore query parameters added by
39
+ # the provider.
40
+ ""
41
+ else
42
+ super
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,12 @@
1
+ namespace :puma_dev do
2
+ desc 'Fast linking to puma dev'
3
+ task :link do
4
+
5
+ application_name = Rails.application.class.try(:parent_name) || Rails.application.class.try(:module_parent_name)
6
+ puma_dev_app_name = "#{application_name.underscore.dasherize}.vesputi-abc"
7
+ command = "ln -s #{Rails.root} ~/.puma-dev/#{puma_dev_app_name}"
8
+
9
+ puts "Script is linking to puma-dev"
10
+ sh command
11
+ end
12
+ end
@@ -0,0 +1,84 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'json'
4
+ require 'optparse'
5
+
6
+ namespace :heimdall do
7
+ desc 'Register application at a Heimdall Application'
8
+ task :register do
9
+
10
+ application_name = Rails.application.class.try(:parent_name) || Rails.application.class.try(:module_parent_name)
11
+
12
+ options = {
13
+ application_name: application_name,
14
+ service_url: "https://#{application_name.underscore.dasherize}.vesputi-abc.de",
15
+ heimdall_url: "https://heimdall.vesputi-abc.de",
16
+ }
17
+ option_parser = OptionParser.new
18
+ option_parser.banner = "Usage: rake add [options]"
19
+ option_parser.on("-h", "--heimdall ARG", String) { |heimdall_url| options[:heimdall_url] = heimdall_url }
20
+ option_parser.on("-s", "--service ARG", String) { |service_url| options[:service_url] = service_url }
21
+ option_parser.on("-u", "--username ARG", String) { |username| options[:username] = username }
22
+ option_parser.on("-p", "--password ARG", String) { |password| options[:password] = password }
23
+
24
+ args = option_parser.order!(ARGV) {}
25
+ option_parser.parse!(args)
26
+
27
+ #TODO: strip the trialing slash ... if there is one
28
+ credentials = create_oauth_application_request(
29
+ options[:heimdall_url],
30
+ options[:service_url],
31
+ "#{options[:application_name]} | (Registered at #{DateTime.current.to_formatted_s(:long)})",
32
+ options[:username],
33
+ options[:password]
34
+ )
35
+
36
+ if credentials
37
+ STDERR.puts "## Sucessfully registered as '#{options[:application_name]}'"
38
+ STDERR.puts "# Heimdall URL as '#{options[:heimdall_url]}' (change it with -h\"https://heimdall.any-whe.re/\")"
39
+ STDERR.puts "# Service URL as '#{options[:service_url]}' (change it with -s\"https://foo.bar/\")"
40
+ puts "HEIMDALL_SERVER_URL=#{options[:heimdall_url]}/"
41
+ puts "HEIMDALL_APPLICATION_ID=#{credentials['uid']}"
42
+ puts "HEIMDALL_APPLICATION_SECRET=#{credentials['secret']}"
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+ def create_oauth_application_request(heimdall_url, application_url, application_name, heimdall_username, heimdall_password)
49
+ uri = URI("#{heimdall_url}/oauth_applications_api.json")
50
+
51
+ # Create client
52
+ http = Net::HTTP.new(uri.host, uri.port)
53
+ http.use_ssl = true
54
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
55
+ dict = {
56
+ "oauth_application" => {
57
+ "name" => "#{application_name}",
58
+ "redirect_uri" =>
59
+ "#{application_url}/auth/heimdall/callback\n" +
60
+ "#{application_url}/auth/heimdall/callback/"
61
+ }
62
+ }
63
+ body = JSON.dump(dict)
64
+
65
+ # Create Request
66
+ req = Net::HTTP::Post.new(uri)
67
+ # Add headers
68
+ req.add_field "Authorization", "Basic #{Base64.strict_encode64("#{heimdall_username}:#{heimdall_password}")}"
69
+ # Add headers
70
+ req.add_field "Content-Type", "application/json; charset=utf-8"
71
+ # Set body
72
+ req.body = body
73
+
74
+ # Fetch Request
75
+ res = http.request(req)
76
+
77
+ if res.code == "201"
78
+ return JSON.parse(res.body)
79
+ else
80
+ STDERR.puts "Can't Register \n\n Code #{res.code} Body: #{res.body}"
81
+ end
82
+ rescue StandardError => e
83
+ STDERR.puts "HTTP Request failed (#{e.message})"
84
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heimdall_auth_bw
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - René Meye
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '5.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '5.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: omniauth
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: omniauth-oauth2
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: omniauth-rails_csrf_protection
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: cancancan
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: sqlite3
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ description: Description of HeimdallAuth.
97
+ email:
98
+ - rene@meye.md
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - MIT-LICENSE
104
+ - README.md
105
+ - Rakefile
106
+ - app/controllers/heimdall_auth/sessions_controller.rb
107
+ - lib/generators/heimdall_auth/cancan/cancan_generator.rb
108
+ - lib/generators/heimdall_auth/cancan/templates/ability.rb
109
+ - lib/generators/heimdall_auth/dotenv/dotenv_generator.rb
110
+ - lib/generators/heimdall_auth/dotenv/templates/dot-env.example
111
+ - lib/generators/heimdall_auth/install/install_generator.rb
112
+ - lib/generators/heimdall_auth/sessions/sessions_generator.rb
113
+ - lib/generators/heimdall_auth/standard_pages/standard_pages_generator.rb
114
+ - lib/generators/heimdall_auth/standard_pages/templates/admin_controller.rb
115
+ - lib/generators/heimdall_auth/standard_pages/templates/admin_view.html.erb
116
+ - lib/generators/heimdall_auth/standard_pages/templates/invalid_user_data.html.erb
117
+ - lib/generators/heimdall_auth/standard_pages/templates/login_button.html.erb
118
+ - lib/generators/heimdall_auth/standard_pages/templates/not_enough_rights.html.erb
119
+ - lib/heimdall_auth/authentication_additions.rb
120
+ - lib/heimdall_auth/controller_additions.rb
121
+ - lib/heimdall_auth/engine.rb
122
+ - lib/heimdall_auth/rails/routes.rb
123
+ - lib/heimdall_auth/railtie.rb
124
+ - lib/heimdall_auth/route_constraint.rb
125
+ - lib/heimdall_auth/user.rb
126
+ - lib/heimdall_auth/version.rb
127
+ - lib/heimdall_auth_bw.rb
128
+ - lib/omniauth/stategies/heimdall.rb
129
+ - lib/tasks/puma_dev_link.rake
130
+ - lib/tasks/register.rake
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubygems_version: 3.6.7
149
+ specification_version: 4
150
+ summary: Summary of HeimdallAuth.
151
+ test_files: []