Merge "Support custom claim and print meta info in zuul-admin create-auth-token"
This commit is contained in:
@@ -45,14 +45,22 @@ create-auth-token
|
||||
|
||||
Example::
|
||||
|
||||
zuul-admin create-auth-token --auth-config zuul-operator --user alice --tenant tenantA --expires-in 1800
|
||||
zuul-admin create-auth-token --auth-config zuul-operator --user alice --tenant tenantA --expires-in 1800 --print-meta-info
|
||||
|
||||
The return value is the value of the ``Authorization`` header the user must set
|
||||
when querying a protected endpoint on Zuul's REST API.
|
||||
when querying a protected endpoint on Zuul's REST API. The meta information of
|
||||
the token will be printed when "--print-meta-info" is specified.
|
||||
|
||||
Example::
|
||||
|
||||
bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vbWFuYWdlc2Yuc2ZyZG90ZXN0aW5zdGFuY2Uub3JnIiwienV1bC50ZW5hbnRzIjp7ImxvY2FsIjoiKiJ9LCJleHAiOjE1Mzc0MTcxOTguMzc3NTQ0fQ.DLbKx1J84wV4Vm7sv3zw9Bw9-WuIka7WkPQxGDAHz7s
|
||||
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NDEzNTAzMTksImV4cCI6MTc0MTM1MjExOSwiaXNzIjoienV1bF9vcGVyYXRvciIsImF1ZCI6Inp1dWwuZXhhbXBsZS5jb20iLCJzdWIiOiJhbGljZSIsInp1dWwiOnsiYWRtaW4iOlsidGVuYW50QSJdfX0.cW3U5LEFJS0TM-EDELZS9_hhbxdw-xObLwvDQKL55fM
|
||||
---------------- Meta Info ----------------
|
||||
Tenant: tenantA
|
||||
User: alice
|
||||
Generated At: 2025-03-07 12:25:19 UTC
|
||||
Expired At: 2025-03-07 12:55:19 UTC
|
||||
SHA1 Checksum: f52018044a209ce7eed5e587c41cc8b360af891d
|
||||
-------------------------------------------
|
||||
|
||||
.. _export-keys:
|
||||
|
||||
|
||||
@@ -153,14 +153,17 @@ class TestWebTokenClient(BaseClientTestCase):
|
||||
'create-auth-token',
|
||||
'--auth-conf', 'zuul_operator',
|
||||
'--user', 'marshmallow_man',
|
||||
'--tenant', 'tenant_one', ],
|
||||
'--tenant', 'tenant_one',
|
||||
'--claim', 'claim1:value1',
|
||||
'--claim', 'claim2:value2',
|
||||
'--print-meta-info', ],
|
||||
stdout=subprocess.PIPE)
|
||||
now = time.time()
|
||||
out, _ = p.communicate()
|
||||
self.assertEqual(p.returncode, 0, 'The command must exit 0')
|
||||
self.assertTrue(out.startswith(b"Bearer "), out)
|
||||
# there is a trailing carriage return in the output
|
||||
token = jwt.decode(out[len("Bearer "):-1],
|
||||
# Get the token from the first line of the output
|
||||
token = jwt.decode(out.split(b'\n')[0][len("Bearer "):],
|
||||
key=self.config.get(
|
||||
'auth zuul_operator',
|
||||
'secret'),
|
||||
@@ -173,12 +176,18 @@ class TestWebTokenClient(BaseClientTestCase):
|
||||
self.assertEqual('marshmallow_man', token.get('sub'))
|
||||
self.assertEqual('zuul_operator', token.get('iss'))
|
||||
self.assertEqual('zuul.example.com', token.get('aud'))
|
||||
self.assertEqual('value1', token.get('claim1'))
|
||||
self.assertEqual('value2', token.get('claim2'))
|
||||
admin_tenants = token.get('zuul', {}).get('admin', [])
|
||||
self.assertTrue('tenant_one' in admin_tenants, admin_tenants)
|
||||
# allow one minute for the process to run
|
||||
self.assertTrue(580 <= int(token['exp']) - now < 660,
|
||||
(token['exp'], now))
|
||||
|
||||
# Get the meta info from the second line of the output
|
||||
meta_info_header = out.split(b'\n')[1]
|
||||
self.assertIn("Meta Info", meta_info_header.decode('utf-8'))
|
||||
|
||||
|
||||
class TestKeyOperations(ZuulTestCase):
|
||||
tenant_config_file = 'config/single-tenant/main.yaml'
|
||||
|
||||
@@ -19,6 +19,7 @@ import babel.dates
|
||||
import datetime
|
||||
import dateutil.parser
|
||||
import dateutil.tz
|
||||
import hashlib
|
||||
import json
|
||||
import jwt
|
||||
import logging
|
||||
@@ -402,6 +403,18 @@ class Client(zuul.cmd.ZuulApp):
|
||||
type=int,
|
||||
default=600,
|
||||
required=False)
|
||||
cmd_create_auth_token.add_argument(
|
||||
'--claim',
|
||||
help=('Custom claim in format claim:value. It can '
|
||||
'be used multiple times to add multiple claims.'),
|
||||
action="extend",
|
||||
type=lambda x: tuple(x.split(':')),
|
||||
nargs='*',
|
||||
default=[])
|
||||
cmd_create_auth_token.add_argument(
|
||||
'--print-meta-info',
|
||||
action='store_true',
|
||||
help="When specified, the meta info of the token will be printed")
|
||||
cmd_create_auth_token.set_defaults(func=self.create_auth_token)
|
||||
|
||||
# Key storage
|
||||
@@ -740,13 +753,20 @@ class Client(zuul.cmd.ZuulApp):
|
||||
% self.args.auth_config)
|
||||
sys.exit(1)
|
||||
now = int(time.time())
|
||||
exp = now + self.args.expires_in
|
||||
token = {'iat': now,
|
||||
'exp': now + self.args.expires_in,
|
||||
'exp': exp,
|
||||
'iss': get_default(self.config, auth_section, 'issuer_id'),
|
||||
'aud': get_default(self.config, auth_section, 'client_id'),
|
||||
'sub': self.args.user,
|
||||
'zuul': {'admin': [self.args.tenant, ]},
|
||||
}
|
||||
|
||||
# Add custom claims, allow to overwrite default claims
|
||||
# when it is required.
|
||||
for k, v in self.args.claim:
|
||||
token[k] = v
|
||||
|
||||
driver = get_default(
|
||||
self.config, auth_section, 'driver')
|
||||
if driver == 'HS256':
|
||||
@@ -768,6 +788,17 @@ class Client(zuul.cmd.ZuulApp):
|
||||
key=key,
|
||||
algorithm=driver)
|
||||
print("Bearer %s" % auth_token)
|
||||
if self.args.print_meta_info:
|
||||
print("---------------- Meta Info ----------------")
|
||||
print("Tenant:\t\t%s" % self.args.tenant)
|
||||
print("User:\t\t%s" % self.args.user)
|
||||
print("Generated At:\t%s" % time.strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC", time.gmtime(now)))
|
||||
print("Expired At:\t%s" % time.strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC", time.gmtime(exp)))
|
||||
print("SHA1 Checksum:\t%s" % hashlib.sha1(
|
||||
auth_token.encode("utf-8")).hexdigest())
|
||||
print("-------------------------------------------")
|
||||
err_code = 0
|
||||
except Exception as e:
|
||||
print("Error when generating Auth Token")
|
||||
|
||||
Reference in New Issue
Block a user