diff --git a/gamestonk_terminal/config_terminal.py b/gamestonk_terminal/config_terminal.py index aed3d612561..8039f5e3c5d 100644 --- a/gamestonk_terminal/config_terminal.py +++ b/gamestonk_terminal/config_terminal.py @@ -45,7 +45,6 @@ RH_PASSWORD = os.getenv("GT_RH_PASSWORD") or "REPLACE_ME" # Degiro DG_USERNAME = os.getenv("GT_DG_USERNAME") or "REPLACE_ME" DG_PASSWORD = os.getenv("GT_DG_PASSWORD") or "REPLACE_ME" -DG_TOTP = os.getenv("GT_DG_TOTP") or None DG_TOTP_SECRET = os.getenv("GT_DG_TOTP_SECRET") or None # https://developer.oanda.com diff --git a/gamestonk_terminal/portfolio/README.md b/gamestonk_terminal/portfolio/README.md index 8a899887185..fcd25fabbee 100644 --- a/gamestonk_terminal/portfolio/README.md +++ b/gamestonk_terminal/portfolio/README.md @@ -181,19 +181,15 @@ In order to login you need to provide the following credentials : | DG_USERNAME | Username used to log into Degiro's website. | | DG_PASSWORD | Password used to log into Degiro's website. | - **2FA** In order to use 2FA you need to provide one of these parameters : | Parameter | Description | | :--- | :--- | -| DG_TOTP | This is your one time password. | -| DG_TOTP_SECRET | This secret key will let Gamestonk generate the DG_TOTP for you. | +| DG_TOTP_SECRET | This secret key will let Gamestonk generate the `OneTimePassword` for you. | -If you choose to use `DG_TOTP` : you will have to provide a temporary password at each connection to Degiro. - -If you provide your `DG_TOTP_SECRET` : you won't have to type your DG_TOTP, Gamestonk will generate it for you at each connection. +If you provide your `DG_TOTP_SECRET` : you won't have to type your `OneTimePassword`, Gamestonk will generate it for you at each connection. `DG_TOTP_SECRET` is the text representation of the `QRCODE` that Degiro's provide you when you enable 2FA. @@ -203,7 +199,17 @@ https://github.com/Chavithra/degiro-connector ### login ```` -usage: login +usage: login [-u USERNAME] [-p PASSWORD] [-o OTP] [-s TOPT_SECRET] [-h] + +optional arguments: + -u USERNAME, --username USERNAME + Username in Degiro's account. + -p PASSWORD, --password PASSWORD + Password in Degiro's account. + -o OTP, --otp OTP One time password (2FA). + -s TOPT_SECRET, --topt-secret TOPT_SECRET + TOTP SECRET (2FA). + -h, --help show this help message ```` ### hold diff --git a/gamestonk_terminal/portfolio/degiro_api.py b/gamestonk_terminal/portfolio/degiro_api.py index cb09d7637fa..0db089b1831 100644 --- a/gamestonk_terminal/portfolio/degiro_api.py +++ b/gamestonk_terminal/portfolio/degiro_api.py @@ -73,6 +73,7 @@ class DegiroController: return positions def __init__(self, credentials: Credentials): + self.__default_credentials = credentials self.__trading_api = TradingAPI(credentials=credentials) self.__degiro_parser = argparse.ArgumentParser( @@ -172,26 +173,78 @@ class DegiroController: def help(self): message = ( "Degiro:\n" - " companynews view news about a company with it's isin\n" - " hold view holdings\n" - " lastnews view latest news\n" - " login connect to degiro api\n" - " lookup view search for a product by name\n" - " pending view pending orders\n" - " topnews view top news preview\n" + " companynews view news about a company with it's isin\n" + " hold view holdings\n" + " lastnews view latest news\n" + " login connect to degiro's api\n" + " logout disconnect from degiro's api\n" + " lookup view search for a product by name\n" + " pending view pending orders\n" + " topnews view top news preview\n" ) print(message) - def login(self, _): + def login(self, l_args): """Connect to Degiro's API.""" - trading_api = self.__trading_api + # PARSING ARGS + default_credentials = self.__default_credentials + parser = argparse.ArgumentParser( + add_help=False, + prog="login", + ) + parser.add_argument( + "-u", + "--username", + dest="username", + type=str, + default=default_credentials.username, + help="Username in Degiro's account.", + ) + parser.add_argument( + "-p", + "--password", + dest="password", + type=str, + default=default_credentials.password, + help="Password in Degiro's account.", + ) + parser.add_argument( + "-o", + "--otp", + dest="otp", + type=int, + default=None, + help="One time password (2FA).", + ) + parser.add_argument( + "-s", + "--topt-secret", + dest="topt_secret", + type=str, + default=None, + help="TOTP SECRET (2FA).", + ) + ns_parser = parse_known_args_and_warn(parser, l_args) - trading_api.connect() - self.setup_extra_credentials() + if ns_parser: + credentials = Credentials() + credentials.CopyFrom(default_credentials) + credentials.username = ns_parser.username + credentials.password = ns_parser.password - print("You are now logged in !") + if ns_parser.otp is not None: + credentials.one_time_password = ns_parser.otp + if ns_parser.topt_secret is not None: + credentials.totp_secret_key = ns_parser.topt_secret + + self.__trading_api = TradingAPI(credentials=credentials) + + self.__trading_api.connect() + self.setup_extra_credentials() + + print("You are now logged in !") def logout(self, _): """Log out from Degiro's API.""" @@ -452,7 +505,7 @@ def menu(): int_account=None, username=config.DG_USERNAME, password=config.DG_PASSWORD, - one_time_password=config.DG_TOTP, + one_time_password=None, totp_secret_key=config.DG_TOTP_SECRET, ) @@ -467,11 +520,11 @@ def menu(): {c: None for c in degiro_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (pa) > (degiro)> ", + f"{get_flair()} (pa)>(degiro)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (pa) > (degiro)> ") + an_input = input(f"{get_flair()} (pa)>(degiro)> ") try: process_input = degiro_controller.switch(an_input)