obscured-doorman 0.4.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 +7 -0
- data/.codeclimate.yml +28 -0
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/publish.yml +44 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +14 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.simplecov +6 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +144 -0
- data/README.md +115 -0
- data/lib/obscured-doorman.rb +69 -0
- data/lib/obscured-doorman/base.rb +203 -0
- data/lib/obscured-doorman/configuration.rb +123 -0
- data/lib/obscured-doorman/errors.rb +44 -0
- data/lib/obscured-doorman/helpers.rb +66 -0
- data/lib/obscured-doorman/loggable.rb +51 -0
- data/lib/obscured-doorman/mailer.rb +46 -0
- data/lib/obscured-doorman/messages.rb +30 -0
- data/lib/obscured-doorman/models/token.rb +57 -0
- data/lib/obscured-doorman/models/user.rb +160 -0
- data/lib/obscured-doorman/providers/base/configuration.rb +69 -0
- data/lib/obscured-doorman/providers/bitbucket.rb +79 -0
- data/lib/obscured-doorman/providers/bitbucket/access_token.rb +27 -0
- data/lib/obscured-doorman/providers/bitbucket/configuration.rb +38 -0
- data/lib/obscured-doorman/providers/bitbucket/messages.rb +13 -0
- data/lib/obscured-doorman/providers/bitbucket/strategy.rb +53 -0
- data/lib/obscured-doorman/providers/github.rb +78 -0
- data/lib/obscured-doorman/providers/github/access_token.rb +23 -0
- data/lib/obscured-doorman/providers/github/configuration.rb +38 -0
- data/lib/obscured-doorman/providers/github/messages.rb +13 -0
- data/lib/obscured-doorman/providers/github/strategy.rb +53 -0
- data/lib/obscured-doorman/strategies/forgot_password.rb +157 -0
- data/lib/obscured-doorman/strategies/password.rb +38 -0
- data/lib/obscured-doorman/strategies/remember_me.rb +54 -0
- data/lib/obscured-doorman/utilities/roles.rb +11 -0
- data/lib/obscured-doorman/utilities/types.rb +14 -0
- data/lib/obscured-doorman/version.rb +7 -0
- data/obscured-doorman.gemspec +42 -0
- data/spec/config/mongoid.yml +11 -0
- data/spec/doorman_spec.rb +203 -0
- data/spec/errors_spec.rb +11 -0
- data/spec/factories/token_factory.rb +8 -0
- data/spec/factories/user_factory.rb +12 -0
- data/spec/helpers/application_helper.rb +52 -0
- data/spec/helpers/request_helper.rb +53 -0
- data/spec/loggable_spec.rb +27 -0
- data/spec/mailer_spec.rb +26 -0
- data/spec/matchers/time.rb +7 -0
- data/spec/setup.rb +58 -0
- data/spec/token_spec.rb +62 -0
- data/spec/user_spec.rb +151 -0
- metadata +361 -0
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'bcrypt'
         | 
| 4 | 
            +
            require 'geocoder'
         | 
| 5 | 
            +
            require 'haml'
         | 
| 6 | 
            +
            require 'mail'
         | 
| 7 | 
            +
            require 'mongoid'
         | 
| 8 | 
            +
            require 'sinatra'
         | 
| 9 | 
            +
            require 'sinatra/contrib'
         | 
| 10 | 
            +
            require 'sinatra/flash'
         | 
| 11 | 
            +
            require 'sinatra/partial'
         | 
| 12 | 
            +
            require 'rack'
         | 
| 13 | 
            +
            require 'rack/contrib'
         | 
| 14 | 
            +
            require 'rack/contrib/cookies'
         | 
| 15 | 
            +
            require 'rest-client'
         | 
| 16 | 
            +
            require 'warden'
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            require 'obscured-doorman/loggable'
         | 
| 19 | 
            +
            require 'obscured-doorman/configuration'
         | 
| 20 | 
            +
            require 'obscured-doorman/errors'
         | 
| 21 | 
            +
            require 'obscured-doorman/providers/bitbucket'
         | 
| 22 | 
            +
            require 'obscured-doorman/providers/github'
         | 
| 23 | 
            +
            require 'obscured-doorman/strategies/password'
         | 
| 24 | 
            +
            require 'obscured-doorman/strategies/forgot_password'
         | 
| 25 | 
            +
            require 'obscured-doorman/strategies/remember_me'
         | 
