shidare 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4979f2290dd0785914420877348d1f4b13fc67b59d50e0018836c0d1626c6920
4
- data.tar.gz: e0d7563622ef03fe34581856887755d473e6ddec7e4abc8eb184ad5f519bbc91
3
+ metadata.gz: 9c0e8a6f8c2a8f6d13a5c4d4bf5cd135f25bf385b36e84311e3d4ea6ca01ece6
4
+ data.tar.gz: 0aead697713967499706429cfb84f5293626a293dd8d562b2953160ffa6b40a2
5
5
  SHA512:
6
- metadata.gz: 94f649bc9af63972014ce047efabf488de09a6951b32aab332320c7ce4f75c42778e22fbcf0af420964b9a8937f3137a5929ecc59b6010f2d46931e2561b86e9
7
- data.tar.gz: d1f2aba3450a92abcaf514ba7a65c6a0d7c7b48e51c51989c495e3bd1776477a0a75ded5f7d96835832ea57a5b0aadb0eaf6b7ba95b3b192699ac3e34c58df68
6
+ metadata.gz: 25808f16260cdd5f04a76e46af055f33c19753a9fefbf1fbb95e12d4968f8b52b484951d9c6a9d050de069f24bb43d305fbdc38f2c59e2001d38fa089561e59f
7
+ data.tar.gz: 85f2dc8925418dacd55301e6d4cb94e628909fda77e38ffd9b71ef1f3df283d98efd59a68617f5b474d6bfab81202d72db631659e8d6ab6fa25faa03dd4eb92b
@@ -0,0 +1,27 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5
3
+
4
+ Exclude:
5
+ - 'vendor/bundle/**/*'
6
+ - 'shidare.gemspec'
7
+ - 'Rakefile'
8
+ - 'Gemfile'
9
+ - 'bin/*'
10
+
11
+ Style/FrozenStringLiteralComment:
12
+ Enabled: false
13
+
14
+ Style/Documentation:
15
+ Enabled: false
16
+
17
+ Metrics/BlockLength:
18
+ Exclude:
19
+ - 'spec/**/*'
20
+
21
+ Metrics/LineLength:
22
+ Exclude:
23
+ - 'spec/**/*'
24
+ Max: 100
25
+
26
+ Style/DoubleNegation:
27
+ Enabled: false
data/Gemfile CHANGED
@@ -2,5 +2,8 @@ source "https://rubygems.org"
2
2
 
3
3
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
- # Specify your gem's dependencies in shidare.gemspec
6
5
  gemspec
6
+
7
+ gem 'pg', require: false
8
+
9
+ gem 'rubocop', require: false
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Shidare
2
2
 
3
- Simple sessoin for hanami by bcrypt
3
+ Simple registration and session for Hanami
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,62 +18,172 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install shidare
20
20
 
21
- ## Usage
21
+ ## Setting
22
+
23
+ You should make `shidare` directory into `lib`
24
+
25
+ ```
26
+ lib
27
+ ├── app
28
+ │   ├── entities
29
+ │   ├── mailers
30
+ │   ├── repositories
31
+ │   └── shidare
32
+ └── app.rb
33
+ ```
34
+
35
+ And define `[model_name]Registration` into your `shidare` directory and include `Shidare::Registration`
36
+
37
+ example, `app/lib/shidare/user_registraion`
38
+
39
+ ```ruby
40
+ module UserRegistration
41
+ include Shidare::Registration
42
+ end
43
+ ```
44
+
45
+ next include `UserRegistration` in your action.
22
46
 
23
- Include your controller like below
47
+ example, `app/apps/web/controllers/users/create.rb`
24
48
 
25
49
  ```ruby
26
- module Web::controllers::Users
50
+ module Web::Controllers::Users
27
51
  class Create
28
52
  include Web::Action
29
- include Shidare::Authentication
30
-
53
+ include UserRegistration
54
+
31
55
  def call(params)
32
56
  end
33
57
  end
34
58
  end
59
+
35
60
  ```
36
- ## interface
37
- you can use below methods
38
61
 
39
- - login_as
40
- - logout_from
41
- - current_user
42
- - sigend_in?
62
+ ## Usage
43
63
 
44
- ## deteil description about above methods
64
+ ### Registration
45
65
 
46
- ### login_as
66
+ **must**
67
+
68
+ Add `email`, `encrypted_password`, `activation_token` and `activated_at` column to your model.
69
+ and `activation_token` and `activated_at` is **NOT** null index.
70
+
71
+ example, `db/migrations/[date]_create_users.rb`
47
72
 
