OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # coding: utf-8 | 2 # coding: utf-8 |
3 # | 3 # |
4 # Copyright 2007 Google Inc. | 4 # Copyright 2007 Google Inc. |
5 # | 5 # |
6 # Licensed under the Apache License, Version 2.0 (the "License"); | 6 # Licensed under the Apache License, Version 2.0 (the "License"); |
7 # you may not use this file except in compliance with the License. | 7 # you may not use this file except in compliance with the License. |
8 # You may obtain a copy of the License at | 8 # You may obtain a copy of the License at |
9 # | 9 # |
10 # http://www.apache.org/licenses/LICENSE-2.0 | 10 # http://www.apache.org/licenses/LICENSE-2.0 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 try: | 65 try: |
66 import readline | 66 import readline |
67 except ImportError: | 67 except ImportError: |
68 pass | 68 pass |
69 | 69 |
70 try: | 70 try: |
71 import keyring | 71 import keyring |
72 except: | 72 except: |
73 keyring = None | 73 keyring = None |
74 | 74 |
| 75 # auth.py is a part of depot_tools. |
| 76 # TODO(vadimsh): Merge upload.py into depot_tools |
| 77 import auth |
| 78 |
75 # The logging verbosity: | 79 # The logging verbosity: |
76 # 0: Errors only. | 80 # 0: Errors only. |
77 # 1: Status messages. | 81 # 1: Status messages. |
78 # 2: Info logs. | 82 # 2: Info logs. |
79 # 3: Debug logs. | 83 # 3: Debug logs. |
80 verbosity = 1 | 84 verbosity = 1 |
81 LOGGER = logging.getLogger('upload') | 85 LOGGER = logging.getLogger('upload') |
82 | 86 |
83 # The account type used for authentication. | 87 # The account type used for authentication. |
84 # This line could be changed by the review server (see handler for | 88 # This line could be changed by the review server (see handler for |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 # Review server | 615 # Review server |
612 group = parser.add_option_group("Review server options") | 616 group = parser.add_option_group("Review server options") |
613 group.add_option("-s", "--server", action="store", dest="server", | 617 group.add_option("-s", "--server", action="store", dest="server", |
614 default=DEFAULT_REVIEW_SERVER, | 618 default=DEFAULT_REVIEW_SERVER, |
615 metavar="SERVER", | 619 metavar="SERVER", |
616 help=("The server to upload to. The format is host[:port]. " | 620 help=("The server to upload to. The format is host[:port]. " |
617 "Defaults to '%default'.")) | 621 "Defaults to '%default'.")) |
618 group.add_option("-e", "--email", action="store", dest="email", | 622 group.add_option("-e", "--email", action="store", dest="email", |
619 metavar="EMAIL", default=None, | 623 metavar="EMAIL", default=None, |
620 help="The username to use. Will prompt if omitted.") | 624 help="The username to use. Will prompt if omitted.") |
621 group.add_option("-H", "--host", action="store", dest="host", | |
622 metavar="HOST", default=None, | |
623 help="Overrides the Host header sent with all RPCs.") | |
624 group.add_option("--no_cookies", action="store_false", | |
625 dest="save_cookies", default=True, | |
626 help="Do not save authentication cookies to local disk.") | |
627 group.add_option("--oauth2", action="store_true", | |
628 dest="use_oauth2", default=False, | |
629 help="Use OAuth 2.0 instead of a password.") | |
630 group.add_option("--oauth2_port", action="store", type="int", | |
631 dest="oauth2_port", default=DEFAULT_OAUTH2_PORT, | |
632 help=("Port to use to handle OAuth 2.0 redirect. Must be an " | |
633 "integer in the range 1024-49151, defaults to " | |
634 "'%default'.")) | |
635 group.add_option("--no_oauth2_webbrowser", action="store_false", | |
636 dest="open_oauth2_local_webbrowser", default=True, | |
637 help="Don't open a browser window to get an access token.") | |
638 group.add_option("--account_type", action="store", dest="account_type", | |
639 metavar="TYPE", default=AUTH_ACCOUNT_TYPE, | |
640 choices=["GOOGLE", "HOSTED"], | |
641 help=("Override the default account type " | |
642 "(defaults to '%default', " | |
643 "valid choices are 'GOOGLE' and 'HOSTED').")) | |
644 group.add_option("-j", "--number-parallel-uploads", | 625 group.add_option("-j", "--number-parallel-uploads", |
645 dest="num_upload_threads", default=8, | 626 dest="num_upload_threads", default=8, |
646 help="Number of uploads to do in parallel.") | 627 help="Number of uploads to do in parallel.") |
| 628 # Authentication |
| 629 auth.add_auth_options(parser) |
647 # Issue | 630 # Issue |
648 group = parser.add_option_group("Issue options") | 631 group = parser.add_option_group("Issue options") |
649 group.add_option("-t", "--title", action="store", dest="title", | 632 group.add_option("-t", "--title", action="store", dest="title", |
650 help="New issue subject or new patch set title") | 633 help="New issue subject or new patch set title") |
651 group.add_option("--project", action="store", dest="project", | 634 group.add_option("--project", action="store", dest="project", |
652 help="The project the issue belongs to") | 635 help="The project the issue belongs to") |
653 group.add_option("-m", "--message", action="store", dest="message", | 636 group.add_option("-m", "--message", action="store", dest="message", |
654 default=None, | 637 default=None, |
655 help="New issue description or new patch set message") | 638 help="New issue description or new patch set message") |
656 group.add_option("-F", "--file", action="store", dest="file", | 639 group.add_option("-F", "--file", action="store", dest="file", |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 self.server = server | 910 self.server = server |
928 self.port = port | 911 self.port = port |
929 self.open_local_webbrowser = open_local_webbrowser | 912 self.open_local_webbrowser = open_local_webbrowser |
930 | 913 |
931 def __call__(self): | 914 def __call__(self): |
932 """Uses stored server and port to retrieve OAuth 2.0 access token.""" | 915 """Uses stored server and port to retrieve OAuth 2.0 access token.""" |
933 return GetAccessToken(server=self.server, port=self.port, | 916 return GetAccessToken(server=self.server, port=self.port, |
934 open_local_webbrowser=self.open_local_webbrowser) | 917 open_local_webbrowser=self.open_local_webbrowser) |
935 | 918 |
936 | 919 |
937 def GetRpcServer(server, email=None, host_override=None, save_cookies=True, | 920 def GetRpcServer(server, auth_config=None, email=None): |
938 account_type=AUTH_ACCOUNT_TYPE, use_oauth2=False, | |
939 oauth2_port=DEFAULT_OAUTH2_PORT, | |
940 open_oauth2_local_webbrowser=True): | |
941 """Returns an instance of an AbstractRpcServer. | 921 """Returns an instance of an AbstractRpcServer. |
942 | 922 |
943 Args: | 923 Args: |
944 server: String containing the review server URL. | 924 server: String containing the review server URL. |
945 email: String containing user's email address. | 925 auth_config: auth.AuthConfig tuple with OAuth2 configuration. |
946 host_override: If not None, string containing an alternate hostname to use | 926 email: String containing user's email address [deprecated]. |
947 in the host header. | |
948 save_cookies: Whether authentication cookies should be saved to disk. | |
949 account_type: Account type for authentication, either 'GOOGLE' | |
950 or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. | |
951 use_oauth2: Boolean indicating whether OAuth 2.0 should be used for | |
952 authentication. | |
953 oauth2_port: Integer, the port where the localhost server receiving the | |
954 redirect is serving. Defaults to DEFAULT_OAUTH2_PORT. | |
955 open_oauth2_local_webbrowser: Boolean, defaults to True. If True and using | |
956 OAuth, this opens a page in the user's browser to obtain a token. | |
957 | 927 |
958 Returns: | 928 Returns: |
959 A new HttpRpcServer, on which RPC calls can be made. | 929 A new HttpRpcServer, on which RPC calls can be made. |
960 """ | 930 """ |
| 931 # If email is given as an empty string or no auth config is passed, then |
| 932 # assume we want to make requests that do not need authentication. Bypass |
| 933 # authentication by setting the auth_function to None. |
| 934 if email == '' or not auth_config: |
| 935 return HttpRpcServer(server, None) |
| 936 |
| 937 if auth_config.use_oauth2: |
| 938 raise NotImplementedError('See https://crbug.com/356813') |
| 939 |
961 # If this is the dev_appserver, use fake authentication. | 940 # If this is the dev_appserver, use fake authentication. |
962 host = (host_override or server).lower() | 941 host = server.lower() |
963 if re.match(r'(http://)?localhost([:/]|$)', host): | 942 if re.match(r'(http://)?localhost([:/]|$)', host): |
964 if email is None: | 943 if email is None: |
965 email = "test@example.com" | 944 email = "test@example.com" |
966 LOGGER.info("Using debug user %s. Override with --email" % email) | 945 LOGGER.info("Using debug user %s. Override with --email" % email) |
967 server = HttpRpcServer( | 946 server = HttpRpcServer( |
968 server, | 947 server, |
969 lambda: (email, "password"), | 948 lambda: (email, "password"), |
970 host_override=host_override, | |
971 extra_headers={"Cookie": | 949 extra_headers={"Cookie": |
972 'dev_appserver_login="%s:False"' % email}, | 950 'dev_appserver_login="%s:False"' % email}, |
973 save_cookies=save_cookies, | 951 save_cookies=auth_config.save_cookies, |
974 account_type=account_type) | 952 account_type=AUTH_ACCOUNT_TYPE) |
975 # Don't try to talk to ClientLogin. | 953 # Don't try to talk to ClientLogin. |
976 server.authenticated = True | 954 server.authenticated = True |
977 return server | 955 return server |
978 | 956 |
979 positional_args = [server] | 957 return HttpRpcServer( |
980 if use_oauth2: | 958 server, |
981 positional_args.append( | 959 KeyringCreds(server, host, email).GetUserCredentials, |
982 OAuth2Creds(server, oauth2_port, open_oauth2_local_webbrowser)) | 960 save_cookies=auth_config.save_cookies, |
983 else: | 961 account_type=AUTH_ACCOUNT_TYPE) |
984 positional_args.append(KeyringCreds(server, host, email).GetUserCredentials) | |
985 return HttpRpcServer(*positional_args, | |
986 host_override=host_override, | |
987 save_cookies=save_cookies, | |
988 account_type=account_type) | |
989 | 962 |
990 | 963 |
991 def EncodeMultipartFormData(fields, files): | 964 def EncodeMultipartFormData(fields, files): |
992 """Encode form fields for multipart/form-data. | 965 """Encode form fields for multipart/form-data. |
993 | 966 |
994 Args: | 967 Args: |
995 fields: A sequence of (name, value) elements for regular form fields. | 968 fields: A sequence of (name, value) elements for regular form fields. |
996 files: A sequence of (name, filename, value) elements for data to be | 969 files: A sequence of (name, filename, value) elements for data to be |
997 uploaded as files. | 970 uploaded as files. |
998 Returns: | 971 Returns: |
(...skipping 1592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2591 if data is None: | 2564 if data is None: |
2592 data = vcs.GenerateDiff(args) | 2565 data = vcs.GenerateDiff(args) |
2593 data = vcs.PostProcessDiff(data) | 2566 data = vcs.PostProcessDiff(data) |
2594 if options.print_diffs: | 2567 if options.print_diffs: |
2595 print "Rietveld diff start:*****" | 2568 print "Rietveld diff start:*****" |
2596 print data | 2569 print data |
2597 print "Rietveld diff end:*****" | 2570 print "Rietveld diff end:*****" |
2598 files = vcs.GetBaseFiles(data) | 2571 files = vcs.GetBaseFiles(data) |
2599 if verbosity >= 1: | 2572 if verbosity >= 1: |
2600 print "Upload server:", options.server, "(change with -s/--server)" | 2573 print "Upload server:", options.server, "(change with -s/--server)" |
2601 if options.use_oauth2: | 2574 |
2602 options.save_cookies = False | 2575 auth_config = auth.extract_auth_config_from_options(options) |
2603 rpc_server = GetRpcServer(options.server, | 2576 rpc_server = GetRpcServer(options.server, auth_config, options.email) |
2604 options.email, | |
2605 options.host, | |
2606 options.save_cookies, | |
2607 options.account_type, | |
2608 options.use_oauth2, | |
2609 options.oauth2_port, | |
2610 options.open_oauth2_local_webbrowser) | |
2611 form_fields = [] | 2577 form_fields = [] |
2612 | 2578 |
2613 repo_guid = vcs.GetGUID() | 2579 repo_guid = vcs.GetGUID() |
2614 if repo_guid: | 2580 if repo_guid: |
2615 form_fields.append(("repo_guid", repo_guid)) | 2581 form_fields.append(("repo_guid", repo_guid)) |
2616 if base: | 2582 if base: |
2617 b = urlparse.urlparse(base) | 2583 b = urlparse.urlparse(base) |
2618 username, netloc = urllib.splituser(b.netloc) | 2584 username, netloc = urllib.splituser(b.netloc) |
2619 if username: | 2585 if username: |
2620 LOGGER.info("Removed username from base URL") | 2586 LOGGER.info("Removed username from base URL") |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2744 os.environ['LC_ALL'] = 'C' | 2710 os.environ['LC_ALL'] = 'C' |
2745 RealMain(sys.argv) | 2711 RealMain(sys.argv) |
2746 except KeyboardInterrupt: | 2712 except KeyboardInterrupt: |
2747 print | 2713 print |
2748 StatusUpdate("Interrupted.") | 2714 StatusUpdate("Interrupted.") |
2749 sys.exit(1) | 2715 sys.exit(1) |
2750 | 2716 |
2751 | 2717 |
2752 if __name__ == "__main__": | 2718 if __name__ == "__main__": |
2753 main() | 2719 main() |
OLD | NEW |