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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
#!/usr/bin/env python
from __future__ import absolute_import, print_function
import argparse
import json
import sys
import time
from . import DecodeError, __version__, decode, encode
def encode_payload(args):
# Try to encode
if args.key is None:
raise ValueError('Key is required when encoding. See --help for usage.')
# Build payload object to encode
payload = {}
for arg in args.payload:
k, v = arg.split('=', 1)
# exp +offset special case?
if k == 'exp' and v[0] == '+' and len(v) > 1:
v = str(int(time.time()+int(v[1:])))
# Cast to integer?
if v.isdigit():
v = int(v)
else:
# Cast to float?
try:
v = float(v)
except ValueError:
pass
# Cast to true, false, or null?
constants = {'true': True, 'false': False, 'null': None}
if v in constants:
v = constants[v]
payload[k] = v
token = encode(
payload,
key=args.key,
algorithm=args.algorithm
)
return token.decode('utf-8')
def decode_payload(args):
try:
if args.token:
token = args.token
else:
if sys.stdin.isatty():
token = sys.stdin.readline().strip()
else:
raise IOError('Cannot read from stdin: terminal not a TTY')
token = token.encode('utf-8')
data = decode(token, key=args.key, verify=args.verify)
return json.dumps(data)
except DecodeError as e:
raise DecodeError('There was an error decoding the token: %s' % e)
def build_argparser():
usage = '''
Encodes or decodes JSON Web Tokens based on input.
%(prog)s [options] <command> [options] input
Decoding examples:
%(prog)s --key=secret decode json.web.token
%(prog)s decode --no-verify json.web.token
Encoding requires the key option and takes space separated key/value pairs
separated by equals (=) as input. Examples:
%(prog)s --key=secret encode iss=me exp=1302049071
%(prog)s --key=secret encode foo=bar exp=+10
The exp key is special and can take an offset to current Unix time.
'''
arg_parser = argparse.ArgumentParser(
prog='pyjwt',
usage=usage
)
arg_parser.add_argument(
'-v', '--version',
action='version',
version='%(prog)s ' + __version__
)
arg_parser.add_argument(
'--key',
dest='key',
metavar='KEY',
default=None,
help='set the secret key to sign with'
)
arg_parser.add_argument(
'--alg',
dest='algorithm',
metavar='ALG',
default='HS256',
help='set crypto algorithm to sign with. default=HS256'
)
subparsers = arg_parser.add_subparsers(
title='PyJWT subcommands',
description='valid subcommands',
help='additional help'
)
# Encode subcommand
encode_parser = subparsers.add_parser('encode', help='use to encode a supplied payload')
payload_help = """Payload to encode. Must be a space separated list of key/value
pairs separated by equals (=) sign."""
encode_parser.add_argument('payload', nargs='+', help=payload_help)
encode_parser.set_defaults(func=encode_payload)
# Decode subcommand
decode_parser = subparsers.add_parser('decode', help='use to decode a supplied JSON web token')
decode_parser.add_argument(
'token',
help='JSON web token to decode.',
nargs='?')
decode_parser.add_argument(
'-n', '--no-verify',
action='store_false',
dest='verify',
default=True,
help='ignore signature and claims verification on decode'
)
decode_parser.set_defaults(func=decode_payload)
return arg_parser
def main():
arg_parser = build_argparser()
try:
arguments = arg_parser.parse_args(sys.argv[1:])
output = arguments.func(arguments)
print(output)
except Exception as e:
print('There was an unforseen error: ', e)
arg_parser.print_help()
|