pollett 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +81 -0
  4. data/Rakefile +25 -0
  5. data/app/controllers/concerns/pollett/controller.rb +37 -0
  6. data/app/controllers/pollett/application_controller.rb +4 -0
  7. data/app/controllers/pollett/keys_controller.rb +5 -0
  8. data/app/controllers/pollett/sessions_controller.rb +5 -0
  9. data/app/controllers/pollett/users_controller.rb +5 -0
  10. data/app/mailers/pollett/mailer.rb +5 -0
  11. data/app/models/concerns/pollett/user.rb +40 -0
  12. data/app/models/pollett/context.rb +5 -0
  13. data/app/models/pollett/key.rb +5 -0
  14. data/app/models/pollett/session.rb +5 -0
  15. data/app/serializers/pollett/key_serializer.rb +5 -0
  16. data/app/serializers/pollett/session_serializer.rb +5 -0
  17. data/app/serializers/user_serializer.rb +3 -0
  18. data/app/services/pollett/authenticate_user.rb +5 -0
  19. data/app/services/pollett/change_password.rb +5 -0
  20. data/app/services/pollett/create_session.rb +5 -0
  21. data/app/services/pollett/register_user.rb +5 -0
  22. data/app/services/pollett/reset_password.rb +5 -0
  23. data/app/views/pollett/mailer/reset.text.erb +5 -0
  24. data/app/views/pollett/mailer/welcome.text.erb +1 -0
  25. data/config/locales/en.yml +14 -0
  26. data/config/routes.rb +11 -0
  27. data/db/migrate/20150226024506_create_pollett_contexts.rb +21 -0
  28. data/lib/generators/pollett/install/install_generator.rb +123 -0
  29. data/lib/generators/pollett/install/templates/db/migrate/add_pollett_to_users.rb +21 -0
  30. data/lib/generators/pollett/install/templates/db/migrate/create_users.rb +15 -0
  31. data/lib/generators/pollett/install/templates/initializer.rb +3 -0
  32. data/lib/generators/pollett/install/templates/user.rb +3 -0
  33. data/lib/pollett.rb +20 -0
  34. data/lib/pollett/concerns.rb +5 -0
  35. data/lib/pollett/concerns/controllers.rb +3 -0
  36. data/lib/pollett/concerns/controllers/keys_controller.rb +37 -0
  37. data/lib/pollett/concerns/controllers/sessions_controller.rb +43 -0
  38. data/lib/pollett/concerns/controllers/users_controller.rb +28 -0
  39. data/lib/pollett/concerns/mailers.rb +1 -0
  40. data/lib/pollett/concerns/mailers/mailer.rb +24 -0
  41. data/lib/pollett/concerns/models.rb +3 -0
  42. data/lib/pollett/concerns/models/context.rb +42 -0
  43. data/lib/pollett/concerns/models/key.rb +13 -0
  44. data/lib/pollett/concerns/models/session.rb +20 -0
  45. data/lib/pollett/concerns/serializers.rb +2 -0
  46. data/lib/pollett/concerns/serializers/context_serializer.rb +21 -0
  47. data/lib/pollett/concerns/serializers/user_serializer.rb +16 -0
  48. data/lib/pollett/concerns/services.rb +5 -0
  49. data/lib/pollett/concerns/services/authenticate_user.rb +21 -0
  50. data/lib/pollett/concerns/services/change_password.rb +21 -0
  51. data/lib/pollett/concerns/services/create_session.rb +27 -0
  52. data/lib/pollett/concerns/services/register_user.rb +29 -0
  53. data/lib/pollett/concerns/services/reset_password.rb +27 -0
  54. data/lib/pollett/configuration.rb +34 -0
  55. data/lib/pollett/engine.rb +12 -0
  56. data/lib/pollett/rspec.rb +6 -0
  57. data/lib/pollett/testing/request_helper.rb +106 -0
  58. data/lib/pollett/version.rb +3 -0
  59. data/spec/dummy/README.rdoc +28 -0
  60. data/spec/dummy/Rakefile +6 -0
  61. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  62. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  63. data/spec/dummy/app/controllers/application_controller.rb +12 -0
  64. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  65. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  66. data/spec/dummy/app/models/user.rb +3 -0
  67. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  68. data/spec/dummy/app/views/layouts/mailer.text.erb +6 -0
  69. data/spec/dummy/bin/bundle +3 -0
  70. data/spec/dummy/bin/rails +4 -0
  71. data/spec/dummy/bin/rake +4 -0
  72. data/spec/dummy/bin/setup +29 -0
  73. data/spec/dummy/config.ru +4 -0
  74. data/spec/dummy/config/application.rb +32 -0
  75. data/spec/dummy/config/boot.rb +5 -0
  76. data/spec/dummy/config/database.yml +85 -0
  77. data/spec/dummy/config/environment.rb +5 -0
  78. data/spec/dummy/config/environments/development.rb +41 -0
  79. data/spec/dummy/config/environments/production.rb +79 -0
  80. data/spec/dummy/config/environments/test.rb +42 -0
  81. data/spec/dummy/config/initializers/active_model_serializers.rb +1 -0
  82. data/spec/dummy/config/initializers/assets.rb +11 -0
  83. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  84. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  85. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  86. data/spec/dummy/config/initializers/inflections.rb +16 -0
  87. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  88. data/spec/dummy/config/initializers/session_store.rb +3 -0
  89. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  90. data/spec/dummy/config/locales/en.yml +23 -0
  91. data/spec/dummy/config/routes.rb +3 -0
  92. data/spec/dummy/config/secrets.yml +22 -0
  93. data/spec/dummy/db/migrate/20150226030314_enable_uuid_extension.rb +5 -0
  94. data/spec/dummy/db/migrate/20150226030315_create_users.rb +15 -0
  95. data/spec/dummy/db/migrate/20150226030316_create_pollett_contexts.pollett.rb +22 -0
  96. data/spec/dummy/db/schema.rb +49 -0
  97. data/spec/dummy/log/development.log +1315 -0
  98. data/spec/dummy/log/test.log +181283 -0
  99. data/spec/dummy/public/404.html +67 -0
  100. data/spec/dummy/public/422.html +67 -0
  101. data/spec/dummy/public/500.html +66 -0
  102. data/spec/dummy/public/favicon.ico +0 -0
  103. data/spec/factories/pollett_context.rb +5 -0
  104. data/spec/factories/pollett_key.rb +5 -0
  105. data/spec/factories/pollett_session.rb +5 -0
  106. data/spec/factories/user.rb +7 -0
  107. data/spec/mailers/pollett/mailer_spec.rb +73 -0
  108. data/spec/rails_helper.rb +19 -0
  109. data/spec/requests/keys_spec.rb +67 -0
  110. data/spec/requests/sessions_spec.rb +176 -0
  111. data/spec/requests/user_spec.rb +41 -0
  112. data/spec/spec_helper.rb +9 -0
  113. data/spec/support/email_helper.rb +9 -0
  114. metadata +323 -0