48
73
  ```ruby
49
- login_as(UserRepository.new.first)
74
+ Hanami::Model.migration do
75
+ change do
76
+ create_table :users do
77
+ primary_key :id
78
+
79
+ column :email , String, null: false
80
+ column :encrypted_password, String, null: false
81
+ column :activation_token, String
82
+
83
+ column :created_at, DateTime, null: false
84
+ column :updated_at, DateTime, null: false
85
+ column :activated_at, DateTime
86
+ end
87
+ end
88
+ end
89
+
50
90
  ```
51
91
 
52
- then current_user(:user) will return current login user
92
+ provide
93
+ - `#signup_as`
94
+ - `#activate_[model_name]`
95
+ - `#activated?`
96
+
97
+ #### signup_as
98
+
99
+ ##### options
100
+ - `mail` (default is `false`)
53
101
 
54
- ### logout_from
102
+ Pass the `params`, so create record your into your model and activate.
55
103
 
56
104
  ```ruby
57
- logout_from(:user)
58
- ```
105
+ module Web::Controllers::Users
106
+ class Create
107
+ include Web::Action
108
+ include UserRegistration
59
109
 
60
- then logout current login user and current_user(:user) will return nil
110
+ def call(params)
111
+ signup_as(params[:user]) # params -> { email: 'test@example.com', password: 'password', ... }
112
+ end
113
+ end
114
+ end
115
+ ```
61
116
 
62
- ### current_user
117
+ If you pass the `mail: true`, you should define method `mailer` in your aciton class
63
118
 
64
119
  ```ruby
65
- current_user(:user)
120
+ module Web::Controllers::Users
121
+ class Create
122
+ include Web::Action
123
+ include UserRegistration
124
+
125
+ def call(params)
126
+ signup_as(params[:user], mail: true) # params -> { email: 'test@example.com', password: 'password', ... }
127
+ end
128
+
129
+ private
130
+
131
+ def mailer
132
+ Mailers::Welcome
133
+ end
134
+ end
135
+ end
66
136
  ```
67
137
 
68
- then return current login user entity
138
+ You can access entity attributes by `account` in your Mailer class
139
+
140
+ example `app/lib/mailers/welcome.rb`
141
+
142
+ ```ruby
143
+ class Mailers::Welcome
144
+ include Hanami::Mailer
145
+
146
+ from 'noreply@exmaple.com'
147
+ to :recipient
148
+ subject 'Hello'
149
+
150
+ private
151
+
152
+ def recipient
153
+ account.email
154
+ end
155
+
156
+ def token
157
+ account.activation_token
158
+ end
159
+ end
160
+
161
+ ```
69
162
 
70
- ### signed_in?
163
+ #### activate_[model_name]
71
164
 
72
165
  ```ruby
