Giter VIP home page Giter VIP logo

stitches's Issues

Rails engine?

Having a generator option alone makes it hard to take advantage of future updates without squashing any changes you may have made to the generated files in the meantime. A Rails engine pattern could help give this and still allow for a generator for non-Rails apps. It would also mean that we could set up a dummy app for CI to actually run the bundled tests.

Another option or baby step could be to vendor the generated files to discourage changes being made to them directly.

ApiClients should be de-activatable

When rotating keys, you can't necessarily delete old api keys, for example if you have foreign key constraints to them from your domain objects.

The default api_clients table should have an active field, defaulting to true, or maybe an active_til field? It would probably be handy to have some rake tasks to help with rotation as well.

Find a way to run the generator in a test

This will be brittle, but might be worth doing, if we had a test that:

  1. rails new
  2. bundle install
  3. rails g stitches:api
  4. rails rspec:install
  5. rails apitome:install
  6. bundle exec rake

And fails the build if any of that fails.

Deprecation warning in Rails 6

Getting a deprecation warning when running this gem in Rails 6.

DEPRECATION WARNING: `Module#parent` has been renamed to `module_parent`. `parent` is deprecated and will be removed in Rails 6.1. (called from <top (required)> at /Users/chris/galley/api_playground/config/environment.rb:5)

Looks like it is the result of rails/rails#34051. Not critical at all as it is just a warning, but wanted to flag!

Failure message on fresh install and rspec run.

rails new APP_NAME

  • added gem 'stitches'
    rails g rspec:install
    rails g apitome:install
    rails g stitches:api
  • create database
  • run migrations
  • run rspec to validate setup

[error]
uninitialized constant RSpec::Rails (NameError)

White-list "complex" route

I have various routes whitelisted, docs for example, but I need to whitelist a route such as users/abc12379xyz_asdf/activate

I have tried this regex but it is still throwing an error:

configuration.whitelist_regexp = %r{\A/(sidekiq|resque|docs|assets)(users\/.*\/activate)(\Z|/.*\Z)}

error:
Unauthorized - no authorization header

Header override

Is it possible to use an alternative header for authentication?
I use stitches to protect the API routes from unauthorized requests based on the API key, but I use devise-jwt to authenticate/authorize user access.
Devise-jwt uses a Bearer token in the Authorization header, so being able to override the header used by stitches to almost anything else would let these two gems play nice together.

Alternative white lisiting method because `configuration.allowlist_regexp` is error prone

The pain of #61 highlights that this regex is cumbersome to maintain. In referrals, we have an entry that looks like this:

  configuration.allowlist_regexp = %r{\A/(referrals\/api\/contacts|referrals\/api\/referrals|assets|client|referrals\/api\/docs|referrals\/proof_of_life|referrals\/resque|referrals\/teaspoon)}

It turns out that there was an overly permissive entry in there which essentially white listed all of the referrals API - not desirable and tests are being back filled.

I'd like to add something that's a bit easier to read/maintain. I spent some time trying to replace the middleware by creating a Rails custom constraint. Constraints have a handle on the request, but not on the response and so I ran into trouble when trying to replicate these lines:

env[@configuration.env_var_to_hold_api_client_primary_key] = client.id
env[@configuration.env_var_to_hold_api_client] = client

Is there a) still a need for these lines, and b) a way to move them out of the middleware? Or maybe some third way to make it more obvious in routes.rb what does/does not require the api_key? A less desirable option would be to add a before_filter in the controllers but I'm guessing that choice was avoided on purpose?

Remove Unused Middleware

Since this is an API, we don't want sessions or cookie support. Let's remove the middleware for these.

# No sessions. This removes the need for CSRF protection.
config.middleware.delete "ActionDispatch::Cookies"
config.middleware.delete "ActionDispatch::Session::CookieStore"
config.middleware.delete "ActionDispatch::Flash"

Version is missing in the response headers

Problem:
ApiVersionConstraint requires clients to send Accept request headers that specify the API version, for example: Accept: "application/json; version=2". However, the API response does not match this expected behavior.

Solution:
Add a default header to Api::ApiController that responds with the correct version.

For example: Content-Type: "application/json; version=2"

Gem release tasks

Need tasks to bump to a new version of the gem and release it to RubyGems.org

Uninitialized constant Api::V1 in debug

