glogin 0.2.4 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 357ad19636ac2af81c1ae7fa5cf8207d913b321f
4
- data.tar.gz: 4d3820c7c7bcbfb6a705d8c18915df06eb06d841
3
+ metadata.gz: c3c071f29aab8173a4e284f3474e9ec61fca2a35
4
+ data.tar.gz: e79f3c2070e7779837fbd91fd9ed57b238eab102
5
5
  SHA512:
6
- metadata.gz: c63d0a85c703d26b28661a6380aef6c1b85a1f1092a2926f715c081172f817ac42325b3aebf243685d1f853961550e6d127b298c8c2784162b1855b3b14749c1
7
- data.tar.gz: cf3c5ee83aaae89c7c1621bd90c506dae4fb51f654068341465ed1ecef60ea77626469f43aa94b25497902256a798fd3797b8c1d5c6a5646edbc79c587d2d642
6
+ metadata.gz: 843729ae29be1dc09908a270559dd7358e37ab37709b4a51412c98d8bf94bbe0d4f7ba7967f9e53453db62b3f2b07e4e1bdd2518d78d788fdd952fdad013f22b
7
+ data.tar.gz: 76185f8c23855c3929d84fe7df2adcdf492ab8efce2508d0b077b77cfbb44280ffd69be2ff4c9f1c644a4e61f702ba503884ceeb015752e4fbd5c32f47763994
data/.rubocop.yml CHANGED
@@ -7,7 +7,7 @@ AllCops:
7
7
 
8
8
  Metrics/MethodLength:
9
9
  Enabled: false
10
- Style/MultilineMethodCallIndentation:
10
+ Layout/MultilineMethodCallIndentation:
11
11
  Enabled: false
12
12
  Metrics/AbcSize:
13
13
  Enabled: false
data/README.md CHANGED
@@ -84,6 +84,12 @@ get '/logout' do
84
84
  end
