punk 0.3.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +1 -1
- data/.rubocop.yml +1091 -93
- data/.standard.yml +2 -0
- data/Gemfile +60 -60
- data/Gemfile.lock +22 -17
- data/README.md +7 -3
- data/Rakefile +9 -7
- data/VERSION +1 -1
- data/app/migrations/001_lets_punk.rb +1 -1
- data/app/routes/hello.rb +1 -1
- data/bin/punk +5 -5
- data/lib/punk.rb +7 -7
- data/lib/punk/actions/sessions/create.rb +3 -3
- data/lib/punk/actions/sessions/verify.rb +2 -2
- data/lib/punk/commands/auth.rb +4 -4
- data/lib/punk/commands/generate.rb +5 -5
- data/lib/punk/commands/http.rb +4 -4
- data/lib/punk/commands/list.rb +10 -10
- data/lib/punk/core/app.rb +41 -41
- data/lib/punk/core/boot.rb +5 -5
- data/lib/punk/core/cli.rb +3 -3
- data/lib/punk/core/commander.rb +28 -28
- data/lib/punk/core/commands.rb +8 -8
- data/lib/punk/core/env.rb +27 -27
- data/lib/punk/core/exec.rb +8 -8
- data/lib/punk/core/interface.rb +19 -19
- data/lib/punk/core/load.rb +2 -2
- data/lib/punk/core/logger.rb +3 -3
- data/lib/punk/core/monkey.rb +1 -1
- data/lib/punk/core/pry.rb +2 -2
- data/lib/punk/core/settings.rb +4 -4
- data/lib/punk/core/version.rb +1 -1
- data/lib/punk/core/worker.rb +6 -6
- data/lib/punk/framework/all.rb +8 -8
- data/lib/punk/framework/model.rb +6 -5
- data/lib/punk/framework/plugins/all.rb +1 -1
- data/lib/punk/framework/plugins/validation.rb +8 -8
- data/lib/punk/framework/service.rb +5 -3
- data/lib/punk/framework/worker.rb +3 -3
- data/lib/punk/helpers/all.rb +5 -5
- data/lib/punk/helpers/loggable.rb +3 -3
- data/lib/punk/helpers/publishable.rb +1 -1
- data/lib/punk/helpers/renderable.rb +10 -10
- data/lib/punk/helpers/validatable.rb +7 -6
- data/lib/punk/migrations/001_punk.rb +12 -12
- data/lib/punk/models/group.rb +1 -1
- data/lib/punk/models/identity.rb +1 -1
- data/lib/punk/models/session.rb +7 -7
- data/lib/punk/models/tenant.rb +1 -1
- data/lib/punk/models/user.rb +2 -2
- data/lib/punk/plugins/all.rb +2 -2
- data/lib/punk/plugins/cors.rb +2 -2
- data/lib/punk/plugins/ssl.rb +1 -1
- data/lib/punk/routes/groups.rb +1 -1
- data/lib/punk/routes/plivo.rb +1 -1
- data/lib/punk/routes/sessions.rb +2 -2
- data/lib/punk/routes/swagger.rb +2 -2
- data/lib/punk/routes/tenants.rb +1 -1
- data/lib/punk/routes/users.rb +1 -1
- data/lib/punk/services/challenge_claim.rb +5 -5
- data/lib/punk/services/generate_swagger.rb +6 -6
- data/lib/punk/services/prove_claim.rb +1 -1
- data/lib/punk/startup/cache.rb +3 -3
- data/lib/punk/startup/database.rb +4 -4
- data/lib/punk/startup/environment.rb +6 -6
- data/lib/punk/startup/logger.rb +2 -2
- data/lib/punk/startup/task.rb +5 -5
- data/lib/punk/views/fail.rb +2 -2
- data/lib/punk/views/groups/list.rb +2 -2
- data/lib/punk/views/info.rb +2 -2
- data/lib/punk/views/plivo_store.rb +2 -2
- data/lib/punk/views/sessions/list.rb +2 -2
- data/lib/punk/views/sessions/pending.rb +2 -2
- data/lib/punk/views/tenants/list.rb +2 -2
- data/lib/punk/views/users/list.rb +2 -2
- data/lib/punk/views/users/show.rb +2 -2
- data/lib/punk/workers/geocode_session_worker.rb +3 -3
- data/lib/punk/workers/identify_session_worker.rb +1 -1
- data/lib/punk/workers/send_email_worker.rb +3 -3
- data/lib/punk/workers/send_sms_worker.rb +3 -3
- data/punk.gemspec +8 -4
- data/spec/actions/groups/punk/list_groups_action_spec.rb +9 -9
- data/spec/actions/sessions/punk/clear_session_action_spec.rb +11 -11
- data/spec/actions/sessions/punk/create_session_action_spec.rb +9 -9
- data/spec/actions/sessions/punk/list_sessions_action_spec.rb +8 -8
- data/spec/actions/sessions/punk/verify_session_action_spec.rb +24 -24
- data/spec/actions/tenants/punk/list_tenants_action_spec.rb +6 -6
- data/spec/actions/users/punk/list_group_users_action_spec.rb +6 -6
- data/spec/actions/users/punk/list_tenant_users_action_spec.rb +6 -6
- data/spec/factories/group.rb +1 -1
- data/spec/factories/group_user_metadata.rb +1 -1
- data/spec/factories/identity.rb +4 -4
- data/spec/factories/session.rb +1 -1
- data/spec/factories/tenant.rb +1 -1
- data/spec/factories/tenant_user_metadata.rb +1 -1
- data/spec/factories/user.rb +1 -1
- data/spec/lib/commands/generate_spec.rb +2 -2
- data/spec/lib/commands/list_spec.rb +2 -2
- data/spec/lib/commands/swagger_spec.rb +2 -2
- data/spec/lib/engine/punk_env_spec.rb +4 -4
- data/spec/lib/engine/punk_exec_spec.rb +2 -2
- data/spec/lib/engine/punk_init_spec.rb +2 -2
- data/spec/lib/engine/punk_store_spec.rb +2 -2
- data/spec/models/punk/group_spec.rb +4 -4
- data/spec/models/punk/group_user_metadata_spec.rb +2 -2
- data/spec/models/punk/identity_spec.rb +17 -17
- data/spec/models/punk/session_spec.rb +4 -4
- data/spec/models/punk/tenant_spec.rb +3 -3
- data/spec/models/punk/tenant_user_metadata_spec.rb +2 -2
- data/spec/models/punk/user_spec.rb +9 -9
- data/spec/routes/groups/get_groups_spec.rb +4 -4
- data/spec/routes/plivo/get_plivo_spec.rb +1 -1
- data/spec/routes/sessions/delete_session_spec.rb +1 -1
- data/spec/routes/sessions/get_sessions_spec.rb +5 -5
- data/spec/routes/sessions/patch_session_spec.rb +1 -1
- data/spec/routes/sessions/post_session_spec.rb +1 -1
- data/spec/routes/swagger/get_swagger_spec.rb +1 -1
- data/spec/routes/tenants/get_tenants_spec.rb +5 -5
- data/spec/routes/users/get_users_spec.rb +6 -6
- data/spec/services/punk/challenge_claim_service_spec.rb +2 -2
- data/spec/services/punk/create_identities_service_spec.rb +1 -1
- data/spec/services/punk/generate_swagger_service_spec.rb +2 -2
- data/spec/services/punk/prove_claim_service_spec.rb +2 -2
- data/spec/services/punk/secret_service_spec.rb +2 -2
- data/spec/spec_helper.rb +27 -27
- data/spec/views/punk/plivo_store_spec.rb +2 -2
- data/spec/views/sessions/punk/list_sessions_view_spec.rb +2 -2
- data/spec/views/sessions/punk/pending_session_view_spec.rb +2 -2
- data/spec/views/tenants/punk/list_tenants_view_spec.rb +2 -2
- data/spec/views/users/punk/list_groups_view_spec.rb +2 -2
- data/spec/views/users/punk/list_users_view_spec.rb +2 -2
- data/spec/workers/punk/geocode_session_worker_spec.rb +2 -2
- data/spec/workers/punk/identify_session_worker_spec.rb +3 -3
- data/spec/workers/punk/send_email_worker_spec.rb +1 -1
- metadata +18 -3
| @@ -17,8 +17,8 @@ module PUNK | |
| 17 17 |  | 
| 18 18 | 
             
                def process
         | 