| 26 | 
            +
            require 'obscured-doorman/utilities/roles'
         | 
| 27 | 
            +
            require 'obscured-doorman/utilities/types'
         | 
| 28 | 
            +
            require 'obscured-doorman/helpers'
         | 
| 29 | 
            +
            require 'obscured-doorman/mailer'
         | 
| 30 | 
            +
            require 'obscured-doorman/messages'
         | 
| 31 | 
            +
            require 'obscured-doorman/version'
         | 
| 32 | 
            +
            require 'obscured-doorman/base'
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            module Obscured
         | 
| 35 | 
            +
              module Doorman
         | 
| 36 | 
            +
                extend Loggable
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                class << self
         | 
| 39 | 
            +
                  # Configuration Object (instance of Obscured::Doorman::Configuration)
         | 
| 40 | 
            +
                  attr_writer :configuration
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  ##
         | 
| 43 | 
            +
                  # Configuration options should be set by passing a hash:
         | 
| 44 | 
            +
                  #
         | 
| 45 | 
            +
                  #   Obscured::Doorman.setup do |cfg|
         | 
| 46 | 
            +
                  #     cfg.confirmation   = false,
         | 
| 47 | 
            +
                  #     cfg.registration   = true,
         | 
| 48 | 
            +
                  #     cfg.smtp_domain    = 'domain.tld',
         | 
| 49 | 
            +
                  #     cfg.smtp_username  = 'username',
         | 
| 50 | 
            +
                  #     cfg.smtp_password  = 'password',
         | 
| 51 | 
            +
                  #   end
         | 
| 52 | 
            +
                  #
         | 
| 53 | 
            +
                  def setup
         | 
| 54 | 
            +
                    yield(configuration)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    require 'obscured-doorman/models/user'
         | 
| 57 | 
            +
                    require 'obscured-doorman/models/token'
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def configuration
         | 
| 61 | 
            +
                    @configuration ||= Configuration.new
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  def default_configuration
         | 
| 65 | 
            +
                    configuration.defaults
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -0,0 +1,203 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Obscured
         | 
| 4 | 
            +
              module Doorman
         | 
| 5 | 
            +
                class Warden::SessionSerializer
         | 
| 6 | 
            +
                  def serialize(user)
         | 
| 7 | 
            +
                    user.id
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def deserialize(id)
         | 
| 11 | 
            +
                    User.find(id)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                module Base
         | 
| 16 | 
            +
                  module Helpers
         | 
| 17 | 
            +
                    # Generates a flash message by trying to fetch a default message,
         | 
| 18 | 
            +
                    # if that fails just pass the message
         | 
| 19 | 
            +
                    def notify(type, message)
         | 
| 20 | 
            +
                      message = Doorman::MESSAGES[message] if message.is_a?(Symbol)
         | 
| 21 | 
            +
                      flash[type] = message
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    # Generates a url for confirm account or reset password
         | 
| 25 | 
            +
                    def token_link(action, token)
         | 
| 26 | 
            +
                      "http://#{env['HTTP_HOST']}/doorman/#{action}/#{token}"
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def self.registered(app)
         | 
| 31 | 
            +
                    app.helpers Doorman::Base::Helpers
         | 
| 32 | 
            +
                    app.helpers Doorman::Helpers
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    # Enable Sessions
         | 
| 35 | 
            +
                    app.set :sessions, true unless defined?(Rack::Session::Cookie)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    app.use Warden::Manager do |config|
         | 
| 38 | 
            +
                      config.scope_defaults :default, action: '/doorman/unauthenticated'
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                      config.failure_app = lambda { |_env|
         | 
| 41 | 
            +
                        notify :error, Doorman[:auth_required]
         | 
| 42 | 
            +
                        [302, { 'Location' => Doorman.configuration.paths[:login] }, ['']]
         | 
| 43 | 
            +
                      }
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    Warden::Manager.before_failure do |env, _opts|
         | 
| 47 | 
            +
                      # Because authentication failure can happen on any request but
         | 
| 48 | 
            +
                      # we handle it only under "post '/doorman/unauthenticated'",
         | 
| 49 | 
            +
                      # we need o change request to POST
         | 
| 50 | 
            +
                      env['REQUEST_METHOD'] = 'POST'
         | 
| 51 | 
            +
                      # And we need to do the following to work with  Rack::MethodOverride
         | 
