Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
a3c80014
Commit
a3c80014
authored
Nov 08, 2018
by
Ash McKenzie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Relocate JSONWebToken::HMACToken from EE
parent
b3b9817e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
173 additions
and
2 deletions
+173
-2
changelogs/unreleased/ashmckenzie-hmac-token-decode-and-tests.yml
...gs/unreleased/ashmckenzie-hmac-token-decode-and-tests.yml
+5
-0
lib/json_web_token/hmac_token.rb
lib/json_web_token/hmac_token.rb
+28
-0
lib/json_web_token/token.rb
lib/json_web_token/token.rb
+7
-2
spec/lib/json_web_token/hmac_token_spec.rb
spec/lib/json_web_token/hmac_token_spec.rb
+133
-0
No files found.
changelogs/unreleased/ashmckenzie-hmac-token-decode-and-tests.yml
0 → 100644
View file @
a3c80014
---
title
:
Relocate JSONWebToken::HMACToken from EE
merge_request
:
22906
author
:
type
:
changed
lib/json_web_token/hmac_token.rb
0 → 100644
View file @
a3c80014
# frozen_string_literal: true
require
'jwt'
module
JSONWebToken
class
HMACToken
<
Token
IAT_LEEWAY
=
60
JWT_ALGORITHM
=
'HS256'
def
initialize
(
secret
)
super
()
@secret
=
secret
end
def
self
.
decode
(
token
,
secret
,
leeway:
IAT_LEEWAY
,
verify_iat:
true
)
JWT
.
decode
(
token
,
secret
,
true
,
leeway:
leeway
,
verify_iat:
verify_iat
,
algorithm:
JWT_ALGORITHM
)
end
def
encoded
JWT
.
encode
(
payload
,
secret
,
JWT_ALGORITHM
)
end
private
attr_reader
:secret
end
end
lib/json_web_token/token.rb
View file @
a3c80014
# frozen_string_literal: true
# frozen_string_literal: true
require
'securerandom'
module
JSONWebToken
module
JSONWebToken
class
Token
class
Token
attr_accessor
:issuer
,
:subject
,
:audience
,
:id
attr_accessor
:issuer
,
:subject
,
:audience
,
:id
attr_accessor
:issued_at
,
:not_before
,
:expire_time
attr_accessor
:issued_at
,
:not_before
,
:expire_time
DEFAULT_NOT_BEFORE_TIME
=
5
DEFAULT_EXPIRE_TIME
=
60
def
initialize
def
initialize
@id
=
SecureRandom
.
uuid
@id
=
SecureRandom
.
uuid
@issued_at
=
Time
.
now
@issued_at
=
Time
.
now
# we give a few seconds for time shift
# we give a few seconds for time shift
@not_before
=
issued_at
-
5
.
seconds
@not_before
=
issued_at
-
DEFAULT_NOT_BEFORE_TIME
# default 60 seconds should be more than enough for this authentication token
# default 60 seconds should be more than enough for this authentication token
@expire_time
=
issued_at
+
1
.
minute
@expire_time
=
issued_at
+
DEFAULT_EXPIRE_TIME
@custom_payload
=
{}
@custom_payload
=
{}
end
end
...
...
spec/lib/json_web_token/hmac_token_spec.rb
0 → 100644
View file @
a3c80014
# frozen_string_literal: true
require
'json'
require
'timecop'
describe
JSONWebToken
::
HMACToken
do
let
(
:secret
)
{
'shh secret squirrel'
}
shared_examples
'a valid, non-expired token'
do
it
'is an Array with two elements'
do
expect
(
decoded_token
).
to
be_a
(
Array
)
expect
(
decoded_token
.
count
).
to
eq
(
2
)
end
it
'contains the following keys in the first Array element Hash - jti, iat, nbf, exp'
do
expect
(
decoded_token
[
0
].
keys
).
to
include
(
'jti'
,
'iat'
,
'nbf'
,
'exp'
)
end
it
'contains the following keys in the second Array element Hash - typ and alg'
do
expect
(
decoded_token
[
1
][
'typ'
]).
to
eql
(
'JWT'
)
expect
(
decoded_token
[
1
][
'alg'
]).
to
eql
(
'HS256'
)
end
end
describe
'.decode'
do
let
(
:leeway
)
{
described_class
::
IAT_LEEWAY
}
let
(
:decoded_token
)
{
described_class
.
decode
(
encoded_token
,
secret
,
leeway:
leeway
)
}
context
'with an invalid token'
do
context
'that is junk'
do
let
(
:encoded_token
)
{
'junk'
}
it
"raises exception saying 'Not enough or too many segments'"
do
expect
{
decoded_token
}.
to
raise_error
(
JWT
::
DecodeError
,
'Not enough or too many segments'
)
end
end
context
'that has been fiddled with'
do
let
(
:encoded_token
)
do
described_class
.
new
(
secret
).
encoded
.
tap
{
|
token
|
token
[
0
]
=
'E'
}
end
it
"raises exception saying 'Invalid segment encoding'"
do
expect
{
decoded_token
}.
to
raise_error
(
JWT
::
DecodeError
,
'Invalid segment encoding'
)
end
end
context
'that was generated using a different secret'
do
let
(
:encoded_token
)
{
described_class
.
new
(
'some other secret'
).
encoded
}
it
"raises exception saying 'Signature verification raised"
do
expect
{
decoded_token
}.
to
raise_error
(
JWT
::
VerificationError
,
'Signature verification raised'
)
end
end
context
'that is expired'
do
# Needs the ! so Timecop.freeze() is effective
let!
(
:encoded_token
)
{
described_class
.
new
(
secret
).
encoded
}
it
"raises exception saying 'Signature has expired'"
do
# Needs to be 120 seconds, because the default expiry is 60 seconds
# with an additional 60 second leeway.
Timecop
.
freeze
(
Time
.
now
+
120
)
do
expect
{
decoded_token
}.
to
raise_error
(
JWT
::
ExpiredSignature
,
'Signature has expired'
)
end
end
end
end
context
'with a valid token'
do
let
(
:encoded_token
)
do
hmac_token
=
described_class
.
new
(
secret
)
hmac_token
.
expire_time
=
Time
.
now
+
expire_time
hmac_token
.
encoded
end
context
'that has expired'
do
let
(
:expire_time
)
{
0
}
context
'with the default leeway'
do
Timecop
.
freeze
(
Time
.
now
+
1
)
do
it_behaves_like
'a valid, non-expired token'
end
end
context
'with a leeway of 0 seconds'
do
let
(
:leeway
)
{
0
}
it
"raises exception saying 'Signature has expired'"
do
Timecop
.
freeze
(
Time
.
now
+
1
)
do
expect
{
decoded_token
}.
to
raise_error
(
JWT
::
ExpiredSignature
,
'Signature has expired'
)
end
end
end
end
context
'that has not expired'
do
let
(
:expire_time
)
{
described_class
::
DEFAULT_EXPIRE_TIME
}
it_behaves_like
'a valid, non-expired token'
end
end
end
describe
'#encoded'
do
let
(
:decoded_token
)
{
described_class
.
decode
(
encoded_token
,
secret
)
}
context
'without data'
do
let
(
:encoded_token
)
{
described_class
.
new
(
secret
).
encoded
}
it_behaves_like
'a valid, non-expired token'
end
context
'with data'
do
let
(
:data
)
{
{
secret_key:
'secret value'
}.
to_json
}
let
(
:encoded_token
)
do
ec
=
described_class
.
new
(
secret
)
ec
[
:data
]
=
data
ec
.
encoded
end
it_behaves_like
'a valid, non-expired token'
it
"contains the 'data' key in the first Array element Hash"
do
expect
(
decoded_token
[
0
]).
to
have_key
(
'data'
)
end
it
'can re-read back the data'
do
expect
(
decoded_token
[
0
][
'data'
]).
to
eql
(
data
)
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment