__main__.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/env python
  2. from __future__ import absolute_import, print_function
  3. import argparse
  4. import json
  5. import sys
  6. import time
  7. from . import DecodeError, __version__, decode, encode
  8. def encode_payload(args):
  9. # Try to encode
  10. if args.key is None:
  11. raise ValueError('Key is required when encoding. See --help for usage.')
  12. # Build payload object to encode
  13. payload = {}
  14. for arg in args.payload:
  15. k, v = arg.split('=', 1)
  16. # exp +offset special case?
  17. if k == 'exp' and v[0] == '+' and len(v) > 1:
  18. v = str(int(time.time()+int(v[1:])))
  19. # Cast to integer?
  20. if v.isdigit():
  21. v = int(v)
  22. else:
  23. # Cast to float?
  24. try:
  25. v = float(v)
  26. except ValueError:
  27. pass
  28. # Cast to true, false, or null?
  29. constants = {'true': True, 'false': False, 'null': None}
  30. if v in constants:
  31. v = constants[v]
  32. payload[k] = v
  33. token = encode(
  34. payload,
  35. key=args.key,
  36. algorithm=args.algorithm
  37. )
  38. return token.decode('utf-8')
  39. def decode_payload(args):
  40. try:
  41. if args.token:
  42. token = args.token
  43. else:
  44. if sys.stdin.isatty():
  45. token = sys.stdin.readline().strip()
  46. else:
  47. raise IOError('Cannot read from stdin: terminal not a TTY')
  48. token = token.encode('utf-8')
  49. data = decode(token, key=args.key, verify=args.verify)
  50. return json.dumps(data)
  51. except DecodeError as e:
  52. raise DecodeError('There was an error decoding the token: %s' % e)
  53. def build_argparser():
  54. usage = '''
  55. Encodes or decodes JSON Web Tokens based on input.
  56. %(prog)s [options] <command> [options] input
  57. Decoding examples:
  58. %(prog)s --key=secret decode json.web.token
  59. %(prog)s decode --no-verify json.web.token
  60. Encoding requires the key option and takes space separated key/value pairs
  61. separated by equals (=) as input. Examples:
  62. %(prog)s --key=secret encode iss=me exp=1302049071
  63. %(prog)s --key=secret encode foo=bar exp=+10
  64. The exp key is special and can take an offset to current Unix time.
  65. '''
  66. arg_parser = argparse.ArgumentParser(
  67. prog='pyjwt',
  68. usage=usage
  69. )
  70. arg_parser.add_argument(
  71. '-v', '--version',
  72. action='version',
  73. version='%(prog)s ' + __version__
  74. )
  75. arg_parser.add_argument(
  76. '--key',
  77. dest='key',
  78. metavar='KEY',
  79. default=None,
  80. help='set the secret key to sign with'
  81. )
  82. arg_parser.add_argument(
  83. '--alg',
  84. dest='algorithm',
  85. metavar='ALG',
  86. default='HS256',
  87. help='set crypto algorithm to sign with. default=HS256'
  88. )
  89. subparsers = arg_parser.add_subparsers(
  90. title='PyJWT subcommands',
  91. description='valid subcommands',
  92. help='additional help'
  93. )
  94. # Encode subcommand
  95. encode_parser = subparsers.add_parser('encode', help='use to encode a supplied payload')
  96. payload_help = """Payload to encode. Must be a space separated list of key/value
  97. pairs separated by equals (=) sign."""
  98. encode_parser.add_argument('payload', nargs='+', help=payload_help)
  99. encode_parser.set_defaults(func=encode_payload)
  100. # Decode subcommand
  101. decode_parser = subparsers.add_parser('decode', help='use to decode a supplied JSON web token')
  102. decode_parser.add_argument(
  103. 'token',
  104. help='JSON web token to decode.',
  105. nargs='?')
  106. decode_parser.add_argument(
  107. '-n', '--no-verify',
  108. action='store_false',
  109. dest='verify',
  110. default=True,
  111. help='ignore signature and claims verification on decode'
  112. )
  113. decode_parser.set_defaults(func=decode_payload)
  114. return arg_parser
  115. def main():
  116. arg_parser = build_argparser()
  117. try:
  118. arguments = arg_parser.parse_args(sys.argv[1:])
  119. output = arguments.func(arguments)
  120. print(output)
  121. except Exception as e:
  122. print('There was an unforseen error: ', e)
  123. arg_parser.print_help()