| 52 | 
            +
                      env.each do |key, _value|
         | 
| 53 | 
            +
                        env[key]['_method'] = 'post' if key == 'rack.request.form_hash'
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                    Warden::Strategies.add(:password, Doorman::Strategies::Password)
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    app.post '/doorman/unauthenticated' do
         | 
| 59 | 
            +
                      status 401
         | 
| 60 | 
            +
                      session[:return_to] = env['warden.options'][:attempted_path] if session[:return_to].nil?
         | 
| 61 | 
            +
                      redirect(Doorman.configuration.paths[:login])
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    app.get '/doorman/register/?' do
         | 
| 65 | 
            +
                      redirect(Doorman.configuration.paths[:success]) if authenticated?
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                      unless Doorman.configuration.registration
         | 
| 68 | 
            +
                        notify :error, :signup_disabled
         | 
| 69 | 
            +
                        redirect(Doorman.configuration.paths[:login])
         | 
| 70 | 
            +
                      end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                      haml :register
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    app.post '/doorman/register' do
         | 
| 76 | 
            +
                      redirect(Doorman.configuration.paths[:success]) if authenticated?
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      unless Doorman.configuration[:registration]
         | 
| 79 | 
            +
                        notify :error, :signup_disabled
         | 
| 80 | 
            +
                        redirect(Doorman.configuration.paths[:login])
         | 
| 81 | 
            +
                      end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                      begin
         | 
| 84 | 
            +
                        if User.registered?(params[:user][:username])
         | 
| 85 | 
            +
                          notify :error, :register_account_exists
         | 
| 86 | 
            +
                          redirect(Doorman.configuration.paths[:login])
         | 
| 87 | 
            +
                        end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                        user = User.make(
         | 
| 90 | 
            +
                          username: params[:user][:username],
         | 
| 91 | 
            +
                          password: params[:user][:password],
         | 
| 92 | 
            +
                          confirmed: !Doorman.configuration[:confirmation]
         | 
| 93 | 
            +
                        )
         | 
| 94 | 
            +
                        user.name = {
         | 
| 95 | 
            +
                          first_name: params[:user][:first_name],
         | 
| 96 | 
            +
                          last_name: params[:user][:last_name]
         | 
| 97 | 
            +
                        }
         | 
| 98 | 
            +
                        user.save
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                        if Doorman.configuration[:confirmation]
         | 
| 101 | 
            +
                          token = user.confirm if Doorman.configuration[:confirmation]
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                          if File.exist?('views/doorman/templates/account_activation.haml')
         | 
| 104 | 
            +
                            template = haml :'/templates/account_activation', layout: false, locals: {
         | 
| 105 | 
            +
                              user: user.username,
         | 
| 106 | 
            +
                              link: token_link('confirm', token.token)
         | 
| 107 | 
            +
                            }
         | 
| 108 | 
            +
                            Doorman::Mailer.new(
         | 
| 109 | 
            +
                              to: user.username,
         | 
| 110 | 
            +
                              subject: 'Account activation request',
         | 
| 111 | 
            +
                              text: "You have to activate your account (#{user.username}) before using this service. " + token_link('confirm', token.token),
         | 
| 112 | 
            +
                              html: template
         | 
| 113 | 
            +
                            ).deliver!
         | 
| 114 | 
            +
                          else
         | 
| 115 | 
            +
                            Doorman.logger.warn "Template not found (views/doorman/templates/account_activation.haml), account activation at #{token_link('confirm', token.token)}"
         | 
| 116 | 
            +
                          end
         | 
| 117 | 
            +
                        end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                        # Login when registration is completed
         | 
| 120 | 
            +
                        warden.authenticate(:password)
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                        # Set cookie
         | 
| 123 | 
            +
                        cookies[:email] = params[:user][:username]
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                        notify :success, :signup_success
         | 
| 126 | 
            +
                        redirect(Doorman.configuration.paths[:success])
         | 
| 127 | 
            +
                      rescue => e
         | 
| 128 | 
            +
                        notify :error, e.message
         | 
| 129 | 
            +
                        redirect(Doorman.configuration.paths[:login])
         | 
| 130 | 
            +
                      end
         | 
| 131 | 
            +
                    end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                    app.get '/doorman/confirm/:token/?' do
         | 
| 134 | 
            +
                      redirect(Doorman.configuration.paths[:success]) if authenticated?
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                      if params[:token].nil? || params[:token].empty?
         | 
