cli.py 2.7 KB

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