sequel_auth 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7520438387075590996072d0bf3f39a4590313d5cd4ac9ebbd7bfe75b7a4c1c6
4
+ data.tar.gz: 9e9619c3be523a75011aa8469b4704f9572df4d6d566f8d7fb2463243e20cdd1
5
+ SHA512:
6
+ metadata.gz: de9544a0e81aee9437200aa43f7a1dae108394a12e6a21a123fd4b95d450cbc8b878395318e96e608e53786cef005252547283ac386094d282219ec76b0ef781
7
+ data.tar.gz: 27b30df7effd4556194675dcd6d5e847a1dab66a7eb1565f37b5ae052dae47076ffd3eab6b2356cb294c58b41e9de63a1a9e59965b0c5f006a57e653aaa24f08
@@ -0,0 +1,35 @@
1
+ require "bcrypt"
2
+
3
+ module SequelAuth
4
+ module Providers
5
+ class Bcrypt
6
+ class << self
7
+
8
+ def cost
9
+ @cost ||= ::BCrypt::Engine.cost
10
+ end
11
+
12
+ def cost=(val)
13
+ raise ArgumentError,"cost < #{min_cost} not allowed!" if val < min_cost
14
+ @cost = val
15
+ end
16
+
17
+ def encrypt(password)
18
+ raise ArgumentError, "password not a valid string" if !password.is_a?(String) || password.strip.empty?
19
+ ::BCrypt::Password.create(password, cost: cost)
20
+ end
21
+
22
+ def matches?(hash,password)
23
+ ::BCrypt::Password.new(hash)==password
24
+ rescue ::BCrypt::Errors::InvalidHash
25
+ false
26
+ end
27
+
28
+ private
29
+ def min_cost
30
+ ::BCrypt::Engine::MIN_COST
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SequelAuth
4
+ module Providers
5
+ class Crypt
6
+ class << self
7
+
8
+ attr_writer :salt_prefix,:salt_size
9
+ # Salt prefix - prefix for random salt
10
+ def salt_prefix
11
+ @salt_prefix ||= defaults[:salt_prefix]
12
+ end
13
+
14
+ # Salt size - size as number
15
+ def salt_size
16
+ @salt_size ||= defaults[:salt_size]
17
+ end
18
+
19
+ def salt
20
+ salt_prefix + (salt_size-salt_prefix.length).times.map {
21
+ (('a'..'z').to_a + (1..9).to_a + ('A'..'Z').to_a).sample
22
+ }.join
23
+ end
24
+
25
+ def encrypt(password)
26
+ password.crypt(salt)
27
+ end
28
+
29
+ def matches?(hash, password)
30
+ password.crypt(hash) == hash
31
+ end
32
+
33
+ def defaults
34
+ {
35
+ salt_prefix: "$6$",
36
+ salt_size: 16,
37
+ }.freeze
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "scrypt"
4
+
5
+ module SequelAuth
6
+ module Providers
7
+ class Scrypt
8
+ class << self
9
+
10
+ attr_writer :key_len, :salt_size, :max_time, :max_mem, :max_memfrac
11
+ # Key length - length in bytes of generated key, from 16 to 512.
12
+ def key_len
13
+ @key_len ||= defaults[:key_len]
14
+ end
15
+
16
+ # Salt size - size in bytes of random salt, from 8 to 32
17
+ def salt_size
18
+ @salt_size ||= defaults[:salt_size]
19
+ end
20
+
21
+ # Max time - maximum time spent in computation
22
+ def max_time
23
+ @max_time ||= defaults[:max_time]
24
+ end
25
+
26
+ # Max memory - maximum memory usage. The minimum is always 1MB
27
+ def max_mem
28
+ @max_mem ||= defaults[:max_mem]
29
+ end
30
+
31
+ # Max memory fraction - maximum memory out of all available. Always
32
+ # greater than zero and <= 0.5.
33
+ def max_memfrac
34
+ @max_memfrac ||= defaults[:max_memfrac]
35
+ end
36
+
37
+ def encrypt(password)
38
+ ::SCrypt::Password.create(
39
+ password,
40
+ key_len: key_len,
41
+ salt_size: salt_size,
42
+ max_mem: max_mem,
43
+ max_memfrac: max_memfrac,
44
+ max_time: max_time
45
+ )
46
+ end
47
+
48
+ def matches?(hash, password)
49
+ ::SCrypt::Password.new(hash)==password
50
+ rescue ::SCrypt::Errors::InvalidHash
51
+ false
52
+ end
53
+
54
+ def defaults
55
+ {
56
+ key_len: 32,
57
+ salt_size: 8,
58
+ max_time: 0.2,
59
+ max_mem: 1024 * 1024,
60
+ max_memfrac: 0.5
61
+ }.freeze
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,92 @@
1
+ require "sequel"
2
+ require "securerandom"
3
+ require_relative "providers/bcrypt"
4
+ require_relative "providers/scrypt"
5
+ require_relative "providers/crypt"
6
+
7
+ module Sequel
8
+ module Plugins
9
+ module SequelAuth
10
+ def self.provider(provider,opts={})
11
+ provider = Kernel.const_get("SequelAuth::Providers::#{provider.to_s.capitalize}")
12
+ opts.each { |k,v| provider.public_send("#{k}=", v) }
13
+ provider
14
+ end
15
+
16
+ def self.configure(model, opts = {})
17
+ model.instance_eval do
18
+ @digest_column = opts.fetch(:digest_column, :password_digest)
19
+ @include_validations = opts.fetch(:include_validations, true)
20
+ @provider = SequelAuth.provider opts.fetch(:provider, :bcrypt),
21
+ opts.fetch(:provider_opts, {})
22
+ #Optional columns
23
+ @access_token_column = opts.fetch(:access_token_column, nil)
24
+ @login_count_column = opts.fetch(:login_count_column, nil)
25
+ @failed_login_count_column = opts.fetch(:failed_login_count_column, nil)
26
+ @last_login_at_column = opts.fetch(:last_login_at_column,nil)
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+ attr_reader :provider,
32
+ :digest_column,
33
+ :access_token_column,
34
+ :login_count_column,
35
+ :failed_login_count_column,
36
+ :last_login_at_column,
37
+ :include_validations
38
+
39
+ # NOTE: nil as a value means that the value of the instance variable
40
+ # will be assigned as is in the subclass.
41
+ Plugins.inherited_instance_variables(self, :@provider => nil,
42
+ :@include_validations => nil,
43
+ :@digest_column => nil)
44
+
45
+ end
46
+
47
+ module InstanceMethods
48
+ attr_accessor :password_confirmation
49
+ attr_reader :password
50
+ def password=(unencrypted)
51
+ @password = unencrypted
52
+ self.send "#{model.digest_column}=",model.provider.encrypt(unencrypted)
53
+ end
54
+
55
+ def authenticate(unencrypted)
56
+ if model.provider.matches?(self.send(model.digest_column),unencrypted)
57
+ if model.login_count_column || model.last_login_at_column
58
+ #Update login count
59
+ self.send("#{model.login_count_column}=",self.send(model.login_count_column)+1 ) if model.login_count_column
60
+ self.send("#{model.last_login_at_column}=",Time.now ) if model.last_login_at_column
61
+ self.save
62
+ end
63
+ self
64
+ else
65
+ if model.failed_login_count_column
66
+ #Update failed login count
67
+ self.send("#{model.failed_login_count_column}=",self.send(model.failed_login_count_column)+1 )
68
+ self.save
69
+ end
70
+ end
71
+ end
72
+
73
+ def reset_access_token
74
+ if model.access_token_column
75
+ self.update(model.access_token_column=>SecureRandom.urlsafe_base64(16))
76
+ end
77
+ end
78
+
79
+ def validate
80
+ super
81
+
82
+ if model.include_validations
83
+ errors.add :password, 'is not present' if password.nil? && new?
84
+ errors.add :password, 'doesn\'t match confirmation' if password != password_confirmation
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ module SequelAuth
6
+ VERSION = '0.0.6'
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel_auth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Fatih GENÇ
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 5.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: bcrypt
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.1'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.1'
47
+ - !ruby/object:Gem::Dependency
48
+ name: scrypt
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: sqlite3
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.4'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.4'
89
+ description: Plugin to add authentication methods to Sequel Model
90
+ email: fatihgnc@gmail.com
91
+ executables: []
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - lib/providers/bcrypt.rb
96
+ - lib/providers/crypt.rb
97
+ - lib/providers/scrypt.rb
98
+ - lib/sequel_auth.rb
99
+ - lib/sequel_auth/version.rb
100
+ homepage: https://gitlab.com/ikilifikir/sequel_auth
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubygems_version: 3.2.15
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Plugin to add authentication methods to Sequel Model Select one of crypt,
123
+ bcrypt, scrypt
124
+ test_files: []