|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +""" |
| 4 | +GENERATE APPROOV TOKEN CLI |
| 5 | +
|
| 6 | +To be used only to generate Approov tokens for testing purposes during development. |
| 7 | +
|
| 8 | +Usage: |
| 9 | + generate-token |
| 10 | + generate-token [--expire EXPIRE] [--claim CLAIM] [--claim-example] [--secret SECRET] |
| 11 | +
|
| 12 | +Options: |
| 13 | + --expire EXPIRE The Approov token expire time in minutes [default: 5]. |
| 14 | + --claim CLAIM The base64 encode sha256 hash of the custom payload claim for the Approov token. |
| 15 | + --claim-example Same as --claim but using an hard-coded claim example. |
| 16 | + --secret SECRET The base64 encoded secret to sign the Approov token for test purposes. |
| 17 | + -h --help Show this screen. |
| 18 | + -v --version Show version. |
| 19 | +
|
| 20 | +""" |
| 21 | + |
| 22 | +# Standard Libraries |
| 23 | +from os import getenv |
| 24 | +from sys import exit |
| 25 | +from time import time |
| 26 | +from hashlib import sha256 |
| 27 | +from base64 import b64decode, b64encode |
| 28 | + |
| 29 | +# Third-Party Libraries |
| 30 | +from jwt import encode |
| 31 | +from docopt import docopt |
| 32 | + |
| 33 | +# to base64 encode the custom payload claim hash: http://tomeko.net/online_tools/hex_to_base64.php |
| 34 | +REQUEST_CLAIM_RAW_VALUE_EXAMPLE = 'claim-value-to-be-sha256-hashed-and-base64-encoded' |
| 35 | + |
| 36 | +def _generateSha256HashBase64Encoded(value): |
| 37 | + value_hash = sha256(value.encode('utf-8')).digest() |
| 38 | + return b64encode(value_hash).decode('utf-8') |
| 39 | + |
| 40 | +def generateToken(approov_base64_secret, token_expire_in_minutes, request_claim_raw_value): |
| 41 | + """Generates a token with a 5 minutes lifetime. Optionally we can set also a custom payload claim.""" |
| 42 | + |
| 43 | + approov_base64_secret = approov_base64_secret.strip() |
| 44 | + |
| 45 | + if not approov_base64_secret: |
| 46 | + raise ValueError('Approov base64 encoded secret is missing.') |
| 47 | + |
| 48 | + if not token_expire_in_minutes: |
| 49 | + token_expire_in_minutes = 5 |
| 50 | + |
| 51 | + payload = { |
| 52 | + 'exp': time() + (60 * token_expire_in_minutes), # required - the timestamp for when the token expires. |
| 53 | + } |
| 54 | + |
| 55 | + if request_claim_raw_value: |
| 56 | + payload['pay'] = _generateSha256HashBase64Encoded(request_claim_raw_value) |
| 57 | + |
| 58 | + return encode(payload, b64decode(approov_base64_secret), algorithm='HS256').decode() |
| 59 | + |
| 60 | +def main(): |
| 61 | + |
| 62 | + arguments = docopt(__doc__, version='GENERATE APPROOV TOKEN CLI - 1.0') |
| 63 | + |
| 64 | + request_claim_raw_value = None |
| 65 | + token_expire_in_minutes = int(arguments['--expire']) |
| 66 | + approov_base64_secret = getenv("APPROOV_BASE64_SECRET") |
| 67 | + |
| 68 | + if arguments['--claim']: |
| 69 | + request_claim_raw_value = arguments['--claim'] |
| 70 | + |
| 71 | + if not request_claim_raw_value and arguments['--claim-example'] is True: |
| 72 | + request_claim_raw_value = REQUEST_CLAIM_RAW_VALUE_EXAMPLE |
| 73 | + |
| 74 | + if arguments['--secret']: |
| 75 | + approov_base64_secret = arguments['--secret'] |
| 76 | + |
| 77 | + if not approov_base64_secret: |
| 78 | + raise ValueError('--secret was provided as an empty string in the CLI or in the .env file.') |
| 79 | + |
| 80 | + token = generateToken(approov_base64_secret, token_expire_in_minutes, request_claim_raw_value) |
| 81 | + |
| 82 | + print('Token:\n', token) |
| 83 | + |
| 84 | + return token |
| 85 | + |
| 86 | +if __name__ == '__main__': |
| 87 | + try: |
| 88 | + main() |
| 89 | + exit(0) |
| 90 | + except Exception as error: |
| 91 | + print(error) |
| 92 | + exit(1) |
0 commit comments