-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmodels.v
More file actions
85 lines (67 loc) · 2.35 KB
/
models.v
File metadata and controls
85 lines (67 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
module jwt
import json
import x.json2
import time
import encoding.base64
// JWTHeader represents the JWT Header contents
// it can be created using the `new_header` function
pub struct JWTHeader {
pub:
alg string
typ string = "JWT"
}
// new_header creates a new object of the JWTHeader struct
fn new_header(algorithm Algorithm) JWTHeader {
return JWTHeader {
alg: algorithm.name.str().to_upper()
}
}
// Token holds all information of a JWT
// it is created using the `parse_token` function
struct Token {
pub:
header JWTHeader
claims string
signature string
expiration int
}
// parse_claims is a generic function that parses the claims of token
// into a real struct
pub fn (t Token) parse_claims<T>() ?T {
return json.decode(T, t.claims)
}
// is_expired gives information about whether the token is expired or still valid
pub fn (t Token) is_expired() bool {
return t.expiration == -1 || time.unix(t.expiration) < time.now()
}
// parse_token takes a JWT string and creates a Token object
// if the given token ius invalid, an error will be thrown
pub fn parse_token(token_raw string) ?Token {
// split token
parts := token_raw.split(".")
// split token into different parts and create token struct
if parts.len != 3 { return error("Invalid token") }
// get header and add "==" if necessary in order to make the base64 string decodable
header_raw := if parts[0].len % 4 == 0 { parts[0] } else { parts[0] + "==" }
// get claims and add "==" if necessary in order to make the base64 string decodable
claims_raw := if parts[1].len % 4 == 0 { parts[1] } else { parts[1] + "==" }
// decode header & claims base64 string
decoded_header := base64.decode_str(header_raw)
decoded_claims := base64.decode_str(claims_raw)
// create a raw json object from the claims in order to check for the expiration
claims := json2.raw_decode(decoded_claims)?.as_map()
mut expiration_given := true
// check if the expiration timestamp was set
expiration_unix := claims["exp"] or {
expiration_given = false
json2.Null{}
}
token := Token {
header: json.decode(JWTHeader, decoded_header)?,
claims: decoded_claims,
signature: parts[2],
// set expiration if given, otherwise use -1 for unset
expiration: if expiration_given { expiration_unix.int() } else { -1 }
}
return token
}