| 623 | self.connect(**kwargs) |
| 624 | |
| 625 | def connect(self, database="", host="", user="", port="", passwd="", dsn="", **kwargs): |
| 626 | # Connect to the database. |
| 627 | |
| 628 | if not user: |
| 629 | user = getuser() |
| 630 | |
| 631 | if not database: |
| 632 | database = user |
| 633 | |
| 634 | kwargs.setdefault("application_name", self.application_name) |
| 635 | |
| 636 | # If password prompt is not forced but no password is provided, try |
| 637 | # getting it from environment variable. |
| 638 | if not self.force_passwd_prompt and not passwd: |
| 639 | if dsn: |
| 640 | # Check if DSN contains a password - if so, don't use PGPASSWORD |
| 641 | parsed_dsn = conninfo_to_dict(dsn) |
| 642 | if "password" not in parsed_dsn: |
| 643 | passwd = os.environ.get("PGPASSWORD", "") |
| 644 | else: |
| 645 | passwd = os.environ.get("PGPASSWORD", "") |
| 646 | |
| 647 | # Prompt for a password immediately if requested via the -W flag. This |
| 648 | # avoids wasting time trying to connect to the database and catching a |
| 649 | # no-password exception. |
| 650 | # If we successfully parsed a password from a URI, there's no need to |
| 651 | # prompt for it, even with the -W flag |
| 652 | if self.force_passwd_prompt and not passwd: |
| 653 | passwd = click.prompt("Password for %s" % user, hide_input=True, show_default=False, type=str) |
| 654 | |
| 655 | key = f"{user}@{host}" |
| 656 | |
| 657 | if not passwd and auth.keyring: |
| 658 | passwd = auth.keyring_get_password(key) |
| 659 | |
| 660 | def should_ask_for_password(exc): |
| 661 | # Prompt for a password after 1st attempt to connect |
| 662 | # fails. Don't prompt if the -w flag is supplied |
| 663 | if self.never_passwd_prompt: |
| 664 | return False |
| 665 | error_msg = exc.args[0] |
| 666 | if "no password supplied" in error_msg: |
| 667 | return True |
| 668 | if "password authentication failed" in error_msg: |
| 669 | return True |
| 670 | return False |
| 671 | |
| 672 | if dsn: |
| 673 | parsed_dsn = conninfo_to_dict(dsn) |
| 674 | if "host" in parsed_dsn: |
| 675 | host = parsed_dsn["host"] |
| 676 | if "port" in parsed_dsn: |
| 677 | port = parsed_dsn["port"] |
| 678 | |
| 679 | if self.dsn_alias and self.dsn_ssh_tunnel_config and not self.ssh_tunnel_url: |
| 680 | for dsn_regex, tunnel_url in self.dsn_ssh_tunnel_config.items(): |
| 681 | if re.search(dsn_regex, self.dsn_alias): |
| 682 | self.ssh_tunnel_url = tunnel_url |