Arksine / moonraker

Web API Server for Klipper
https://moonraker.readthedocs.io
GNU General Public License v3.0
1.02k stars 392 forks source link

How to add Authenticator #842

Closed SlimRG closed 2 months ago

SlimRG commented 2 months ago

Is your feature request related to a problem? Please describe

I have static ip (https://slimhome.tech/#/login) and fluiid. So, my pass was brootforced by me by 45 days. It's a secure problem, so I want to fix it.

Describe the solution you'd like

After entering login/pass show page to write google auth pin or with QR code to create it if no key inserted before.

Describe alternatives you've considered

No response

Additional information

https://www.rfc-editor.org/rfc/rfc6238 https://github.com/googleapis/google-auth-library-nodejs

SlimRG commented 2 months ago

Adding a little, but I don't know more about your code. I know python only a little( But you can add

    def __init__(self, config: ConfigHelper) -> None:
        """
        Initialize with a storage mechanism for user-specific secrets.
        user_secret_storage should be a dictionary or a database that maps usernames to secret keys.
        """
        self.user_secret_storage = user_secret_storage

    def generate_secret(self) -> str:
        """
        Generate a new secret key that can be saved for a user.
        Typically, this would be done during the setup process of 2FA.
        """
        return pyotp.random_base32()

    def get_uri_for_qr(self, username: str, issuer_name: str) -> str:
        """
        Generate a URI that can be encoded into a QR code and scanned by Google Authenticator.
        issuer_name is the name of the organization providing the 2FA.
        """
        secret = self.user_secret_storage.get(username)
        if not secret:
            raise ValueError("User does not have a secret key set up.")
        return pyotp.TOTP(secret).provisioning_uri(username, issuer_name=issuer_name)

    def verify_code(self, username: str, code: str) -> bool:
        """
        Verify the TOTP code entered by the user.
        Returns True if the code is correct, False otherwise.
        """
        secret = self.user_secret_storage.get(username)
        if not secret:
            raise self.server.error("User does not have a secret key set up.")

        totp = pyotp.TOTP(secret)
        return totp.verify(code)
SlimRG commented 2 months ago

I don't like python lang, but made support for you)

https://github.com/Arksine/moonraker/pull/844