@@ -0,0 +1,21 @@
1
+ class AddPollettToUsers < ActiveRecord::Migration
2
+ def up
3
+ change_table :users do |t|
4
+ <% config[:new_columns].values.each do |column| -%>
5
+ <%= column %>
6
+ <% end -%>
7
+ end
8
+
9
+ <% config[:new_indexes].values.each do |index| -%>
10
+ <%= index %>
11
+ <% end -%>
12
+ end
13
+
14
+ def down
15
+ change_table :users do |t|
16
+ <% if config[:new_columns].any? -%>
17
+ t.remove <%= new_columns.keys.map { |column| ":#{column}" }.join(",") %>
18
+ <% end -%>
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users, id: :uuid do |t|
4
+ t.string :name, null: false
5
+ t.string :email, null: false
6
+ t.string :password_digest, null: false
7
+ t.string :reset_token
8
+
9
+ t.timestamps null: false
10
+ end
11
+
12
+ add_index :users, :email, unique: true
13
+ add_index :users, :reset_token, unique: true
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ Pollett.configure do |config|
2
+ config.reset_url = ->(token) { "https://example.com/#{token}/reset" }
3
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ include Pollett::User
3
+ end
data/lib/pollett.rb ADDED
@@ -0,0 +1,20 @@
1
+ require "active_model_serializers"
2
+ require "servitore"
3
+
4
+ require "pollett/concerns"
5
+ require "pollett/configuration"
6
+ require "pollett/engine"
7
+
8
+ module Pollett
9
+ Unauthorized = Class.new(StandardError)
10
+
11
+ TOKEN_LENGTH = 32
12
+
13
+ def self.generate_token(length = TOKEN_LENGTH)
14
+ SecureRandom.urlsafe_base64(length)
15
+ end
16
+
17
+ def self.reset_url(token)
18
+ config.reset_url.call(token)
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ require "pollett/concerns/controllers"
2
+ require "pollett/concerns/mailers"
3
+ require "pollett/concerns/models"
4
+ require "pollett/concerns/serializers"
5
+ require "pollett/concerns/services"
@@ -0,0 +1,3 @@
1
+ require "pollett/concerns/controllers/users_controller"
2
+ require "pollett/concerns/controllers/sessions_controller"
3
+ require "pollett/concerns/controllers/keys_controller"
@@ -0,0 +1,37 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Controllers
4
+ module KeysController
5
+ extend ActiveSupport::Concern
6
+
7
+ def index
8
+ render_list(scoped)
9
+ end
10
+
11
+ def create
12
+ key = current_user.keys.create!(safe_params)
13
+ render json: key, status: :created
14
+ end
15
+
16
+ def show
17
+ key = scoped.find(params[:id])
18
+ render json: key, status: :ok
19
+ end
20
+
21
+ def destroy
22
+ scoped.find(params[:id]).revoke!
23
+ head :no_content
24
+ end
25
+
26
+ private
27
+ def safe_params
28
+ params.permit(:client)
29
+ end
30
+
31
+ def scoped
32
+ current_user.keys.active
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Controllers
4
+ module SessionsController
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ skip_authentication only: [:create, :forgot]
9
+ end
10
+
11
+ def index
12
+ render_list(scoped)
13
+ end
14
+
15
+ def show
16
+ session = scoped.find(params[:id])
17
+ render json: session, status: :ok
18
+ end
19
+
20
+ def create
21
+ session = CreateSession.call(params)
22
+ activate_context(session)
23
+ render json: session, status: :created
24
+ end
25
+
26
+ def forgot
27
+ ResetPassword.call(params)
28
+ render json: { status: :accepted }, status: :accepted
29
+ end
30
+
31
+ def destroy
32
+ scoped.find(params[:id]).revoke!
33
+ head :no_content
34
+ end
35
+
36
+ private
37
+ def scoped
38
+ current_user.sessions.active
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Controllers
4
+ module UsersController
5
+ extend ActiveSupport::Concern
6
+
7
+ def show
8
+ render json: current_user, status: :ok
9
+ end
10
+
11
+ def update
12
+ current_user.update!(safe_params)
13
+ render json: current_user, status: :ok
14
+ end
15
+
16
+ def destroy
17
+ current_user.destroy
18
+ head :no_content
19
+ end
20
+
21
+ private
22
+ def safe_params
23
+ params.permit(:name, :email, :password)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1 @@
1
+ require "pollett/concerns/mailers/mailer"
@@ -0,0 +1,24 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Mailers
4
+ module Mailer
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ default from: Pollett.config.from_email if Pollett.config.from_email
9
+ end
10
+
11
+ def welcome(user)
12
+ @user = user
13
+ mail(to: user.email)
14
+ end
15
+
16
+ def reset(user)
17
+ @user = user
18
+ @url = Pollett.reset_url(user.reset_token)
19
+ mail(to: user.email)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ require "pollett/concerns/models/context"
2
+ require "pollett/concerns/models/session"
3
+ require "pollett/concerns/models/key"
@@ -0,0 +1,42 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Models
4
+ module Context
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ belongs_to :user, class_name: Pollett.config.user_model_name
9
+
10
+ scope :active, -> { where("((type = 'Pollett::Session' AND accessed_at >= ?) OR (type = 'Pollett::Key')) AND revoked_at IS NULL", Pollett.config.timeout.ago) }
11
+ end
12
+
13
+ module ClassMethods
14
+ def authenticate(id)
15
+ active.find_by(id: id)
16
+ end
17
+ end
18
+
19
+ def revoked
20
+ revoked_at?
21
+ end
22
+
23
+ def active
24
+ !revoked
25
+ end
26
+
27
+ def access(request)
28
+ update({
29
+ accessed_at: current_time_from_proper_timezone,
30
+ ip: request.remote_ip,
31
+ user_agent: request.user_agent
32
+ })
33
+ end
34
+
35
+ def revoke!
36
+ self.revoked_at ||= current_time_from_proper_timezone
37
+ save!
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Models
4
+ module Key
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ validates :client, presence: true
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Models
4
+ module Session
5
+ extend ActiveSupport::Concern
6
+
7
+ CLIENT = "App"
8
+
9
+ included do
10
+ before_create :set_client
11
+ end
12
+
13
+ private
14
+ def set_client
15
+ self.client = CLIENT
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,2 @@
1
+ require "pollett/concerns/serializers/user_serializer"
2
+ require "pollett/concerns/serializers/context_serializer"
@@ -0,0 +1,21 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Serializers
4
+ module ContextSerializer
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attributes :client,
9
+ :active,
10
+ :ip,
11
+ :user_agent,
12
+ :accessed_at,
13
+ :created_at,
14
+ :updated_at
15
+
16
+ belongs_to :user
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Serializers
4
+ module UserSerializer
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attributes :created_at,
9
+ :updated_at,
10
+ :name,
11
+ :email
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ require "pollett/concerns/services/authenticate_user"
2
+ require "pollett/concerns/services/change_password"
3
+ require "pollett/concerns/services/create_session"
4
+ require "pollett/concerns/services/register_user"
5
+ require "pollett/concerns/services/reset_password"
@@ -0,0 +1,21 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Services
4
+ module AuthenticateUser
5
+ extend ActiveSupport::Concern
6
+
7
+ include Servitore::Service
8
+
9
+ included do
10
+ param_reader :email, :password
11
+ end
12
+
13
+ def call
14
+ Pollett.config.user_model.find_by_normalized_email(email).tap do |u|
15
+ raise Unauthorized unless u && u.authenticate(password)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Services
4
+ module ChangePassword
5
+ extend ActiveSupport::Concern
6
+
7
+ include Servitore::Service
8
+
9
+ included do
10
+ param_reader :token, :password
11
+ end
12
+
13
+ def call
14
+ Pollett.config.user_model.find_by!(reset_token: token).tap do |u|
15
+ u.update!(password: password, reset_token: nil)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Services
4
+ module CreateSession
5
+ extend ActiveSupport::Concern
6
+
7
+ include Servitore::Service
8
+
9
+ def call
10
+ user = service.call(_params)
11
+ user.sessions.create!
12
+ end
13
+
14
+ private
15
+ def service
16
+ @service ||= if _params.key?(:name)
17
+ Pollett::RegisterUser
18
+ elsif _params.key?(:token)
19
+ Pollett::ChangePassword
20
+ else
21
+ Pollett::AuthenticateUser
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module Pollett
2
+ module Concerns
3
+ module Services
4
+ module RegisterUser
5
+ extend ActiveSupport::Concern
6
+
7
+ include Servitore::Service
8
+
9
+ PERMITTED = [:name, :email, :password]
10
+
11
+ def call
12
+ Pollett.config.user_model.create!(safe_params).tap do |user|
13
+ deliver_email(user) if Pollett.config.send_welcome_email
14
+ end
15
+ end
16
+
17
+ private
18
+ def safe_params
19
+ permitted = Pollett.config.whitelist | PERMITTED
20
+ _params.permit(*permitted)
21
+ end
22
+
23
+ def deliver_email(user)
24
+ Mailer.welcome(user).deliver_later
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end