| 19 19 | 
             
                  verify = ProveClaimService.run(session: session, secret: secret)
         | 
| 20 | 
            -
                  raise BadRequest,  | 
| 21 | 
            -
                  present Info, message:  | 
| 20 | 
            +
                  raise BadRequest, "Secret is incorrect" unless verify.result == true
         | 
| 21 | 
            +
                  present Info, message: "We have succesfully verified your identity.  Welcome to GroupFire!"
         | 
| 22 22 | 
             
                end
         | 
| 23 23 | 
             
              end
         | 
| 24 24 | 
             
            end
         | 
    
        data/lib/punk/commands/auth.rb
    CHANGED
    
    | @@ -15,7 +15,7 @@ PUNK::Command.create "login" do | |
| 15 15 | 
             
                    "PATH_INFO" => "/sessions",
         | 
| 16 16 | 
             
                    "CONTENT_TYPE" => "text/json",
         | 
| 17 17 | 
             
                    "SCRIPT_NAME" => "",
         | 
| 18 | 
            -
                    "rack.input" => StringIO.new({ | 
| 18 | 
            +
                    "rack.input" => StringIO.new({claim: claim}.to_json)
         | 
| 19 19 | 
             
                  )
         | 
| 20 20 | 
             
                response = ActiveSupport::JSON.decode(response[-1].first).deep_symbolize_keys
         | 
| 21 21 | 
             
                return if response[:errors].present?
         | 
| @@ -23,17 +23,17 @@ PUNK::Command.create "login" do | |
| 23 23 | 
             
                authenticated = false
         | 
| 24 24 | 
             
                while authenticated == false
         | 
| 25 25 | 
             
                  SemanticLogger.flush
         | 
| 26 | 
            -
                  secret = ask("Secret: ") { |q| q.echo =  | 
| 26 | 
            +
                  secret = ask("Secret: ") { |q| q.echo = "*" }
         | 
| 27 27 | 
             
                  response =
         | 
| 28 28 | 
             
                    PUNK.app.call(
         | 
| 29 29 | 
             
                      "REQUEST_METHOD" => "PATCH",
         | 
| 30 30 | 
             
                      "PATH_INFO" => "/sessions/#{slug}",
         | 
| 31 31 | 
             
                      "CONTENT_TYPE" => "text/json",
         | 
| 32 32 | 
             
                      "SCRIPT_NAME" => "",
         | 
| 33 | 
            -
                      "rack.input" => StringIO.new({ | 
| 33 | 
            +
                      "rack.input" => StringIO.new({secret: secret}.to_json)
         | 
| 34 34 | 
             
                    )
         | 
| 35 35 | 
             
                  response = ActiveSupport::JSON.decode(response[-1].first).deep_symbolize_keys
         | 
| 36 | 
            -
                  break if response[:errors].present? && response[:errors].first !=  | 
| 36 | 
            +
                  break if response[:errors].present? && response[:errors].first != "Secret is incorrect"
         | 
| 37 37 | 
             
                  authenticated = response[:message].present?
         | 
| 38 38 | 
             
                end
         | 
| 39 39 | 
             
                response[:message]
         | 
| @@ -1,17 +1,17 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            PUNK::Command.create "generate" do
         | 
| 4 | 
            -
              shortcut  | 
| 4 | 
            +
              shortcut "g"
         | 
| 5 5 | 
             
              description "Generate routes, actions, models, views, services or workers"
         | 
| 6 6 |  | 
| 7 7 | 
             
              def process
         | 
| 8 | 
            -
                case args.join( | 
| 9 | 
            -
                when  | 
| 8 | 
            +
                case args.join(" ")
         | 
| 9 | 
            +
                when "route", "action", "model", "view", "service", "worker", "scaffold"
         | 
| 10 10 | 
             
                  "TBD"
         | 
| 11 | 
            -
                when  | 
| 11 | 
            +
                when "", "help"
         | 
| 12 12 | 
             
                  "? specify one of: routes, actions, models, views, services, scaffold"
         | 
| 13 13 | 
             
                else
         | 
| 14 | 
            -
                  "? unkown arguments: #{args.join( | 
| 14 | 
            +
                  "? unkown arguments: #{args.join(",")}"
         | 
| 15 15 | 
             
                end
         | 
| 16 16 | 
             
              end
         | 
| 17 17 | 
             
            end
         | 
    
        data/lib/punk/commands/http.rb
    CHANGED
    
    | @@ -4,7 +4,7 @@ PUNK::Command.create "GET" do | |
| 4 4 | 
             
              description "Perform a HTTP GET request"
         | 
| 5 5 |  | 
| 6 6 | 
             
              def process
         | 
| 7 | 
            -
                path, query = args[0].split( | 
| 7 | 
            +
                path, query = args[0].split("?")
         | 
| 8 8 | 
             
                PUNK.app.call(
         | 
| 9 9 | 
             
                  "REQUEST_METHOD" => "GET",
         | 
| 10 10 | 
             
                  "PATH_INFO" => path,
         | 
| @@ -24,7 +24,7 @@ PUNK::Command.create "PATCH" do | |
| 24 24 | 
             
                  "PATH_INFO" => args[0],
         | 
| 25 25 | 
             
                  "CONTENT_TYPE" => "text/json",
         | 
| 26 26 | 
             
                  "SCRIPT_NAME" => "",
         | 
| 27 | 
            -
                  "rack.input" => StringIO.new(args[1 | 
| 27 | 
            +
                  "rack.input" => StringIO.new(args[1..].join)
         | 
| 28 28 | 
             
                )
         | 
| 29 29 | 
             
              end
         | 
| 30 30 | 
             
            end
         | 
| @@ -38,7 +38,7 @@ PUNK::Command.create "POST" do | |
| 38 38 | 
             
                  "PATH_INFO" => args[0],
         | 
| 39 39 | 
             
                  "CONTENT_TYPE" => "text/json",
         | 
| 40 40 | 
             
                  "SCRIPT_NAME" => "",
         | 
| 41 | 
            -
                  "rack.input" => StringIO.new(args[1 | 
| 41 | 
            +
                  "rack.input" => StringIO.new(args[1..].join)
         | 
| 42 42 | 
             
                )
         | 
| 43 43 | 
             
              end
         | 
| 44 44 | 
             
            end
         | 
| @@ -52,7 +52,7 @@ PUNK::Command.create "PUT" do | |
| 52 52 | 
             
                  "PATH_INFO" => args[0],
         | 
| 53 53 | 
             
                  "CONTENT_TYPE" => "text/json",
         | 
| 54 54 | 
             
                  "SCRIPT_NAME" => "",
         | 
| 55 | 
            -
                  "rack.input" => StringIO.new(args[1 | 
| 55 | 
            +
                  "rack.input" => StringIO.new(args[1..].join)
         | 
| 56 56 | 
             
                )
         | 
| 57 57 | 
             
              end
         | 
| 58 58 | 
             
            end
         | 
    
        data/lib/punk/commands/list.rb
    CHANGED
    
    | @@ -1,30 +1,30 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            PUNK::Command.create "list" do
         | 
| 4 | 
            -
              shortcut  | 
| 4 | 
            +
              shortcut "l"
         | 
| 5 5 | 
             
              description "List routes, actions, models, views, services or workers"
         | 
| 6 6 |  | 
| 7 7 | 
             
              option shortcut: :a, name: :all, description: "Include Punk!", type: nil
         | 
| 8 8 |  | 
| 9 9 | 
             
              def process
         | 
| 10 | 
            -
                case args.join( | 
| 11 | 
            -
                when  | 
| 10 | 
            +
                case args.join(" ")
         | 
| 11 | 
            +
                when "routes"
         | 
| 12 12 | 
             
                  PUNK.app
         | 
| 13 13 | 
             
                  PUNK::App.route_list # TODO: exclude PUNK routes by default
         | 
| 14 | 
            -
                when  | 
| 14 | 
            +
                when "actions"
         | 
| 15 15 | 
             
                  ObjectSpace.each_object(PUNK::Action.singleton_class).map(&:name).reject { |name| _hide?(name) }
         | 
| 16 | 
            -
                when  | 
| 16 | 
            +
                when "models"
         | 
| 17 17 | 
             
                  ObjectSpace.each_object(PUNK::Model.singleton_class).map(&:name).reject { |name| _hide?(name) }
         | 
| 18 | 
            -
                when  | 
| 18 | 
            +
                when "views"
         | 
| 19 19 | 
             
                  ObjectSpace.each_object(PUNK::View.singleton_class).map(&:name).reject { |name| _hide?(name) }
         | 
| 20 | 
            -
                when  | 
| 20 | 
            +
                when "services"
         | 
| 21 21 | 
             
                  ObjectSpace.each_object(PUNK::Service.singleton_class).select { |klass| klass.superclass == PUNK::Service }.map(&:name).reject { |name| _hide?(name) }
         | 
| 22 | 
            -
                when  | 
| 22 | 
            +
                when "workers"
         | 
| 23 23 | 
             
                  ObjectSpace.each_object(PUNK::Worker.singleton_class).select { |klass| klass.superclass == PUNK::Worker }.map(&:name).reject { |name| _hide?(name) }
         | 
| 24 | 
            -
                when  | 
| 24 | 
            +
                when "", "help"
         | 
| 25 25 | 
             
                  "? specify one of: routes, actions, models, views, services, workers"
         | 
| 26 26 | 
             
                else
         | 
| 27 | 
            -
                  "? unkown arguments: #{args.join( | 
| 27 | 
            +
                  "? unkown arguments: #{args.join(",")}"
         | 
| 28 28 | 
             
                end
         | 
| 29 29 | 
             
              end
         | 
| 30 30 |  | 
    
        data/lib/punk/core/app.rb
    CHANGED
    
    | @@ -1,16 +1,16 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require  | 
| 4 | 
            -
            require  | 
| 5 | 
            -
            require  | 
| 6 | 
            -
            require  | 
| 3 | 
            +
            require "roda"
         | 
| 4 | 
            +
            require "sidekiq/web"
         | 
| 5 | 
            +
            require "sidekiq/cron/web"
         | 
| 6 | 
            +
            require "rack/protection"
         | 
| 7 7 |  | 
| 8 | 
            -
            require_relative  | 
| 8 | 
            +
            require_relative "../plugins/all"
         | 
| 9 9 |  | 
| 10 10 | 
             
            # don't use rack session for sidekiq (we do our own auth when routing)
         | 
| 11 11 | 
             
            Sidekiq::Web.set(:sessions, false)
         | 
| 12 12 | 
             
            # TODO: need custom roda route csrf in sidekiq web forms
         | 
| 13 | 
            -
            Sidekiq::Web.use(::Rack::Protection, use: :none, logging: true, logger: SemanticLogger[ | 
| 13 | 
            +
            Sidekiq::Web.use(::Rack::Protection, use: :none, logging: true, logger: SemanticLogger["PUNK::RPT"])
         | 
| 14 14 |  | 
| 15 15 | 
             
            module PUNK
         | 
| 16 16 | 
             
              def self.route(name, &block)
         | 
| @@ -23,15 +23,15 @@ module PUNK | |
| 23 23 |  | 
| 24 24 | 
             
              ROUTES = Tempfile.new("routes.json").path
         | 
| 25 25 | 
             
              PUNK.profile_info("generate", path: ROUTES) do
         | 
| 26 | 
            -
                system "roda-parse_routes -f #{ROUTES} #{File.expand_path(File.join(PUNK.get.app.path,  | 
| 26 | 
            +
                system "roda-parse_routes -f #{ROUTES} #{File.expand_path(File.join(PUNK.get.app.path, "routes", "*"))} #{File.expand_path(File.join(__dir__, "..", "routes", "*"))}"
         | 
| 27 27 | 
             
              end
         | 
| 28 28 |  | 
| 29 29 | 
             
              class App < Roda
         | 
| 30 30 | 
             
                include Loggable
         | 
| 31 31 |  | 
| 32 32 | 
             
                REMOTE = PUNK.env.staging? || PUNK.env.production?
         | 
| 33 | 
            -
                PUBLIC = File.join(PUNK.get.app.path,  | 
| 34 | 
            -
                index_path = File.join(PUBLIC,  | 
| 33 | 
            +
                PUBLIC = File.join(PUNK.get.app.path, "..", "www")
         | 
| 34 | 
            +
                index_path = File.join(PUBLIC, "index.html")
         | 
| 35 35 | 
             
                INDEX =
         | 
| 36 36 | 
             
                  if File.exist?(index_path)
         | 
| 37 37 | 
             
                    File.read(index_path)
         | 
| @@ -50,7 +50,7 @@ module PUNK | |
| 50 50 | 
             
                    INDEX_HTML
         | 
| 51 51 | 
             
                  end
         | 
| 52 52 |  | 
| 53 | 
            -
                plugin :sessions, secret: [PUNK.get.cookie.secret].pack( | 
| 53 | 
            +
                plugin :sessions, secret: [PUNK.get.cookie.secret].pack("H*"),
         | 
| 54 54 | 
             
                                  key: PUNK.get.cookie.key,
         | 
| 55 55 | 
             
                                  max_seconds: 1.year.to_i,
         | 
| 56 56 | 
             
                                  max_idle_sessions: 1.month.to_i,
         | 
| @@ -70,12 +70,12 @@ module PUNK | |
| 70 70 | 
             
                plugin :path_rewriter
         | 
| 71 71 | 
             
                plugin :slash_path_empty
         | 
| 72 72 | 
             
                plugin :multi_route
         | 
| 73 | 
            -
                plugin :type_routing, types: { | 
| 73 | 
            +
                plugin :type_routing, types: {csv: "text/csv"}, default_type: :json
         | 
| 74 74 | 
             
                plugin :route_list, file: ROUTES
         | 
| 75 75 | 
             
                plugin :disallow_file_uploads
         | 
| 76 76 | 
             
                plugin :public, root: PUBLIC
         | 
| 77 77 |  | 
| 78 | 
            -
                plugin :default_headers,  | 
| 78 | 
            +
                plugin :default_headers, "Content-Type" => "text/html", "Content-Security-Policy" => "default-src 'self';img-src *", "Strict-Transport-Security" => "max-age=16070400;", "X-Frame-Options" => "deny", "X-Content-Type-Options" => "nosniff", "X-XSS-Protection" => "1; mode=block"
         | 
| 79 79 |  | 
| 80 80 | 
             
                plugin :error_handler
         | 
| 81 81 | 
             
                plugin :not_found
         | 
| @@ -83,24 +83,24 @@ module PUNK | |
| 83 83 |  | 
| 84 84 | 
             
                request_delegate :root, :on, :is, :get, :post, :redirect, :patch, :delete
         | 
| 85 85 |  | 
| 86 | 
            -
                rewrite_path(/\A\/?\z/,  | 
| 87 | 
            -
                rewrite_path(/\A\/api\/?\z/,  | 
| 86 | 
            +
                rewrite_path(/\A\/?\z/, "/index.html")
         | 
| 87 | 
            +
                rewrite_path(/\A\/api\/?\z/, "/api/index.html")
         | 
| 88 88 |  | 
| 89 89 | 
             
                def require_session!
         | 
| 90 90 | 
             
                  begin
         | 
| 91 | 
            -
                    @_current_session = Session[request.session[ | 
| 91 | 
            +
                    @_current_session = Session[request.session["session_id"]]
         | 
| 92 92 | 
             
                    if @_current_session&.active?
         | 
| 93 93 | 
             
                      @_current_session.touch
         | 
| 94 94 | 
             
                    else
         | 
| 95 95 | 
             
                      clear_session
         | 
| 96 96 | 
             
                      @_current_session = nil
         | 
| 97 97 | 
             
                    end
         | 
| 98 | 
            -
                  rescue  | 
| 98 | 
            +
                  rescue => e
         | 
| 99 99 | 
             
                    exception(e)
         | 
| 100 100 | 
             
                    raise Unauthorized, e.message
         | 
| 101 101 | 
             
                  end
         | 
| 102 | 
            -
                  raise Unauthorized,  | 
| 103 | 
            -
                  PUNK.logger.info "require_session!", { | 
| 102 | 
            +
                  raise Unauthorized, "Session does not exist" if @_current_session.nil?
         | 
| 103 | 
            +
                  PUNK.logger.info "require_session!", {current_session: current_session.inspect, current_identity: current_identity.inspect, current_user: current_user.inspect}.inspect
         | 
| 104 104 | 
             
                end
         | 
| 105 105 |  | 
| 106 106 | 
             
                def require_anonymous!
         | 
| @@ -109,9 +109,9 @@ module PUNK | |
| 109 109 | 
             
                end
         | 
| 110 110 |  | 
| 111 111 | 
             
                def require_tenant!
         | 
| 112 | 
            -
                  raise Unauthorized,  | 
| 112 | 
            +
                  raise Unauthorized, "Session does not exist" if @_current_session.nil?
         | 
| 113 113 | 
             
                  @_current_tenant = current_user.tenants_dataset[id: params[:tenant_id]]
         | 
| 114 | 
            -
                  PUNK.logger.info "require_tenant!", { | 
| 114 | 
            +
                  PUNK.logger.info "require_tenant!", {current_tenant: @_current_tenant.inspect}.inspect
         | 
| 115 115 | 
             
                end
         | 
| 116 116 |  | 
| 117 117 | 
             
                def args
         | 
| @@ -145,17 +145,17 @@ module PUNK | |
| 145 145 | 
             
                end
         | 
| 146 146 |  | 
| 147 147 | 
             
                PUNK_CONTENT_TYPE_LOOKUP = {
         | 
| 148 | 
            -
                  csv:  | 
| 149 | 
            -
                  html:  | 
| 150 | 
            -
                  json:  | 
| 151 | 
            -
                  xml:  | 
| 148 | 
            +
                  csv: "text/csv",
         | 
| 149 | 
            +
                  html: "text/html",
         | 
| 150 | 
            +
                  json: "application/json",
         | 
| 151 | 
            +
                  xml: "application/xml"
         | 
| 152 152 | 
             
                }.freeze
         | 
| 153 153 | 
             
                def render(view)
         | 
| 154 154 | 
             
                  raise InternalServerError, "Not a view: #{view}" unless view.is_a?(View)
         | 
| 155 155 | 
             
                  format = request.requested_type
         | 
| 156 156 | 
             
                  view.profile_info("render", format: format) do
         | 
| 157 157 | 
             
                    response.status = view.status if view.is_a?(Fail)
         | 
| 158 | 
            -
                    response[ | 
| 158 | 
            +
                    response["Content-Type"] = PUNK_CONTENT_TYPE_LOOKUP[format]
         | 
| 159 159 | 
             
                    view.render(format)
         | 
| 160 160 | 
             
                  end
         | 
| 161 161 | 
             
                end
         | 
| @@ -164,7 +164,7 @@ module PUNK | |
| 164 164 | 
             
                  exception(e, current_user: current_user)
         | 
| 165 165 | 
             
                  case e
         | 
| 166 166 | 
             
                  when BadRequest
         | 
| 167 | 
            -
                    present Fail, message:  | 
| 167 | 
            +
                    present Fail, message: "Bad Request", error_messages: [e.message], status: 400
         | 
| 168 168 | 
             
                  when Unauthorized
         | 
| 169 169 | 
             
                    present Fail, message: "Unauthorized", error_messages: [e.message], status: 401
         | 
| 170 170 | 
             
                  when Forbidden
         | 
| @@ -190,10 +190,10 @@ module PUNK | |
| 190 190 | 
             
                  @_started = Time.now.utc
         | 
| 191 191 | 
             
                  name = "#{request.request_method} #{request.path}"
         | 
| 192 192 | 
             
                  logger.info "Started #{name} for #{request.ip}", params.deep_symbolize_keys.sanitize.inspect
         | 
| 193 | 
            -
                  logger.trace request.env[ | 
| 193 | 
            +
                  logger.trace request.env["HTTP_USER_AGENT"]
         | 
| 194 194 | 
             
                  logger.info "Started #{name} for #{request.ip || Session.default_values[:remote_addr].to_s}", params.deep_symbolize_keys.sanitize.inspect
         | 
| 195 | 
            -
                  logger.trace request.env[ | 
| 196 | 
            -
                  logger.trace request.env[ | 
| 195 | 
            +
                  logger.trace request.env["HTTP_USER_AGENT"] || Session.default_values[:user_agent]
         | 
| 196 | 
            +
                  logger.trace request.env["HTTP_COOKIE"]
         | 
| 197 197 | 
             
                  logger.push_tags(name)
         | 
| 198 198 | 
             
                  _set_cookie(request.env)
         | 
| 199 199 | 
             
                end
         | 
| @@ -203,14 +203,14 @@ module PUNK | |
| 203 203 | 
             
                  name = logger.pop_tags(1).join
         | 
| 204 204 | 
             
                  duration = 1000.0 * (Time.now.utc - @_started)
         | 
| 205 205 | 
             
                  logger.pop_tags
         | 
| 206 | 
            -
                  logger.trace((headers.present? ? headers[ | 
| 206 | 
            +
                  logger.trace((headers.present? ? headers["Set-Cookie"] : nil) || "(no cookie set)")
         | 
| 207 207 | 
             
                  logger.info message: "Completed #{name} status #{status}", duration: duration
         | 
| 208 208 | 
             
                  _store_cookie(headers)
         | 
| 209 209 | 
             
                end
         | 
| 210 210 |  | 
| 211 211 | 
             
                route do |r|
         | 
| 212 212 | 
             
                  r.public
         | 
| 213 | 
            -
                  r.on  | 
| 213 | 
            +
                  r.on "jobs" do
         | 
| 214 214 | 
             
                    require_session!
         | 
| 215 215 | 
             
                    r.run Sidekiq::Web
         | 
| 216 216 | 
             
                  end
         | 
| @@ -222,26 +222,26 @@ module PUNK | |
| 222 222 | 
             
                def _set_cookie(headers)
         | 
| 223 223 | 
             
                  return if REMOTE
         | 
| 224 224 | 
             
                  return if headers.blank?
         | 
| 225 | 
            -
                  return if headers[ | 
| 226 | 
            -
                  return if headers[ | 
| 227 | 
            -
                  cookie_file =  | 
| 228 | 
            -
                  cookie_file +=  | 
| 225 | 
            +
                  return if headers["HTTP_USER_AGENT"].present?
         | 
| 226 | 
            +
                  return if headers["HTTP_COOKIE"].present?
         | 
| 227 | 
            +
                  cookie_file = "tmp/.cookie-jar"
         | 
| 228 | 
            +
                  cookie_file += "-test" if PUNK.env.test?
         | 
| 229 229 | 
             
                  cookie = File.read(cookie_file) if File.exist?(cookie_file)
         | 
| 230 230 | 
             
                  return if cookie.blank?
         | 
| 231 | 
            -
                  headers[ | 
| 231 | 
            +
                  headers["HTTP_COOKIE"] = cookie
         | 
| 232 232 | 
             
                end
         | 
| 233 233 |  | 
| 234 234 | 
             
                def _store_cookie(headers)
         | 
| 235 235 | 
             
                  return if REMOTE
         | 
| 236 236 | 
             
                  return if headers.blank?
         | 
| 237 | 
            -
                  cookie = headers[ | 
| 237 | 
            +
                  cookie = headers["Set-Cookie"]
         | 
| 238 238 | 
             
                  return if cookie.blank?
         | 
| 239 | 
            -
                  cookie_file =  | 
| 240 | 
            -
                  cookie_file +=  | 
| 241 | 
            -
                  if  | 
| 239 | 
            +
                  cookie_file = "tmp/.cookie-jar"
         | 
| 240 | 
            +
                  cookie_file += "-test" if PUNK.env.test?
         | 
| 241 | 
            +
                  if /max-age=0/.match?(cookie)
         | 
| 242 242 | 
             
                    File.delete(cookie_file)
         | 
| 243 243 | 
             
                  else
         | 
| 244 | 
            -
                    File.open(cookie_file,  | 
| 244 | 
            +
                    File.open(cookie_file, "w") { |file| file << cookie }
         | 
| 245 245 | 
             
                  end
         | 
| 246 246 | 
             
                end
         | 
| 247 247 | 
             
              end
         | 
    
        data/lib/punk/core/boot.rb
    CHANGED
    
    | @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative  | 
| 4 | 
            -
            require_relative  | 
| 5 | 
            -
            require_relative  | 
| 6 | 
            -
            require_relative  | 
| 7 | 
            -
            require_relative  | 
| 3 | 
            +
            require_relative "../startup/logger"
         | 
| 4 | 
            +
            require_relative "../startup/environment"
         | 
| 5 | 
            +
            require_relative "../startup/task"
         | 
| 6 | 
            +
            require_relative "../startup/database"
         | 
| 7 | 
            +
            require_relative "../startup/cache"
         | 
| 8 8 |  | 
| 9 9 | 
             
            PUNK.store[:state] = :booted
         | 
    
        data/lib/punk/core/cli.rb
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative  | 
| 3 | 
            +
            require_relative "../../punk"
         | 
| 4 4 |  | 
| 5 | 
            -
            require  | 
| 5 | 
            +
            require "highline/import"
         | 
| 6 6 |  | 
| 7 | 
            -
            PUNK.init(task:  | 
| 7 | 
            +
            PUNK.init(task: "console", config: {app: {name: "Punk!"}}).exec
         | 
| 8 8 |  | 
| 9 9 | 
             
            PUNK.commands(:pry)
         | 
| 10 10 |  | 
    
        data/lib/punk/core/commander.rb
    CHANGED
    
    | @@ -1,65 +1,65 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            command :test do |c|
         | 
| 4 | 
            -
              c.description =  | 
| 4 | 
            +
              c.description = "Run rubocop and rspec"
         | 
| 5 5 | 
             
              c.action do
         | 
| 6 | 
            -
                say( | 
| 7 | 
            -
                unless ENV[ | 
| 8 | 
            -
                  error( | 
| 6 | 
            +
                say("Running tests...")
         | 
| 7 | 
            +
                unless ENV["PUNK_ENV"] == "test"
         | 
| 8 | 
            +
                  error("!!! PUNK_ENV should be test !!!")
         | 
| 9 9 | 
             
                  exit 1 # rubocop:disable Rails/Exit
         | 
| 10 10 | 
             
                end
         | 
| 11 11 | 
             
                ENV.delete_if { |name, _value| name =~ /^PUNK_/ }
         | 
| 12 | 
            -
                system( | 
| 12 | 
            +
                system("rubocop") &&
         | 
| 13 13 | 
             
                  # system('quasar build -m pwa') &&
         | 
| 14 | 
            -
                  system( | 
| 14 | 
            +
                  system("PUNK_ENV=test rspec")
         | 
| 15 15 | 
             
                exit $CHILD_STATUS.exitstatus # rubocop:disable Rails/Exit
         | 
| 16 16 | 
             
              end
         | 
| 17 17 | 
             
            end
         | 
| 18 18 |  | 
| 19 19 | 
             
            command :console do |c|
         | 
| 20 | 
            -
              c.description =  | 
| 20 | 
            +
              c.description = "Launch the console"
         | 
| 21 21 | 
             
              c.action do
         | 
| 22 | 
            -
                say(HighLine.color( | 
| 23 | 
            -
                path = File.join(__dir__,  | 
| 22 | 
            +
                say(HighLine.color("🤘 Are you ready to rock?", :green, :bold))
         | 
| 23 | 
            +
                path = File.join(__dir__, "cli.rb")
         | 
| 24 24 | 
             
                exec "pry -r #{path}"
         | 
| 25 25 | 
             
              end
         | 
| 26 26 | 
             
            end
         | 
| 27 27 | 
             
            alias_command :c, :console
         | 
| 28 28 |  | 
| 29 29 | 
             
            command :server do |c|
         | 
| 30 | 
            -
              c.description =  | 
| 30 | 
            +
              c.description = "Start the server"
         | 
| 31 31 | 
             
              c.action do
         | 
| 32 | 
            -
                say( | 
| 33 | 
            -
                exec  | 
| 32 | 
            +
                say("Starting server...")
         | 
| 33 | 
            +
                exec "puma -C ./config/puma.rb"
         | 
| 34 34 | 
             
              end
         | 
| 35 35 | 
             
            end
         | 
| 36 36 | 
             
            alias_command :s, :server
         | 
| 37 37 |  | 
| 38 38 | 
             
            command :worker do |c|
         | 
| 39 | 
            -
              c.description =  | 
| 39 | 
            +
              c.description = "Start the worker"
         | 
| 40 40 | 
             
              c.action do
         | 
| 41 | 
            -
                say( | 
| 42 | 
            -
                path = File.join(__dir__,  | 
| 41 | 
            +
                say("Starting worker...")
         | 
| 42 | 
            +
                path = File.join(__dir__, "worker.rb")
         | 
| 43 43 | 
             
                exec "sidekiq -r #{path} -C ./config/sidekiq.yml"
         | 
| 44 44 | 
             
              end
         | 
| 45 45 | 
             
            end
         | 
| 46 46 | 
             
            alias_command :w, :worker
         | 
| 47 47 |  | 
| 48 | 
            -
            command  | 
| 49 | 
            -
              c.description =  | 
| 48 | 
            +
            command "env dump" do |c|
         | 
| 49 | 
            +
              c.description = "Display the environment"
         | 
| 50 50 | 
             
              c.action do
         | 
| 51 | 
            -
                say( | 
| 51 | 
            +
                say("Dumping env...")
         | 
| 52 52 | 
             
                ap PUNK.get # rubocop:disable Rails/Output
         | 
| 53 53 | 
             
              end
         | 
| 54 54 | 
             
            end
         | 
| 55 55 |  | 
| 56 | 
            -
            command  | 
| 57 | 
            -
              c.description =  | 
| 56 | 
            +
            command "db create" do |c|
         | 
| 57 | 
            +
              c.description = "Create the database (dropping it first if necessary)"
         | 
| 58 58 | 
             
              c.action do
         | 
| 59 | 
            -
                say( | 
| 60 | 
            -
                require  | 
| 59 | 
            +
                say("Creating db...")
         | 
| 60 | 
            +
                require "sequel"
         | 
| 61 61 | 
             
                database = File.basename(PUNK.get.db.url)
         | 
| 62 | 
            -
                server = PUNK.get.db.url.gsub(/[^\/]+$/,  | 
| 62 | 
            +
                server = PUNK.get.db.url.gsub(/[^\/]+$/, "postgres")
         | 
| 63 63 | 
             
                pg = Sequel.connect(server)
         | 
| 64 64 | 
             
                pg.execute "DROP DATABASE IF EXISTS #{database}"
         | 
| 65 65 | 
             
                pg.execute "CREATE DATABASE #{database}"
         | 
| @@ -67,14 +67,14 @@ command 'db create' do |c| | |
| 67 67 | 
             
              end
         | 
| 68 68 | 
             
            end
         | 
| 69 69 |  | 
| 70 | 
            -
            command  | 
| 71 | 
            -
              c.description =  | 
| 72 | 
            -
              c.option  | 
| 70 | 
            +
            command "db migrate" do |c|
         | 
| 71 | 
            +
              c.description = "Run database migrations"
         | 
| 72 | 
            +
              c.option "-r", "Number of versions to migrate, +ve for up and -ve for down", "--relative NUMBER", Integer
         | 
| 73 73 | 
             
              c.action do |_args, options|
         | 
| 74 | 
            -
                say( | 
| 74 | 
            +
                say("Migrating db...")
         | 
| 75 75 | 
             
                PUNK.boot
         | 
| 76 76 | 
             
                Sequel.extension :migration
         | 
| 77 | 
            -
                migrations_path = File.join(PUNK.get.app.path,  | 
| 77 | 
            +
                migrations_path = File.join(PUNK.get.app.path, "migrations")
         | 
| 78 78 | 
             
                if File.exist?(migrations_path)
         | 
| 79 79 | 
             
                  if options.relative.nil?
         | 
| 80 80 | 
             
                    Sequel::Migrator.run(PUNK.db, migrations_path)
         |