aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/PyJWT/py2/jwt/__main__.py
blob: bf50aabf4afa8fe597590302432123ff56c3ddf2 (plain) (blame)
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()