cadenero 0.0.2.a → 0.0.2.a1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. data/README.md +46 -9
  2. data/app/controllers/cadenero/v1/account/dashboard_controller.rb +1 -1
  3. data/app/controllers/cadenero/v1/account/sessions_controller.rb +27 -0
  4. data/app/controllers/cadenero/v1/accounts_controller.rb +4 -0
  5. data/app/extenders/controllers/application_controller_decorator.rb +4 -3
  6. data/app/serializers/cadenero/user_serializer.rb +1 -0
  7. data/config/initializers/warden/strategies/password.rb +13 -4
  8. data/config/initializers/warden.rb +1 -0
  9. data/config/routes.rb +6 -11
  10. data/db/seeds.rb +8 -2
  11. data/lib/cadenero/engine.rb +1 -0
  12. data/lib/cadenero/version.rb +1 -1
  13. data/lib/cadenero.rb +25 -0
  14. data/lib/generators/cadenero/install/templates/initializer.rb +0 -3
  15. data/lib/generators/cadenero/install_generator.rb +40 -17
  16. data/spec/dummy/app/controllers/application_controller.rb +6 -0
  17. data/spec/dummy/db/seeds.rb +8 -0
  18. data/spec/dummy/log/development.log +527 -87
  19. data/spec/dummy/log/test.log +3117 -8571
  20. data/spec/dummy/tmp/cache/assets/D0B/E90/sprockets%2F2c56f5dc65ded8014ad1226c5c985124 +0 -0
  21. data/spec/dummy/tmp/cache/assets/D86/490/sprockets%2Faaf0d4667cf7ef62869d70539bc77af7 +0 -0
  22. data/spec/dummy/tmp/cache/assets/DA6/CC0/sprockets%2F1c575d7a7db598dfcf41536ccc83f01e +0 -0
  23. data/spec/dummy/tmp/cache/assets/DB6/250/sprockets%2F0f882b7b9528900cfec89e8b2fffcc38 +0 -0
  24. data/spec/dummy/tmp/cache/assets/E18/9D0/sprockets%2F1f79e8f926ea465ded9dcc552cd56bff +0 -0
  25. data/spec/dummy/tmp/restart.txt +0 -0
  26. data/spec/features/users/sign_in_spec.rb +29 -10
  27. data/spec/features/users/sign_up_spec.rb +2 -2
  28. data/spec/generators/install_generator_spec.rb +1 -24
  29. metadata +17 -3
  30. data/app/controllers/cadenero/v1/sessions_controller.rb +0 -13
data/README.md CHANGED
@@ -18,19 +18,56 @@ Authentication Engine for Rails.API multitenant RESTful APIs based on Warden. It
18
18
  ### Why Cadenero?
