summaryrefslogtreecommitdiff
path: root/jwt/__main__.py
blob: 94abf2a5646eddab0fd64b3a5d6d370e48e0441a (plain)
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
#!/usr/bin/env python

from __future__ import absolute_import, print_function

import json
import optparse
import sys
import time

from . import DecodeError, __package__, __version__, decode, encode


def main():

    usage = '''Encodes or decodes JSON Web Tokens based on input.

  %prog [options] input

Decoding examples:

  %prog --key=secret json.web.token
  %prog --no-verify json.web.token

Encoding requires the key option and takes space separated key/value pairs
separated by equals (=) as input. Examples:

  %prog --key=secret iss=me exp=1302049071
  %prog --key=secret foo=bar exp=+10

The exp key is special and can take an offset to current Unix time.\
'''
    p = optparse.OptionParser(
        usage=usage,
        prog='pyjwt',
        version='%s %s' % (__package__, __version__),
    )

    p.add_option(
        '-n', '--no-verify',
        action='store_false',
        dest='verify',
        default=True,
        help='ignore signature and claims verification on decode'
    )

    p.add_option(
        '--key',
        dest='key',
        metavar='KEY',
        default=None,
        help='set the secret key to sign with'
    )

    p.add_option(
        '--alg',
        dest='algorithm',
        metavar='ALG',
        default='HS256',
        help='set crypto algorithm to sign with. default=HS256'
    )

    options, arguments = p.parse_args()

    if len(arguments) > 0 or not sys.stdin.isatty():
        if len(arguments) == 1 and (not options.verify or options.key):
            # Try to decode
            try:
                if not sys.stdin.isatty():
                    token = sys.stdin.read()
                else:
                    token = arguments[0]

                token = token.encode('utf-8')
                data = decode(token, key=options.key, verify=options.verify)

                print(json.dumps(data))
                sys.exit(0)
            except DecodeError as e:
                print(e)
                sys.exit(1)

        # Try to encode
        if options.key is None:
            print('Key is required when encoding. See --help for usage.')
            sys.exit(1)

        # Build payload object to encode
        payload = {}

        for arg in arguments:
            try:
                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
            except ValueError:
                print('Invalid encoding input at {}'.format(arg))
                sys.exit(1)

        try:
            token = encode(
                payload,
                key=options.key,
                algorithm=options.algorithm
            )

            print(token)
            sys.exit(0)
        except Exception as e:
            print(e)
            sys.exit(1)
    else:
        p.print_help()

if __name__ == '__main__':
    main()