| 137 | 
            +
                        notify :error, :token_not_found
         | 
| 138 | 
            +
                        redirect(back)
         | 
| 139 | 
            +
                      end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                      token = Token.where(token: params[:token]).first
         | 
| 142 | 
            +
                      if token.nil? && !token&.type.eql?(:confirm)
         | 
| 143 | 
            +
                        notify :error, :token_not_found
         | 
| 144 | 
            +
                        redirect(back)
         | 
| 145 | 
            +
                      end
         | 
| 146 | 
            +
                      if token&.used?
         | 
| 147 | 
            +
                        notify :error, :token_used
         | 
| 148 | 
            +
                        redirect(back)
         | 
| 149 | 
            +
                      end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                      user = token&.user
         | 
| 152 | 
            +
                      if user.nil?
         | 
| 153 | 
            +
                        notify :error, :confirm_no_user
         | 
| 154 | 
            +
                        redirect(Doorman.config.paths[:login])
         | 
| 155 | 
            +
                      end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                      user&.confirm!
         | 
| 158 | 
            +
                      notify :success, :confirm_success
         | 
| 159 | 
            +
                      redirect(Doorman.configuration.paths[:login])
         | 
| 160 | 
            +
                    end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                    app.get '/doorman/login/?' do
         | 
| 163 | 
            +
                      redirect(Doorman.configuration.paths[:success]) if authenticated?
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                      email = cookies[:email]
         | 
| 166 | 
            +
                      email = params[:email] if email.nil?
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                      haml :login, locals: { email: email }
         | 
| 169 | 
            +
                    end
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                    app.post '/doorman/login' do
         | 
| 172 | 
            +
                      warden.authenticate(:password)
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                      # Set cookie
         | 
| 175 | 
            +
                      cookies[:email] = params[:user][:username]
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                      # Notify if there are any messages from Warden.
         | 
| 178 | 
            +
                      notify :error, warden.message unless warden.message.blank?
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                      redirect(Doorman.configuration.use_referrer && session[:return_to] ? session.delete(:return_to) : Doorman.configuration.paths[:success])
         | 
| 181 | 
            +
                    end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                    app.get '/doorman/logout/?' do
         | 
| 184 | 
            +
                      warden.logout(:default)
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                      notify :success, :logout_success
         | 
| 187 | 
            +
                      redirect(Doorman.configuration.paths[:login])
         | 
| 188 | 
            +
                    end
         | 
| 189 | 
            +
                  end
         | 
| 190 | 
            +
                end
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                class Middleware < Sinatra::Base
         | 
| 193 | 
            +
                  helpers Sinatra::Cookies
         | 
| 194 | 
            +
                  register Sinatra::Flash
         | 
| 195 | 
            +
                  register Sinatra::Partial
         | 
| 196 | 
            +
                  register Strategies::ForgotPassword
         | 
| 197 | 
            +
                  register Strategies::RememberMe
         | 
| 198 | 
            +
                  register Doorman::Base
         | 
| 199 | 
            +
                  register Doorman::Providers::Bitbucket
         | 
| 200 | 
            +
                  register Doorman::Providers::GitHub
         | 
| 201 | 
            +
                end
         | 
| 202 | 
            +
              end
         | 
| 203 | 
            +
            end
         | 
| @@ -0,0 +1,123 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Obscured
         | 
| 4 | 
            +
              module Doorman
         | 
| 5 | 
            +
                class Configuration
         | 
| 6 | 
            +
                  def self.config_option(name)
         | 
| 7 | 
            +
                    define_method(name) do
         | 
| 8 | 
            +
                      read_value(name)
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    define_method("#{name}=") do |value|
         | 
| 12 | 
            +
                      set_value(name, value)
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  #def self.proc_config_option(name)
         | 
| 17 | 
            +
                  #  define_method(name) do |&block|
         | 
| 18 | 
            +
                  #    set_value(name, block) unless block.nil?
         | 
| 19 | 
            +
                  #    read_value(name)
         | 
| 20 | 
            +
                  #  end
         | 
| 21 | 
            +
                  #
         | 
| 22 | 
            +
                  #  define_method("#{name}=") do |value|
         | 
| 23 | 
            +
                  #    set_value(name, value)
         | 
| 24 | 
            +
                  #  end
         | 
| 25 | 
            +
                  #end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # Set log level
         | 
