cli.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """CLI interface."""
  2. import argparse
  3. from typing import Optional
  4. from ocma import connect
  5. def run() -> None:
  6. """Run the CLI interface."""
  7. parser = argparse.ArgumentParser(description="openconnect-microsoft-authenticator")
  8. # add argument
  9. parser.add_argument(
  10. "-u",
  11. "--username",
  12. metavar="username",
  13. type=str,
  14. help="MS Account username.",
  15. required=True,
  16. )
  17. parser.add_argument(
  18. "-p",
  19. "--password",
  20. metavar="password",
  21. type=str,
  22. help="MS Account password. If not provided, it will be read from stdin.",
  23. )
  24. parser.add_argument(
  25. "-m",
  26. "--mfa",
  27. metavar="secret",
  28. type=str,
  29. help="TOTP secret. Required, if you have set up 2FA with your MS account (only TOTP).",
  30. required=False,
  31. )
  32. parser.add_argument(
  33. "--vpn-url",
  34. nargs="?",
  35. metavar="url",
  36. type=str,
  37. help="Login URL",
  38. default="https://vpn.fhnw.ch",
  39. )
  40. parser.add_argument(
  41. "--show-head",
  42. action="store_false",
  43. help="If the browser window should be shown during the authentication process.",
  44. )
  45. parser.add_argument(
  46. "-v",
  47. action="store_true",
  48. help="If verbal messages should be printed to stderr",
  49. )
  50. parser.add_argument(
  51. "--print-to-stdout",
  52. action="store_true",
  53. help="""If the vpn host and cookie should be printed to the stdout. To be used like:\n
  54. \n
  55. eval $( python ocma/cli.py -u [username] -p [password] --print-to-stdout ); \n
  56. [ -n $VPN_COOKIE ] && echo $VPN_COOKIE | sudo openconnect --cookie-on-stdin $VPN_HOST
  57. """,
  58. )
  59. # parse the arguments from standard input
  60. args = parser.parse_args()
  61. username: str = args.username
  62. password: Optional[str] = args.password
  63. mfa_secret: str = args.mfa
  64. vpn_url: str = args.vpn_url
  65. headless: bool = args.show_head
  66. print_to_stdout: bool = args.print_to_stdout
  67. log_messages: bool = args.v
  68. if password is None:
  69. password = input()
  70. if mfa_secret is not None:
  71. try:
  72. connect.get_mfa_code(mfa_secret)
  73. except ValueError as e:
  74. raise ValueError(f"Your MFA secret '{mfa_secret}' is invalid!") from e
  75. cookie = connect.login(
  76. username=username,
  77. password=password,
  78. mfa_secret=mfa_secret,
  79. vpn_site=vpn_url,
  80. headless=headless,
  81. log_messages=log_messages,
  82. )
  83. if print_to_stdout:
  84. print(f"VPN_HOST={cookie.domain}")
  85. print(f"VPN_COOKIE={cookie.cookie}")
  86. if __name__ == "__main__":
  87. run()