glogin 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/lib/glogin/codec.rb +76 -0
- data/lib/glogin/cookie.rb +11 -30
- data/lib/glogin/version.rb +1 -1
- data/test/glogin/test_codec.rb +53 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c119e131499ee21da88734113b234d547954e07
|
4
|
+
data.tar.gz: 1f8d5998346047a3c5d818b4d76510c1d23b5ef5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d49f67f6d1469db13a608e22c01bf3dda74065b5e9d95ef0c695fd321e79d81213b574a678d6f13c2894086aea3d2028c3221bd3a0a75017989866b058a85544
|
7
|
+
data.tar.gz: 64ebc43231b37ef27f359384fef145ad4b6aac34f07c3003c183bb4a743fa7c724474583470cec6d8a9791f874579d9afc5fa10f7a0cf67f74d64041442232cb
|
data/lib/glogin/codec.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2017-2018 Yegor Bugayenko
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in all
|
12
|
+
# copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
|
22
|
+
require 'securerandom'
|
23
|
+
require 'openssl'
|
24
|
+
require 'digest/sha1'
|
25
|
+
require 'base64'
|
26
|
+
|
27
|
+
# Codec.
|
28
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
+
# Copyright:: Copyright (c) 2017-2018 Yegor Bugayenko
|
30
|
+
# License:: MIT
|
31
|
+
module GLogin
|
32
|
+
#
|
33
|
+
# Codec
|
34
|
+
#
|
35
|
+
class Codec
|
36
|
+
def initialize(secret)
|
37
|
+
raise 'Secret can\'t be nil' if secret.nil?
|
38
|
+
@secret = secret
|
39
|
+
end
|
40
|
+
|
41
|
+
def decrypt(text)
|
42
|
+
if @secret.empty?
|
43
|
+
text
|
44
|
+
else
|
45
|
+
cpr = cipher
|
46
|
+
cpr.decrypt
|
47
|
+
cpr.key = digest
|
48
|
+
plain = Base64.decode64(text)
|
49
|
+
raise OpenSSL::Cipher::CipherError if plain.empty?
|
50
|
+
decrypted = cpr.update(plain)
|
51
|
+
decrypted << cpr.final
|
52
|
+
salt, body = decrypted.to_s.force_encoding('UTF-8').split(' ', 2)
|
53
|
+
raise OpenSSL::Cipher::CipherError if salt.empty?
|
54
|
+
body
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def encrypt(text)
|
59
|
+
cpr = cipher
|
60
|
+
cpr.encrypt
|
61
|
+
cpr.key = digest
|
62
|
+
salt = SecureRandom.base64(Random.rand(8..32))
|
63
|
+
encrypted = cpr.update(salt + ' ' + text)
|
64
|
+
encrypted << cpr.final
|
65
|
+
Base64.encode64(encrypted.to_s)
|
66
|
+
end
|
67
|
+
|
68
|
+
def digest
|
69
|
+
Digest::SHA1.hexdigest(@secret)[0..31]
|
70
|
+
end
|
71
|
+
|
72
|
+
def cipher
|
73
|
+
OpenSSL::Cipher.new('aes-256-cbc')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/glogin/cookie.rb
CHANGED
@@ -48,25 +48,15 @@ module GLogin
|
|
48
48
|
# OpenSSL::Cipher::CipherError will be raised, which you have
|
49
49
|
# to catch in your applicaiton and ignore the login attempt.
|
50
50
|
def to_user
|
51
|
-
plain =
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
cpr = Cookie.cipher
|
56
|
-
cpr.decrypt
|
57
|
-
cpr.key = Cookie.digest(@secret)
|
58
|
-
decrypted = cpr.update(Base64.decode64(@text))
|
59
|
-
decrypted << cpr.final
|
60
|
-
decrypted.to_s
|
61
|
-
end
|
62
|
-
parts = plain.split('|', 3)
|
63
|
-
if !@secret.empty? && parts[2].to_s != @context
|
51
|
+
plain = Codec.new(@secret).decrypt(@text)
|
52
|
+
login, avatar, ctx = plain.split('|', 3)
|
53
|
+
if !@secret.empty? && ctx.to_s != @context
|
64
54
|
raise(
|
65
55
|
OpenSSL::Cipher::CipherError,
|
66
|
-
"Context '#{@context}' expected, but '#{
|
56
|
+
"Context '#{@context}' expected, but '#{ctx}' found"
|
67
57
|
)
|
68
58
|
end
|
69
|
-
{ login:
|
59
|
+
{ login: login, avatar: avatar }
|
70
60
|
end
|
71
61
|
end
|
72
62
|
|
@@ -83,23 +73,14 @@ module GLogin
|
|
83
73
|
|
84
74
|
# Returns the text you should drop back to the user as a cookie.
|
85
75
|
def to_s
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
76
|
+
Codec.new(@secret).encrypt(
|
77
|
+
[
|
78
|
+
@json['login'],
|
79
|
+
@json['avatar_url'],
|
80
|
+
@context
|
81
|
+
].join('|')
|
91
82
|
)
|
92
|
-
encrypted << cpr.final
|
93
|
-
Base64.encode64(encrypted.to_s)
|
94
83
|
end
|
95
84
|
end
|
96
|
-
|
97
|
-
def self.digest(secret)
|
98
|
-
Digest::SHA1.hexdigest(secret)[0..31]
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.cipher
|
102
|
-
OpenSSL::Cipher.new('aes-256-cbc')
|
103
|
-
end
|
104
85
|
end
|
105
86
|
end
|
data/lib/glogin/version.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2017-2018 Yegor Bugayenko
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in all
|
12
|
+
# copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
|
22
|
+
require 'minitest/autorun'
|
23
|
+
require_relative '../../lib/glogin/codec'
|
24
|
+
|
25
|
+
class TestCodec < Minitest::Test
|
26
|
+
def test_encodes_and_decodes
|
27
|
+
text = 'This is the text, дорогой товарищ'
|
28
|
+
assert_equal(
|
29
|
+
text,
|
30
|
+
Base64.decode64(Base64.encode64(text)).force_encoding('UTF-8')
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_encrypts_and_decrypts
|
35
|
+
crypt = GLogin::Codec.new('this is the secret key!')
|
36
|
+
text = 'This is the text, товарищ'
|
37
|
+
assert_equal(text, crypt.decrypt(crypt.encrypt(text)))
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_decrypts_with_invalid_password
|
41
|
+
assert_raises OpenSSL::Cipher::CipherError do
|
42
|
+
GLogin::Codec.new('the wrong key').decrypt(
|
43
|
+
GLogin::Codec.new('the right key').encrypt('the text')
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_decrypts_broken_text
|
49
|
+
assert_raises OpenSSL::Cipher::CipherError do
|
50
|
+
GLogin::Codec.new('the key').decrypt('этот текст не был зашифрован')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glogin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
@@ -131,9 +131,11 @@ files:
|
|
131
131
|
- glogin.gemspec
|
132
132
|
- lib/glogin.rb
|
133
133
|
- lib/glogin/auth.rb
|
134
|
+
- lib/glogin/codec.rb
|
134
135
|
- lib/glogin/cookie.rb
|
135
136
|
- lib/glogin/version.rb
|
136
137
|
- test/glogin/test_auth.rb
|
138
|
+
- test/glogin/test_codec.rb
|
137
139
|
- test/glogin/test_cookie.rb
|
138
140
|
- test/test__helper.rb
|
139
141
|
- test/test_glogin.rb
|
@@ -164,6 +166,7 @@ specification_version: 2
|
|
164
166
|
summary: Login/logout via GitHub OAuth for your web app
|
165
167
|
test_files:
|
166
168
|
- test/glogin/test_auth.rb
|
169
|
+
- test/glogin/test_codec.rb
|
167
170
|
- test/glogin/test_cookie.rb
|
168
171
|
- test/test__helper.rb
|
169
172
|
- test/test_glogin.rb
|