| 28 | 
            +
                  config_option :log_level
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  # Enables/disables user confirmation
         | 
| 31 | 
            +
                  config_option :confirmation
         | 
| 32 | 
            +
                  # Enables/disables user registration
         | 
| 33 | 
            +
                  config_option :registration
         | 
| 34 | 
            +
                  # Enables/disables the usage of referrer redirection
         | 
| 35 | 
            +
                  config_option :use_referrer
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  # Remember me cookie name
         | 
| 38 | 
            +
                  config_option :remember_cookie
         | 
| 39 | 
            +
                  # Remember me for x-days
         | 
| 40 | 
            +
                  config_option :remember_for
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  # Database name
         | 
| 43 | 
            +
                  config_option :db_name
         | 
| 44 | 
            +
                  # Database client
         | 
| 45 | 
            +
                  config_option :db_client
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # SMTP Domain
         | 
| 48 | 
            +
                  config_option :smtp_domain
         | 
| 49 | 
            +
                  # SMTP Server
         | 
| 50 | 
            +
                  config_option :smtp_server
         | 
| 51 | 
            +
                  # SMTP Server PSort
         | 
| 52 | 
            +
                  config_option :smtp_port
         | 
| 53 | 
            +
                  # SMTP Sender Username
         | 
| 54 | 
            +
                  config_option :smtp_username
         | 
| 55 | 
            +
                  # SMTP Sender Password
         | 
| 56 | 
            +
                  config_option :smtp_password
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  # Authentication Providers
         | 
| 59 | 
            +
                  config_option :providers
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  # Authentication Providers
         | 
| 62 | 
            +
                  config_option :paths
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  attr_reader :defaults
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  def initialize
         | 
| 67 | 
            +
                    @config_values = {}
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    # set default attribute values
         | 
| 70 | 
            +
                    @defaults = _defaults
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  def [](key)
         | 
| 74 | 
            +
                    read_value(key)
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  def []=(key, value)
         | 
| 78 | 
            +
                    set_value(key, value)
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  private
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  def read_value(name)
         | 
| 84 | 
            +
                    if @config_values.key?(name)
         | 
| 85 | 
            +
                      @config_values[name]
         | 
| 86 | 
            +
                    else
         | 
| 87 | 
            +
                      @defaults.send(name)
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  def set_value(name, value)
         | 
| 92 | 
            +
                    @config_values[name] = value
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  def _defaults
         | 
| 96 | 
            +
                    OpenStruct.new(
         | 
| 97 | 
            +
                      log_level: Logger::DEBUG,
         | 
| 98 | 
            +
                      confirmation: false,
         | 
| 99 | 
            +
                      registration: false,
         | 
| 100 | 
            +
                      use_referrer: true,
         | 
| 101 | 
            +
                      remember_cookie: 'sinatra.doorman.remember',
         | 
| 102 | 
            +
                      remember_for: 30,
         | 
| 103 | 
            +
                      db_name: 'doorman',
         | 
| 104 | 
            +
                      db_client: :doorman,
         | 
| 105 | 
            +
                      smtp_domain: 'doorman.local',
         | 
| 106 | 
            +
                      smtp_server: '127.0.0.1',
         | 
| 107 | 
            +
                      smtp_port: 587,
         | 
| 108 | 
            +
                      smtp_username: nil,
         | 
| 109 | 
            +
                      smtp_password: nil,
         | 
| 110 | 
            +
                      providers: [],
         | 
| 111 | 
            +
                      paths: {
         | 
| 112 | 
            +
                        success: '/home',
         | 
| 113 | 
            +
                        login: '/doorman/login',
         | 
| 114 | 
            +
                        logout: '/doorman/logout',
         | 
| 115 | 
            +
                        forgot: '/doorman/forgot',
         | 
| 116 | 
            +
                        reset: '/doorman/reset',
         | 
| 117 | 
            +
                        register: '/doorman/register'
         | 
| 118 | 
            +
                      }
         | 
| 119 | 
            +
                    )
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
            end
         | 
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Obscured
         | 
| 4 | 
            +
              module Doorman
         | 
| 5 | 
            +
                class Error < StandardError
         | 
| 6 | 
            +
                  attr_reader :code
         | 
| 7 | 
            +
                  attr_reader :field
         | 