73
- signed_in(:user)
166
+ module Web::Controllers::Users
167
+ class AccountActivation
168
+ include Web::Action
169
+ include UserRegistration
170
+
171
+ def call(params)
172
+ acitivate_user(params) # params -> { email: 'user@example.com', activation_token: 'user_token' }
173
+ end
174
+ end
175
+ end
74
176
  ```
75
177
 
76
- then return true if login as user
178
+ #### activated?
179
+
180
+ If record is activated return `true`
181
+
182
+ exmaple
183
+
184
+ ```ruby
185
+ UserRepository.new.first.activated? # => true if user is activated
186
+ ```
77
187
 
78
188
  ## Development
79
189
 
@@ -12,5 +12,7 @@ require "shidare"
12
12
 
13
13
  require "irb"
14
14
 
15
- class A < Shidare::Authentication; end
15
+ require_relative '../spec/entities/user'
16
+ require_relative '../spec/repositories/user_repository'
17
+
16
18
  IRB.start(__FILE__)
@@ -1,37 +1,2 @@
1
- require "shidare/version"
2
- require 'bcrypt'
3
- require 'hanami/controller'
4
- require 'hanami/action/session'
5
-
6
- module Shidare
7
- class Authentication
8
- include Hanami::Action
9
- include Hanami::Action::Session
10
- def self.inherited(klass)
11
- entity_name = klass.to_s.gsub(/Authentication/, '').downcase
12
- klass.class_eval do
13
- define_method("current_#{entity_name}") do
14
- Object.const_get("#{entity_name.capitalize}Repository").new.find(session["#{entity_name}_id".to_sym])
15
- end
16
-
17
- end
18
- end
19
-
20
- def initialize(session)
21
- @session = session
22
- end
23
-
24
- def login(id)
25
- @session[:current_id] = id
26
- end
27
-
28
-
29
- def logout
30
- @session[:current_id] = nil
31
- end
32
-
33
- def signed_in?
34
- @session["current_id"] ? true : false
35
- end
36
- end
37
- end
1
+ require 'shidare/version'
2
+ require 'shidare/registration'
@@ -0,0 +1,4 @@
1
+ module Shidare
2
+ class AttributesError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Shidare
2
+ class InvalidParameter < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Shidare
2
+ class ModelNotGenerated < StandardError
3
+ end
4
+ end
@@ -0,0 +1,19 @@
1
+ require 'hanami/model'
2
+
3
+ module Shidare
4
+ module EntityExtension
5
+ refine Hanami::Entity.singleton_class do
6
+ def column?(attribute_name)
7
+ schema.instance_variable_get(:@attributes).key?(attribute_name)
8
+ end
9
+
10
+ def repository
11
+ Object.const_get("#{self}Repository")
12
+ end
13
+
14
+ def activatable?
15
+ column?(:activated_at) && column?(:activation_token)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ require 'hanami/model'
2
+
3
+ module Shidare
4
+ module RepositoryExtension
5
+ refine Hanami::Repository do
6
+ def by_email(email)
7
+ send(self.class.relation).where(email: email).limit(1).one
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ require 'hanami/utils'
2
+
3
+ module Shidare
4
+ module StringExtension
5
+ refine String do
6
+ def to_snake
7
+ gsub(/([A-Z])/, '_\1')[1..-1].downcase
8
+ end
9
+
10
+ def to_camel
11
+ split('_').map(&:capitalize).join
12
+ end
13
+
14
+ def pluralize
15
+ Hanami::Utils::Inflector.pluralize(self)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,124 @@
1
+ require 'shidare/version'
2
+ require 'bcrypt'
3
+ require 'securerandom'
4
+
5
+ require 'shidare/exceptions/attributes_error'
6
+ require 'shidare/exceptions/model_not_generated_error'
7
+
8
+ require 'shidare/extensions/string_extension'
9
+ require 'shidare/extensions/entity_extension'
10
+ require 'shidare/extensions/repository_extension'
11
+
12
+ module Shidare
13
+ module Registration
14
+ using StringExtension
15
+ using EntityExtension
16
+ using RepositoryExtension
17
+
18
+ class << self
19
+ def included(klass)
20
+ klass.class_eval do
21
+ entity = Object.const_get(klass.to_s.slice(/.*(?=Registration)/).to_camel)
22
+
23
+ entity.class_eval do
24
+ # Return entity is acitavated or not
25
+ #
26
+ # example:
27
+ # user = UserRepository.new.first
28
+ # user.activated?
29
+ #
30
+ # @return [Boolean] if entity is activated, return true
31
+ def activated?
32
+ !!activated_at
33
+ end
34
+ end
35
+
36
+ # Signup by parameters
37
+ #
38
+ # If you want to signup as paramger {name, email, password}
39
+ # use like below
40
+ # example:
41
+ # signup_as({ name: 'ippachi', email: 'test@example.com', password: 'password' })
42
+ #
43
+ # @param params [Hash] parameter you want to signup
44
+ # @param mail [Boolean] if you use mail activation, set true
45
+ #
46
+ # @return [Entity] signuped entity
47
+ define_method :signup_as do |params, mail: false|
48
+ define_signup_as(entity, params, mail)
49
+ end
50
+
51
+ # Activate specific entity by email and activation_token
52
+ #
53
+ # example:
54
+ # activate_user( { email: 'test@example.com', activation_token: 'example_token' } )
55
+ #
56
+ # @params params [Hash] parameter that has email and activation_token keys
57
+ #
58
+ # @return [Boolean] return false if account don't have specific email
59
+ define_method "activate_#{entity.to_s.to_snake}" do |params|
60
+ define_activate(entity, params)
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ # Return encrypted password by BCrypt
69
+ #
70
+ # @param password [String] password
71
+ #
72
+ # @return [String] encrypted string
73
+ def encrypted_password(password)
74
+ BCrypt::Password.create(password)
75
+ end
76
+
77
+ # Format params into suitable form for signup
78
+ #
79
+ # example:
80
+ # UserRepository.new.create(formated_params({ email: 'test@example.com', password: 'password' }))
81
+ #
82
+ # @param params [Hash] parameter that is using for signup
83
+ # @param mail [Boolean] set true, if you use mail activation
84
+ def formated_params(params, mail)
85
+ submit_params = params.dup
86
+
87
+ submit_params[:encrypted_password] \
88
+ = encrypted_password(params[:password])
89
+
90
+ if mail
91
+ submit_params[:activation_token] = token
92
+ else
93
+ submit_params[:activated_at] = Time.now
94
+ end
95
+
96
+ submit_params.tap { |param| param.delete(:password) }
97
+ end
98
+
99
+ # Return urlsafe token for account activation
100
+ #
101
+ # @return [String] token
102
+ def token
103
+ SecureRandom.urlsafe_base64
104
+ end
105
+
106
+ def define_signup_as(entity, params, mail)
107
+ raise AttributesError unless entity.column?(:encrypted_password)
108
+ if mail
109
+ raise AttributesError unless entity.activatable?
110
+ end
111
+ account = entity.repository.new.create(formated_params(params, mail))
112
+ mailer.deliver(account: account) if mail
113
+ account
114
+ end
115
+
116
+ def define_activate(entity, params)
117
+ account = entity.repository.new.by_email(params[:email])
118
+ return nil unless account && account.activation_token == params[:activation_token]
119
+ entity.repository.new.update(account.id, acitvation_token: nil, activated_at: Time.now)
120
+ end
121
+
122
+ def mailer; end
123
+ end
124
+ end
@@ -1,3 +1,3 @@
1
1
  module Shidare
2
- VERSION = "0.0.3"
2
+ VERSION = '0.0.4'.freeze
3
3
  end
@@ -32,9 +32,12 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "bundler", "~> 1.16"
33
33
  spec.add_development_dependency "rake", "~> 10.0"
34
34
  spec.add_development_dependency "rspec", "~> 3.0"
35
+ spec.add_development_dependency "pry"
35
36
 
36
- spec.add_runtime_dependency 'bcrypt', '~> 3.1'
37
- spec.add_runtime_dependency 'hanami-controller', '~> 1.1.0'
38
- spec.add_runtime_dependency 'hanami-model', '~> 1.1.0'
39
- spec.add_runtime_dependency 'hanami-router', '~> 1.1.0'
37
+ spec.add_runtime_dependency 'bcrypt'
38
+ spec.add_runtime_dependency 'hanami-controller', '>= 1.1.0'
39
+ spec.add_runtime_dependency 'hanami-model', '>= 1.1.0'
40
+ spec.add_runtime_dependency 'hanami-cli', '>= 0.1.0'
41
+ spec.add_runtime_dependency 'hanami-mailer', '>= 1.1.0'
42
+ spec.add_runtime_dependency 'hanami-utils', '>= 1.1.0'
40
43
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shidare
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ippachi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-09 00:00:00.000000000 Z
11
+ date: 2018-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,60 +52,102 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bcrypt
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - "~>"
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '3.1'
75
+ version: '0'
62
76
  type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - "~>"
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '3.1'
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: hanami-controller
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - "~>"
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
89
  version: 1.1.0
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - "~>"
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: 1.1.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: hanami-model
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - "~>"
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
103
  version: 1.1.0
90
104
  type: :runtime
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - "~>"
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: 1.1.0
97
111
  - !ruby/object:Gem::Dependency
98
- name: hanami-router
112
+ name: hanami-cli
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - "~>"
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 0.1.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 0.1.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: hanami-mailer
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
102
130
  - !ruby/object:Gem::Version
103
131
  version: 1.1.0
104
132
  type: :runtime
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
- - - "~>"
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 1.1.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: hanami-utils
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: 1.1.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
109
151
  - !ruby/object:Gem::Version
110
152
  version: 1.1.0
111
153
  description:
@@ -117,6 +159,7 @@ extra_rdoc_files: []
117
159
  files:
118
160
  - ".gitignore"
119
161
  - ".rspec"
162
+ - ".rubocop.yml"
120
163
  - ".travis.yml"
121
164
  - CODE_OF_CONDUCT.md
122
165
  - Gemfile
@@ -125,6 +168,13 @@ files:
125
168
  - bin/console
126
169
  - bin/setup
127
170
  - lib/shidare.rb
171
+ - lib/shidare/exceptions/attributes_error.rb
172
+ - lib/shidare/exceptions/invalid_parameter_error.rb
173
+ - lib/shidare/exceptions/model_not_generated_error.rb
174
+ - lib/shidare/extensions/entity_extension.rb
175
+ - lib/shidare/extensions/repository_extension.rb
176
+ - lib/shidare/extensions/string_extension.rb
177
+ - lib/shidare/registration.rb
128
178
  - lib/shidare/version.rb
129
179
  - shidare.gemspec
130
180
  homepage: https://github.com/ippachi/shidare