Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(250)

Side by Side Diff: tools/experiments/generate_token.py

Issue 1578793002: Add experimental framework token generation tool (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add OWNERS file for tool directory Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2016 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Utility for generating experimental API tokens
7
8 usage: generate_token.py [-h] [--key-file KEY_FILE]
9 [--expire-days EXPIRE_DAYS |
10 --expire-timestamp EXPIRE_TIMESTAMP]
11 hostname api_name
12
13 Generate tokens for enabling experimental APIs
14
15 positional arguments:
16 hostname Host for which to enable the API. This can be a bare
17 hostname (in which case https will be assumed,) or a
18 valid origin URL (hostname, protocol and port can all
19 be included.)
20 api_name API to enable. The current list of experimental APIs
21 can be found in RuntimeFeatures.in
22
23 optional arguments:
24 -h, --help show this help message and exit
25 --key-file KEY_FILE Ed25519 private key file to sign the token with
26 --expire-days EXPIRE_DAYS
27 Days from now when the token should exipire
28 --expire-timestamp EXPIRE_TIMESTAMP
29 Exact time (milliseconds since 1970-01-01 00:00:00
30 UTC) when the token should exipire
miket_OOO 2016/01/21 21:54:56 This is up to you, but if this is just a rote copy
iclelland 2016/01/22 20:31:57 It is a rote copy, just for anyone reading the cod
31 """
32 import argparse
33 import base64
34 import re
35 import os
36 import sys
37 import time
38 import urlparse
39
40 from third_party import ed25519
41
42 def OriginFromArgs(arg):
43 """Constructs the origin for the token from the command line arguments.
44
45 Returns None if this is not possible (neither a valid hostname nor a
46 valid origin URL was provided.)
47 """
48 # Does it look like a hostname?
49 if re.match('^[a-z0-9.-]*$', arg):
miket_OOO 2016/01/21 21:54:56 Make sure we (this tool and dev-console server cod
iclelland 2016/01/22 20:31:57 It looks like your regex disallows a '-' as a comp
50 return 'https://'+arg
51 # Try to construct an origin URL from the argument
52 origin = urlparse.urlparse(arg)
53 if not origin or not origin.scheme or not origin.netloc:
54 raise argparse.ArgumentTypeError("%s is not a hostname or a URL" % arg)
55 # Strip any other components and return the URL:
56 return urlparse.urlunparse(origin[:2]+('',)*4)
miket_OOO 2016/01/21 21:54:56 whitespace after comma and around binary operator
iclelland 2016/01/22 20:31:57 Done.
57
58 def ExpiryFromArgs(args):
59 if args.expire_timestamp:
60 return int(args.expire_timestamp)
61 return ((int(time.time()) + (int(args.expire_days) * 86400)) * 1000)
62
63 def GenerateTokenData(origin, apiName, expiry):
64 return "{0}|{1}|{2}".format(origin, apiName, expiry)
65
66 def Sign(private_key, data):
67 return ed25519.signature(data, private_key[:32], private_key[32:])
68
69 def FormatToken(signature, data):
70 return base64.b64encode(signature) + "|" + data
71
72 def main():
73 parser = argparse.ArgumentParser(
74 description="Generate tokens for enabling experimental APIs")
75 parser.add_argument('hostname',
76 help="Host for which to enable the API. This can be a "
77 "bare hostname (in which case https will be "
78 "assumed,) or a valid origin URL (hostname, "
79 "protocol and port can all be included.)",
80 type=OriginFromArgs)
81 parser.add_argument('api_name',
82 help="API to enable. The current list of experimental "
83 "APIs can be found in RuntimeFeatures.in")
84 parser.add_argument('--key-file',
85 help='Ed25519 private key file to sign the token with',
86 default="eftest.key")
87 expiry_group = parser.add_mutually_exclusive_group()
88 expiry_group.add_argument('--expire-days',
89 help='Days from now when the token should exipire',
90 type=int,
91 default=42)
92 expiry_group.add_argument('--expire-timestamp',
93 help="Exact time (milliseconds since 1970-01-01 "
94 "00:00:00 UTC) when the token should exipire",
95 type=int)
96
97 args = parser.parse_args()
98 expiry = ExpiryFromArgs(args)
99
100 key_file = open(os.path.expanduser(args.key_file))
101 private_key = key_file.read()
102
103 # Validate that the key file read was a proper Ed25519 key -- running the
104 # publickey method on the first half of the key should return the second
105 # half.
106 if (len(private_key) != 64 or
107 ed25519.publickey(private_key[:32]) != private_key[32:]):
108 print("Unable to use the specified private key file.")
109 sys.exit(1)
110
111 token_data = GenerateTokenData(args.hostname, args.api_name, expiry)
112 signature = Sign(private_key, token_data)
113
114 # Verify that that the signature is correct before printing it.
115 try:
116 ed25519.checkvalid(signature, token_data, private_key[32:])
117 except Exception:
118 print "There was an error generating the signature."
119 sys.exit(1)
120
121 print FormatToken(signature, token_data)
122
123 if __name__ == "__main__":
124 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698