from snek.system.form import Form, FormButtonElement, FormInputElement, HTMLElement class AuthField(FormInputElement): @property async def errors(self): result = await super().errors if self.model.password.value and self.model.username.value: if not await self.app.services.user.validate_login( self.model.username.value, self.model.password.value ): return ["Invalid username or password"] return result class LoginForm(Form): title = HTMLElement(tag="h1", text="Login") username = AuthField( name="username", required=True, min_length=2, max_length=20, regex=r"^[a-zA-Z0-9_]+$", place_holder="Username", type="text", ) password = AuthField( name="password", required=True, regex=r"^[a-zA-Z0-9_.+-]{6,}", type="password", place_holder="Password", ) action = FormButtonElement( name="action", value="submit", text="Login", type="button" ) @property async def is_valid(self): return all( [ self["username"], self["password"], not await self.username.errors, not await self.password.errors, ] )