85
85
  ```
86
86
 
87
+ It is recommended to provide the third "context" parameter to
88
+ `GLogin::Cookie::Closed` and `GLogin::Cookie::Open` constructors, in order
89
+ to enforce stronger security. The context may include the `User-Agent`
90
+ HTTP header of the user, their IP address, and so on. When anything
91
+ changes on the user side, they will be forced to re-login.
92
+
87
93
  One more thing is the login URL you will need for your front page. Here
88
94
  it is:
89
95
 
data/Rakefile CHANGED
@@ -40,6 +40,7 @@ Rake::TestTask.new(:test) do |test|
40
40
  Rake::Cleaner.cleanup_files(['coverage'])
41
41
  test.libs << 'lib' << 'test'
42
42
  test.pattern = 'test/**/test_*.rb'
43
+ test.warning = true
43
44
  test.verbose = false
44
45
  end
45
46
 
data/glogin.gemspec CHANGED
@@ -45,11 +45,11 @@ Gem::Specification.new do |s|
45
45
  s.test_files = s.files.grep(%r{^(test|features)/})
46
46
  s.rdoc_options = ['--charset=UTF-8']
47
47
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
48
- s.add_development_dependency 'codecov', '0.1.10'
49
- s.add_development_dependency 'minitest', '5.5.0'
50
- s.add_development_dependency 'rake', '12.0.0'
51
- s.add_development_dependency 'rdoc', '4.2.0'
52
- s.add_development_dependency 'rspec-rails', '3.1.0'
53
- s.add_development_dependency 'rubocop', '0.57'
54
- s.add_development_dependency 'rubocop-rspec', '1.5.1'
48
+ s.add_development_dependency 'codecov', '~>0.1'
49
+ s.add_development_dependency 'minitest', '~>5.5'
50
+ s.add_development_dependency 'rake', '~>12.0'
51
+ s.add_development_dependency 'rdoc', '~>4.2'
52
+ s.add_development_dependency 'rspec-rails', '~>3.1'
53
+ s.add_development_dependency 'rubocop', '~>0.57'
54
+ s.add_development_dependency 'rubocop-rspec', '~>1.5'
55
55
  end
data/lib/glogin/cookie.rb CHANGED
@@ -32,15 +32,21 @@ module GLogin
32
32
  # Secure cookie
33
33
  #
34
34
  class Cookie
35
- # Closed
35
+ # Closed cookie.
36
36
  class Closed
37
- def initialize(text, secret)
37
+ def initialize(text, secret, context = '')
38
38
  raise 'Text can\'t be nil' if text.nil?
39
39
  @text = text
40
40
  raise 'Secret can\'t be nil' if secret.nil?
41
41
  @secret = secret
42
+ @context = context.to_s
42
43
  end
43
44
 
45
+ # Returns a hash with two elements: login and avatar.
46
+ # If the secret is empty, the text will be returned, without
47
+ # any decryption. If the data is not valid, an exception
48
+ # OpenSSL::Cipher::CipherError will be raised, which you have
49
+ # to catch in your applicaiton and ignore the login attempt.
44
50
  def to_user
45
51
  plain =
46
52
  if @secret.empty?
@@ -53,25 +59,36 @@ module GLogin
53
59
  decrypted << cpr.final
54
60
  decrypted.to_s
55
61
  end
56
- parts = plain.split('|')
62
+ parts = plain.split('|', 3)
63
+ unless parts[2].to_s == @context
64
+ raise(
65
+ OpenSSL::Cipher::CipherError,
66
+ "Context '#{@context}' expectected, but '#{parts[2]}' found"
67
+ )
68
+ end
57
69
  { login: parts[0], avatar: parts[1] }
58
70
  end
59
71
  end
60
72
 
61
73
  # Open
62
74
  class Open
63
- def initialize(json, secret)
75
+ # Here comes the JSON you receive from Auth.user()
76
+ def initialize(json, secret, context = '')
64
77
  raise 'JSON can\'t be nil' if json.nil?
65
78
  @json = json
66
79
  raise 'Secret can\'t be nil' if secret.nil?
67
80
  @secret = secret
81
+ @context = context.to_s
68
82
  end
69
83
 
84
+ # Returns the text you should drop back to the user as a cookie.
70
85
  def to_s
71
86
  cpr = Cookie.cipher
72
87
  cpr.encrypt
73
88
  cpr.key = Cookie.digest(@secret)
74
- encrypted = cpr.update("#{@json['login']}|#{@json['avatar_url']}")
89
+ encrypted = cpr.update(
90
+ "#{@json['login']}|#{@json['avatar_url']}|#{@context}"
91
+ )
75
92
  encrypted << cpr.final
76
93
  Base64.encode64(encrypted.to_s)
77
94
  end
@@ -82,7 +99,7 @@ module GLogin
82
99
  end
83
100
 
84
101
  def self.cipher
85
- OpenSSL::Cipher::Cipher.new('aes-256-cbc')
102
+ OpenSSL::Cipher.new('aes-256-cbc')
86
103
  end
87
104
  end
88
105
  end
@@ -24,5 +24,5 @@
24
24
  # Copyright:: Copyright (c) 2017-2018 Yegor Bugayenko
25
25
  # License:: MIT
26
26
  module GLogin
27
- VERSION = '0.2.4'.freeze
27
+ VERSION = '0.3'.freeze
28
28
  end
@@ -39,6 +39,22 @@ class TestCookie < Minitest::Test
39
39
  assert_equal(user[:avatar], 'https://avatars1.githubusercontent.com/u/526301')
40
40
  end
41
41
 
42
+ def test_encrypts_and_decrypts_with_context
43
+ secret = 'kfdj7hjsywhs6hjshr7shsw990s'
44
+ context = '127.0.0.1'
45
+ user = GLogin::Cookie::Closed.new(
46
+ GLogin::Cookie::Open.new(
47
+ JSON.parse('{"login":"jeffrey","avatar_url":"#"}'),
48
+ secret,
49
+ context
50
+ ).to_s,
51
+ secret,
52
+ context
53
+ ).to_user
54
+ assert_equal(user[:login], 'jeffrey')
55
+ assert_equal(user[:avatar], '#')
56
+ end
57
+
42
58
  def test_decrypts_in_test_mode
43
59
  user = GLogin::Cookie::Closed.new(
44
60
  'test|http://example.com', ''
@@ -58,4 +74,19 @@ class TestCookie < Minitest::Test
58
74
  ).to_user
59
75
  end
60
76
  end
77
+
78
+ def test_fails_on_wrong_context
79
+ secret = 'fdjruewoijs789fdsufds89f7ds89fs'
80
+ assert_raises OpenSSL::Cipher::CipherError do
81
+ GLogin::Cookie::Closed.new(
82
+ GLogin::Cookie::Open.new(
83
+ JSON.parse('{"login":"x","avatar_url":"x"}'),
84
+ secret,
85
+ 'context-1'
86
+ ).to_s,
87
+ secret,
88
+ 'context-2'
89
+ ).to_user
90
+ end
91
+ end
61
92
  end
metadata CHANGED
@@ -1,113 +1,113 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glogin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: '0.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-07 00:00:00.000000000 Z
11
+ date: 2018-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codecov
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.10
19
+ version: '0.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '='
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.10
26
+ version: '0.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 5.5.0
33
+ version: '5.5'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 5.5.0
40
+ version: '5.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 12.0.0
47
+ version: '12.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '='
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 12.0.0
54
+ version: '12.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rdoc
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '='
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 4.2.0
61
+ version: '4.2'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '='
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 4.2.0
68
+ version: '4.2'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec-rails
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '='
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 3.1.0
75
+ version: '3.1'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '='
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 3.1.0
82
+ version: '3.1'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '='
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.57'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '='
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.57'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop-rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '='
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.5.1
103
+ version: '1.5'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '='
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.5.1
110
+ version: '1.5'
111
111
  description: Enables login/logout functionality for a Ruby web app
112
112
  email: yegor256@gmail.com
113
113
  executables: []