19
19
  **"Cadenero"** is the spanish word for ["Bouncer (doorman)"](http://en.wikipedia.org/wiki/Bouncer_(doorman\)). The main function of **Cadenero** is to be a resource for authenticating consumers of the services that the API provides. As the real bouncers, **Cadenero** aims to provide security, check authorized access, to refuse entry for intoxication, aggressive behavior or non-compliance with statutory or establishment rules.
20
20
 
21
+ ### Inatalling **Cadenero**
22
+ Generate first your Rails.API app as usual using:
23
+ ```
24
+ > rails-api new your_app --skip-test-unit
25
+ ```
26
+ In the `Gemfile` add the following lines:
27
+ ```ruby
28
+ gem 'cadenero', '~> 0.0.2.a1'
29
+ gem 'pg'
30
+ ```
31
+ In the `config/database.yml` replace the `sqlite3` adapter for `postgresql` as follow:
32
+ ```
33
+ development:
34
+ adapter: postgresql
35
+ database: your_app_development
36
+ min_messages: warning
37
+
38
+ test:
39
+ adapter: postgresql
40
+ database: your_app_test
41
+ min_messages: warning
42
+ ```
43
+
44
+ Then run bundle, create the databases and the generator:
45
+ ```
46
+ > bundle install; rake db:create; rails-api g cadenero:install
47
+ ```
48
+ Finally run the server:
49
+ ```
50
+ rails-api s
51
+ ```
52
+
53
+ Check that you can access the API using the default account `www` and user `testy@example.com` with password `changeme˜ for that you can use [cURL](http://curl.haxx.se/) or [RESTClient](http://restclient.net/)
54
+
55
+ Then have fun!
56
+
21
57
  ### Access Points
22
58
  **Cadenero** creates the following versioned routes for exposing the authentication RESTful API
23
59
 
24
60
  ```
25
- v1_users_new GET /v1/users/new(.:format) cadenero/v1/users#new
26
- v1_root /v1(.:format) cadenero/v1/account/dashboard#index
27
- v1_sign_in GET /v1/sign_in(.:format) cadenero/v1/account/sessions#new
28
- v1_sessions POST /v1/sign_in(.:format) cadenero/v1/account/sessions#create
29
- v1_user_sign_up GET /v1/sign_up(.:format) cadenero/v1/account/users#new
30
- v1_user_sign_up POST /v1/sign_up(.:format) cadenero/v1/account/users#create
31
- v1_sign_up GET /v1/sign_up(.:format) cadenero/v1/accounts#new
32
- v1_accounts POST /v1/accounts(.:format) cadenero/v1/accounts#create
33
- v1_root /v1(.:format) cadenero/v1/dashboard#index
61
+ v1_root /v1(.:format) cadenero/v1/account/dashboard#index {:default=>:json}
62
+ v1_sessions POST /v1/sessions(.:format) cadenero/v1/account/sessions#create {:default=>:json}
63
+ DELETE /v1/sessions(.:format) cadenero/v1/account/sessions#delete {:default=>:json}
64
+ v1_users POST /v1/users(.:format) cadenero/v1/account/users#create {:default=>:json}
65
+ v1_accounts POST /v1/accounts(.:format) cadenero/v1/accounts#create {:default=>:json}
66
+ root / cadenero/v1/account/dashboard#index {:default=>:json}
67
+ ```
68
+ You can check then running:
69
+ ```
70
+ rake routes
34
71
  ```
35
72
 
36
73
  ### The Cadenero Task List
@@ -5,7 +5,7 @@ module Cadenero
5
5
  before_filter :authenticate_user!
6
6
 
7
7
  def index
8
-
8
+ render json: {message: "Welcome #{current_user.email}"}, status: 201
9
9
  end
10
10
  end
11
11
  end
@@ -0,0 +1,27 @@
1
+ require_dependency "cadenero/application_controller"
2
+
3
+ module Cadenero::V1
4
+ class Account::SessionsController < Cadenero::ApplicationController
5
+ def create
6
+ Rails.logger.info "params: #{params}"
7
+ if env['warden'].authenticate(:password, :scope => :user)
8
+ render json: current_user, status: 201
9
+ else
10
+ render json: {errors: {user:["Invalid email or password"]}}, status: 422
11
+ end
12
+ end
13
+ def delete
14
+ user = Cadenero::User.find_by_id(params[:id])
15
+ Rails.logger.info "id: #{params[:id]}"
16
+ Rails.logger.info "user: #{user.to_json}"
17
+ Rails.logger.info "current_user.id: #{current_user}"
18
+ Rails.logger.info "user_signed_in?: #{user_signed_in?}"
19
+ if user_signed_in?
20
+ env['warden'].logout(:user)
21
+ render json: {message: "Successful logout"}, status: 201
22
+ else
23
+ render json: {message: "Unsuccessful logout user with id"}, status: 401
24
+ end
25
+ end
26
+ end
27
+ end
@@ -3,6 +3,10 @@ require_dependency "cadenero/application_controller"
3
3
  module Cadenero
4
4
  module V1
5
5
  class AccountsController < Cadenero::ApplicationController
6
+ def new
7
+ errors = %Q{Please sign up. posting the account json data as {account: { name: "Testy", subdomain: "test", owner_attributes: {email: "testy@example.com", password: "changeme", password_confirmation: "changeme"} }} to /v1/accounts/sign_up}
8
+ render json: {errors: errors, links: "/v1/accounts/sign_up"}, status: 422
9
+ end
6
10
  def create
7
11
  @account = Cadenero::V1::Account.create_with_owner(params[:account])
8
12
  if @account.valid?
@@ -23,7 +23,7 @@
23
23
  if user_signed_in?
24
24
  @current_user ||= begin
25
25
  user_id = env['warden'].user(:scope => :user)
26
- Cadenero::User.find(user_id)
26
+ Cadenero::User.find_by_id(user_id)
27
27
  end
28
28
  end
29
29
  end
@@ -35,9 +35,10 @@
35
35
 
36
36
  # it the user is not authenticated returns a 422 and an informative error with the link for sign
37
37
  def authenticate_user!
38
+ Rails.logger.info "env['warden'].authenticated?(:user): #{env['warden'].authenticated?(:user)}"
38
39
  unless user_signed_in?
39
- errors = "Please sign in. posting the user json credentials to /v1/sign_in"
40
- render json: {errors: errors, links: "/v1/sign_in"}, status: 422
40
+ errors = %Q{Please sign in. posting the user json credentials as: {"user": {"email": "testy2@example.com", "password": "changeme"}} to /v1/sessions}
41
+ render json: {errors: errors, links: "/v1/sessions"}, status: 422
41
42
  end
42
43
  end
43
44
 
@@ -4,5 +4,6 @@ module Cadenero
4
4
  attributes :id, :email
5
5
  has_many :members, :class_name => "Cadenero::Member"
6
6
  has_many :accounts, :through => :members
7
+
7
8
  end
8
9
  end
@@ -3,18 +3,27 @@ Warden::Strategies.add(:password) do
3
3
  ActionDispatch::Http::URL.extract_subdomains(request.host, 1)
4
4
  end
5
5
 
6
+ def json_params
7
+ unless params.empty?
8
+ params
9
+ else
10
+ @json ||= env['rack.input'].gets
11
+ JSON.parse(@json)
12
+ end
13
+ end
14
+
6
15
  def valid?
7
- subdomain.present? && params["user"]
16
+ subdomain.present? && json_params["user"]
8
17
  end
9
18
 
10
19
  def authenticate!
11
20
  account = Cadenero::V1::Account.find_by_subdomain(subdomain)
12
21
  if account
13
- u = account.users.find_by_email(params["user"]["email"])
14
- if u.nil?
22
+ u = account.users.find_by_email(json_params["user"]["email"])
23
+ if u.nil? || u.blank?
15
24
  fail!
16
25
  else
17
- u.authenticate(params["user"]["password"]) ? success!(u) : fail!
26
+ u.authenticate(json_params["user"]["password"]) ? success!(u) : fail!
18
27
  end
19
28
  else
20
29
  fail!
@@ -1,3 +1,4 @@
1
1
  Rails.application.config.middleware.use Warden::Manager do |manager|
2
+ manager.failure_app = Cadenero::V1::Account::DashboardController.action(:index)
2
3
  manager.default_strategies :password
3
4
  end
data/config/routes.rb CHANGED
@@ -2,23 +2,18 @@ require 'cadenero/constraints/subdomain_required'
2
2
 
3
3
  Cadenero::Engine.routes.draw do
4
4
  namespace :v1 do
5
- get "users/new"
6
-
7
5
  constraints(Cadenero::Constraints::SubdomainRequired) do
8
6
  scope :module => "account" do
9
- root :to => "dashboard#index"
10
- get '/sign_in', :to => "sessions#new"
11
- post '/sign_in', :to => "sessions#create", :as => :sessions
12
- get '/sign_up', :to => "users#new", :as => :user_sign_up
13
- post '/sign_up', :to => "users#create", :as => :user_sign_up
7
+ root :to => "dashboard#index", default: :json
8
+ post '/sessions', :to => "sessions#create", default: :json
9
+ delete '/sessions', :to => "sessions#delete", default: :json
10
+ post '/users', :to => "users#create", default: :json
14
11
  end
15
12
  end
16
- get '/sign_up', :to => "accounts#new", :as => :sign_up
17
- post '/accounts', :to => "accounts#create", :as => :accounts
18
-
19
- root :to => "dashboard#index"
13
+ post '/accounts', :to => "accounts#create", :as => :accounts, default: :json
20
14
 
21
15
  end
16
+ root :to => "v1/account/dashboard#index", default: :json
22
17
  # post '/v1/accounts', :to => "v1/accounts#create", :as => :accounts
23
18
 
24
19
  end
data/db/seeds.rb CHANGED
@@ -1,2 +1,8 @@
1
- user = Cadenero::User.create(email: "testy@example.com", password: "changeme", password_confirmation: "changeme")
2
- Cadenero::V1::Account.create(name: 'Root Account for the Site', subdomain: 'www', owner: user)
1
+ @account = Cadenero::V1::Account.create!(name: Cadenero.default_account_name,
2
+ subdomain: Cadenero.default_account_subdomain,
3
+ owner: Cadenero::User.create!(email: Cadenero.default_user_email,
4
+ password: Cadenero.default_user_password,
5
+ password_confirmation: Cadenero.default_user_password))
6
+
7
+ @account.create_schema
8
+ @account.ensure_authentication_token!
@@ -1,5 +1,6 @@
1
1
  require 'warden'
2
2
  module Cadenero
3
+
3
4
  class Engine < ::Rails::Engine
4
5
  isolate_namespace Cadenero
5
6
  config.middleware.use Warden::Manager do |manager|
@@ -1,3 +1,3 @@
1
1
  module Cadenero
2
- VERSION = "0.0.2.a"
2
+ VERSION = "0.0.2.a1"
3
3
  end
data/lib/cadenero.rb CHANGED
@@ -26,4 +26,29 @@ require 'warden'
26
26
  require 'apartment'
27
27
 
28
28
  module Cadenero
29
+ mattr_accessor :base_path,
30
+ :user_class,
31
+ :default_account_name,
32
+ :default_account_subdomain,
33
+ :default_user_email,
34
+ :default_user_password
35
+
36
+ class << self
37
+ def base_path
38
+ @@base_path ||= Rails.application.routes.named_routes[:cadenero].path
39
+ end
40
+
41
+ def user_class
42
+ if @@user_class.is_a?(Class)
43
+ raise "You can no longer set Cadenero.user_class to be a class. Please use a string instead."
44
+ elsif @@user_class.is_a?(String)
45
+ begin
46
+ Object.const_get(@@user_class)
47
+ rescue NameError
48
+ @@user_class.constantize
49
+ end
50
+ end
51
+ end
52
+ end
53
+
29
54
  end
@@ -1,8 +1,5 @@
1
1
  Cadenero.user_class = "<%= user_class %>"
2
- Cadenero.email_from_address = "please-change-me@example.com"
3
2
  # If you do not want to use gravatar for avatars then specify the method to use here:
4
- # Cadenero.avatar_user_method = :custom_avatar_url
5
- #Cadenero.per_page = <%= Cadenero.per_page.inspect %>
6
3
 
7
4
 
8
5
  # Rails.application.config.to_prepare do
@@ -1,8 +1,12 @@
1
1
  require 'rails/generators'
2
2
  module Cadenero
3
3
  module Generators
4
- class InstallGenerator < Rails::Generators::Base
4
+ class InstallGenerator < Rails::Generators::Base
5
5
  class_option "user-class", :type => :string
6
+ class_option "default-account-name", :type => :string
7
+ class_option "default-account-subdomain", :type => :string
8
+ class_option "default-user-email", :type => :string
9
+ class_option "default-user-password", :type => :string
6
10
  class_option "no-migrate", :type => :boolean
7
11
  class_option "current-user-helper", :type => :string
8
12
 
@@ -18,13 +22,13 @@ module Cadenero
18
22
 
19
23
  def determine_user_class
20
24
  @user_class = options["user-class"].presence ||
21
- ask("What is your user class called? [User]").presence ||
25
+ ask("What will be the name for your user class? [User]").presence ||
22
26
  'User'
23
27
  end
24
28
 
25
29
  def determine_current_user_helper
26
30
  current_user_helper = options["current-user-helper"].presence ||
27
- ask("What is the current_user helper called in your app? [current_user]").presence ||
31
+ ask("What will be the current_user helper called in your app? [current_user]").presence ||
28
32
  :current_user
29
33
 
30
34
  puts "Defining cadenero_user method inside ApplicationController..."
@@ -43,6 +47,30 @@ module Cadenero
43
47
 
44
48
  end
45
49
 
50
+ def determine_default_account_name
51
+ Cadenero.default_account_name = options["default-account-name"].presence ||
52
+ ask("What will be the name for the default account? [Root Account]").presence ||
53
+ 'Root Account'
54
+ end
55
+
56
+ def determine_default_account_subdomain
57
+ Cadenero.default_account_subdomain = options["default-account-subdomain"].presence ||
58
+ ask("What will be the subdomain for the default account? [www]").presence ||
59
+ 'www'
60
+ end
61
+
62
+ def determine_default_user_email
63
+ Cadenero.default_user_email = options["default-user-email"].presence ||
64
+ ask("What will be the email for the default user owner of the default account? [testy@example.com]").presence ||
65
+ 'testy@example.com'
66
+ end
67
+
68
+ def determine_default_user_password
69
+ Cadenero.default_user_password = options["default-user-password "].presence ||
70
+ ask("What will be the password for the default user owner of the default account? [change-me]").presence ||
71
+ 'change-me'
72
+ end
73
+
46
74
  def add_cadenero_initializer
47
75
  path = "#{Rails.root}/config/initializers/cadenero.rb"
48
76
  if File.exists?(path)
@@ -62,6 +90,11 @@ module Cadenero
62
90
  end
63
91
 
64
92
  def seed_database
93
+ puts "default_account_name: #{Cadenero.default_account_name}"
94
+ puts "default_account_subdomain: #{Cadenero.default_account_subdomain}"
95
+ puts "default_user_email: #{Cadenero.default_user_email}"
96
+ puts "default_user_password: #{Cadenero.default_user_password}"
97
+
65
98
  load "#{Rails.root}/config/initializers/cadenero.rb"
66
99
  unless options["no-migrate"]
67
100
  puts "Creating default cadenero account and owner"
@@ -73,10 +106,11 @@ module Cadenero
73
106
  puts "Mounting Cadenero::Engine at \"/\" in config/routes.rb..."
74
107
  insert_into_file("#{Rails.root}/config/routes.rb", :after => /routes.draw.do\n/) do
75
108
  %Q{
76
- # This line mounts Cadenero's routes at / by default.
109
+ mount Cadenero::Engine, :at => "/" # This line mounts Cadenero's routes at / by default.
77
110
  # This means, any requests to the / URL of your application will go to Cadenero::V1:Account::DashboardController#index.
78
111
  # If you would like to change where this extension is mounted, simply change the :at option to something different
79
112
  # but that is discourage, the idea is to protect the whole site
113
+
80
114
  }
81
115
  end
82
116
  end
@@ -88,8 +122,6 @@ module Cadenero
88
122
  Here's what happened:\n\n}
89
123
 
90
124
  output += step("Cadenero's migrations were copied over into db/migrate.\n")
91
- output += step("We created a new migration called AddCadeneroAdminToTable.
92
- This creates a new field called \"cadenero_admin\" on your #{user_class} model's table.\n")
93
125
  output += step("A new method called `cadenero_user` was inserted into your ApplicationController.
94
126
  This lets Cadenero know what the current user of your application is.\n")
95
127
  output += step("A new file was created at config/initializers/cadenero.rb
@@ -97,25 +129,16 @@ Here's what happened:\n\n}
97
129
 
98
130
  unless options["no-migrate"]
99
131
  output += step("`rake db:migrate` was run, running all the migrations against your database.\n")
100
- output += step("Seed forum and topic were loaded into your database.\n")
132
+ output += step("Seed account and user were loaded into your database.\n")
101
133
  end
102
134
  output += step("The engine was mounted in your config/routes.rb file using this line:
103
135
 
104
136
  mount Cadenero::Engine, :at => \"/\"
105
137
 
106
- If you want to change where the forums are located, just change the \"/forums\" path at the end of this line to whatever you want.")
138
+ If you want to change where the forums are located, just change the \"/\" path at the end of this line to whatever you want.")
107
139
  output += %Q{\nAnd finally:
108
140
 
109
141
  #{step("We told you that Cadenero has been successfully installed and walked you through the steps.")}}
110
- unless defined?(Devise)
111
- output += %Q{We have detected you're not using Devise (which is OK with us, really!), so there's one extra step you'll need to do.
112
-
113
- You'll need to define a "sign_in_path" method for Cadenero to use that points to the sign in path for your application. You can set Cadenero.sign_in_path to a String inside config/initializers/cadenero.rb to do this, or you can define it in your config/routes.rb file with a line like this:
114
-
115
- get '/users/sign_in', :to => "users#sign_in"
116
-
117
- Either way, Cadenero needs one of these two things in order to work properly. Please define them!}
118
- end
119
142
  output += "\nIf you have any questions, comments or issues, please post them on our issues page: http://github.com/AgilTec/cadenero/issues.\n\n"
120
143
  output += "Thanks for using Cadenero!"
121
144
  puts output
@@ -1,2 +1,8 @@
1
1
  class ApplicationController < ActionController::API
2
+
3
+ def cadenero_user
4
+ current_user
5
+ end
6
+ helper_method :cadenero_user
7
+
2
8
  end
@@ -0,0 +1,8 @@
1
+ @account = Cadenero::V1::Account.create!(name: 'Root Account',
2
+ subdomain: 'www',
3
+ owner: Cadenero::User.create!(email: 'testy@example.com',
4
+ password: '12345678',
5
+ password_confirmation: '12345678'))
6
+
7
+ @account.create_schema
8
+ @account.ensure_authentication_token!