| 8 | 
            +
                  attr_reader :error
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  ERRORS = {
         | 
| 11 | 
            +
                    invalid_api_method: 'No method parameter was supplied',
         | 
| 12 | 
            +
                    unspecified_error: 'Unspecified error',
         | 
| 13 | 
            +
                    already_exists: '{what}',
         | 
| 14 | 
            +
                    does_not_exist: '{what}',
         | 
| 15 | 
            +
                    does_not_match: '{what}',
         | 
| 16 | 
            +
                    account: '{what}',
         | 
| 17 | 
            +
                    invalid_date: 'Cannot parse {what} from: {date}',
         | 
| 18 | 
            +
                    invalid_type: '{what}',
         | 
| 19 | 
            +
                    not_active: 'Not active',
         | 
| 20 | 
            +
                    required_field_missing: 'Required field {field} is missing'
         | 
| 21 | 
            +
                  }.freeze
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  def initialize(code, params = {})
         | 
| 24 | 
            +
                    field = params.delete(:field)
         | 
| 25 | 
            +
                    error = params.delete(:error)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    super(parse(code, params))
         | 
| 28 | 
            +
                    @code = code || :unspecified_error
         | 
| 29 | 
            +
                    @field = field || :unspecified_field
         | 
| 30 | 
            +
                    @error = error
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  private
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def parse(code, params = {})
         | 
| 36 | 
            +
                    message = ERRORS[code]
         | 
| 37 | 
            +
                    params.each_pair do |key, value|
         | 
| 38 | 
            +
                      message = message.sub("{#{key}}", value)
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                    message
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
            end
         | 
| @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Obscured
         | 
| 4 | 
            +
              module Doorman
         | 
| 5 | 
            +
                module Helpers
         | 
| 6 | 
            +
                  # The main accessor to the warden middleware
         | 
| 7 | 
            +
                  def warden
         | 
| 8 | 
            +
                    request.env['warden']
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  # Check the current session is authenticated to a given scope
         | 
| 12 | 
            +
                  def authenticated?(scope = nil)
         | 
| 13 | 
            +
                    scope ? warden.authenticated?(scope: scope) : warden.authenticated?
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  alias logged_in? authenticated?
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # Authenticate a user against defined strategies
         | 
| 18 | 
            +
                  def authenticate(*args)
         | 
| 19 | 
            +
                    warden.authenticate!(*args)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                  alias login authenticate
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  # Return session info
         | 
| 24 | 
            +
                  #
         | 
| 25 | 
            +
                  # @param [Symbol] scope the scope to retrieve session info for
         | 
| 26 | 
            +
                  def session_info(scope = nil)
         | 
| 27 | 
            +
                    scope ? warden.session(scope) : scope
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  # Terminate the current session
         | 
| 31 | 
            +
                  #
         | 
| 32 | 
            +
                  # @param [Symbol] scopes the session scope to terminate
         | 
| 33 | 
            +
                  def logout(scopes = nil)
         | 
| 34 | 
            +
                    scopes ? warden.logout(scopes) : warden.logout(warden.config.default_scope)
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  # Access the user from the current session
         | 
| 38 | 
            +
                  #
         | 
| 39 | 
            +
                  # @param [Symbol] scope for the logged in user
         | 
| 40 | 
            +
                  def user(scope = nil)
         | 
| 41 | 
            +
                    scope ? warden.user(scope) : warden.user
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                  alias current_user user
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  # Require authorization for an action
         | 
| 46 | 
            +
                  #
         | 
| 47 | 
            +
                  # @param [String] failure_path path to redirect to if user is unauthenticated
         | 
| 48 | 
            +
                  def authorize!(failure_path = nil)
         | 
| 49 | 
            +
                    unless authenticated?
         | 
| 50 | 
            +
                      session[:return_to] = request.path if Doorman.configuration.use_referrer
         | 
| 51 | 
            +
                      redirect(failure_path || Doorman.configuration.paths[:login])
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  # Require authorization for example ajax calls, returns 403 is not authenticated
         | 
| 56 | 
            +
                  #
         | 
| 57 | 
            +
                  # @param [Symbol] format
         | 
| 58 | 
            +
                  def authorized?(format = :json)
         | 
| 59 | 
            +
                    unless authenticated?
         | 
| 60 | 
            +
                      halt 403, { 'Content-Type' => 'application/json' }, { message: 'Unauthorized' }.to_json if format == :json
         | 
| 61 | 
            +
                      halt 403
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         |