Problem:
I get ActionController::RoutingError (uninitialized constant Api::V1) in debug mode using Fast Debugger in IntelliJ IDEA (ruby-debug-ide 0.8.0.beta8 with debase 0.3.0.beta8).

Steps to reproduce:

Create new Rails 6 API app and setup stitches.

Create a Controller, e.g. RestaurantsController with Rails scaffold:

My example rails app has following routes then:

namespace :api do
    scope module: :v1, constraints: Stitches::ApiVersionConstraint.new(1) do
      resource :ping, only: [:create]
      # Add your V1 resources here
      resources :restaurants
    end
  end
end
...

Controller looks like:

class Api::V1::RestaurantsController < Api::ApiController
...
  # POST /restaurants
  def create
    @restaurant = Restaurant.new(restaurant_params)

    if @restaurant.save
      render json: { restaurant: @restaurant }, status: :created,
             location: @restaurant
    else
      render json: Stitches::Errors.from_active_record(@restaurant),
             status: :unprocessable_entity
    end
  end
...
end

Now start Server with rails s and send proper POST to localhost:3000/api/restaurants/1.
It works just fine for now.

Now start Server with debug and you will see the error: ActionController::RoutingError (uninitialized constant Api::V1) with the same POST request.

Root route always unauthorized

how can I allow the root route? Or what am I setting incorrectly?

My stitches.rb:

require 'stitches'

Stitches.configure do |configuration|
  # Regexp of urls that do not require ApiKeys or valid, versioned mime types
  configuration.allowlist_regexp = %r{
    admin|dashboard|root|password_resets|login|logout|activate|sessions|
    sms_events|sidekiq|resque|docs|assets|temp_athletes|temp_commit_offers|
    commit-offers|co_email_recipients|co_email_groupings|conferences|
    rails\/mailers|forest
  }

  # Name of the custom Authorization scheme.  See http://www.ietf.org/rfc/rfc2617.txt for details,
  # but generally should be a string with no spaces or special characters.
  configuration.custom_http_auth_scheme = 'My_Key'
end

My routes.rb:

Rails.application.routes.draw do
 ...
  root to: 'user_sessions#new'
 ...
end

My application_controller.rb:

class ApplicationController < ActionController::Base
  include Sorcery::Controller

  def authenticate
    current_user || not_authenticated
  end

  def not_authenticated
    respond_to do |type|
      type.html { redirect_to login_path, alert: 'Please login first' }
      type.json { render json: { errors: 'Unable to authenticate' }, status: :unauthorized }
    end
  end

  def unable_to_activate
    render json: { errors: 'User already activated or not found' }, status: :unprocessable_entity
  end
end

My user_sessions_controller.rb:

class UserSessionsController < ApplicationController
  skip_before_action :require_login # , except: %i[destroy]

  def new
    if logged_in?
      if current_user.is_admin?
        redirect_to(admin_path) && return
      else
        redirect_to(athletes_path) && return
      end
    end
    @user = User.new
  end
 ...
end

When I start my server locally and attempt to go to the root all I get rendered is:
Unauthorized - no authorization header
and the only request I see come through is for:
Started GET "/" for 127.0.0.1 at 2018-12-10 10:16:15 -0600

Issue with model validation and controller valid? check

I was reviewing the details from the Error Handling page, but it does seem to indicate the best way to implement validations in the model.

I have a model that contains a file attachment called :object. I have a validation that checks the file size based on file type:

def ojbect_size_valid
   errors.add(:object, 'should be less than or equal to 5MB for images') if object_file_size > 5.megabytes && image_type?
   errors.add(:object, 'should be less than or equal to 15MB for gifs and videos') if object_file_size > 15.megabytes && (gif_type? || video_type?)
end

This validation is catching files correctly but in the create method of the controller it is throwing an error:

def create
    mp = medium_params
    @medium = Medium.create(mp)

    if @medium.valid?
       ...
    else
      render json: {
        errors: Stitches::Errors.from_active_record_object(@medium)
      }, status: :unprocessable_entity
    end
  end

undefined method `full_messages' for {}:Hash

app/controllers/api/v1/media_controller.rb, line 108

  103         )
  104       else
  105   
  106   
  107         render json: {
> 108           errors: Stitches::Errors.from_active_record_object(@medium)
  109         }, status: :unprocessable_entity
  110       end
  111     end
  112   

What am I doing wrong here to get the errors to render?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.