mirror of
https://github.com/1f349/lavender.git
synced 2025-04-15 23:37:53 +01:00
I guess I modified stuff
This commit is contained in:
parent
3fbe905cb2
commit
c27a86010c
@ -1,15 +1,12 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"github.com/1f349/lavender/auth/authContext"
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Button interface {
|
type Button interface {
|
||||||
// ButtonName defines the text to show on the button.
|
Provider
|
||||||
ButtonName() string
|
|
||||||
|
|
||||||
// RenderButtonTemplate returns a template for the button widget.
|
// RenderButtonTemplate returns a template for the button widget.
|
||||||
RenderButtonTemplate(ctx context.Context, req *http.Request) template.HTML
|
RenderButtonTemplate(ctx authContext.TemplateContext)
|
||||||
}
|
}
|
||||||
|
13
auth/auth-form.go
Normal file
13
auth/auth-form.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import "github.com/1f349/lavender/auth/authContext"
|
||||||
|
|
||||||
|
type Form interface {
|
||||||
|
Provider
|
||||||
|
|
||||||
|
// RenderTemplate returns HTML to embed in the page template.
|
||||||
|
RenderTemplate(ctx authContext.TemplateContext) error
|
||||||
|
|
||||||
|
// AttemptLogin processes the login request.
|
||||||
|
AttemptLogin(ctx authContext.FormContext) error
|
||||||
|
}
|
54
auth/auth.go
54
auth/auth.go
@ -2,11 +2,7 @@ package auth
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/1f349/lavender/auth/authContext"
|
|
||||||
"github.com/1f349/lavender/database"
|
"github.com/1f349/lavender/database"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// State defines the currently reached authentication state
|
// State defines the currently reached authentication state
|
||||||
@ -15,6 +11,9 @@ type State byte
|
|||||||
const (
|
const (
|
||||||
// StateUnauthorized defines the "unauthorized" state of a session
|
// StateUnauthorized defines the "unauthorized" state of a session
|
||||||
StateUnauthorized State = iota
|
StateUnauthorized State = iota
|
||||||
|
// StateBase defines the "username" only user state
|
||||||
|
// This state is for providing a username to allow redirecting to oauth clients
|
||||||
|
StateBase
|
||||||
// StateBasic defines the "username and password with no OTP" user state
|
// StateBasic defines the "username and password with no OTP" user state
|
||||||
// This is skipped if OTP/passkey is optional and not enabled for the user
|
// This is skipped if OTP/passkey is optional and not enabled for the user
|
||||||
StateBasic
|
StateBasic
|
||||||
@ -36,53 +35,6 @@ type Provider interface {
|
|||||||
|
|
||||||
// Name defines a string value for the provider.
|
// Name defines a string value for the provider.
|
||||||
Name() string
|
Name() string
|
||||||
|
|
||||||
// RenderTemplate returns HTML to embed in the page template.
|
|
||||||
RenderTemplate(ctx authContext.TemplateContext) error
|
|
||||||
|
|
||||||
// AttemptLogin processes the login request.
|
|
||||||
AttemptLogin(ctx authContext.TemplateContext) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserSafeError struct {
|
|
||||||
Display string
|
|
||||||
Code int
|
|
||||||
Internal error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e UserSafeError) Error() string {
|
|
||||||
return fmt.Sprintf("%s [%d]: %v", e.Display, e.Code, e.Internal)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e UserSafeError) Unwrap() error {
|
|
||||||
return e.Internal
|
|
||||||
}
|
|
||||||
|
|
||||||
func BasicUserSafeError(code int, message string) UserSafeError {
|
|
||||||
return UserSafeError{
|
|
||||||
Code: code,
|
|
||||||
Display: message,
|
|
||||||
Internal: errors.New(message),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AdminSafeError(inner error) UserSafeError {
|
|
||||||
return UserSafeError{
|
|
||||||
Code: http.StatusInternalServerError,
|
|
||||||
Display: "Internal server error",
|
|
||||||
Internal: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type RedirectError struct {
|
|
||||||
Target string
|
|
||||||
Code int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e RedirectError) TargetUrl() string { return e.Target }
|
|
||||||
|
|
||||||
func (e RedirectError) Error() string {
|
|
||||||
return fmt.Sprintf("redirect to '%s'", e.Target)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LookupUserDB interface {
|
type LookupUserDB interface {
|
||||||
|
@ -2,11 +2,12 @@ package authContext
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/1f349/lavender/auth/login-process"
|
||||||
"github.com/1f349/lavender/database"
|
"github.com/1f349/lavender/database"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTemplateContext(req *http.Request, user *database.User) TemplateContext {
|
func NewTemplateContext(req *http.Request, user *database.User) *BaseTemplateContext {
|
||||||
return &BaseTemplateContext{
|
return &BaseTemplateContext{
|
||||||
req: req,
|
req: req,
|
||||||
user: user,
|
user: user,
|
||||||
@ -18,30 +19,38 @@ type TemplateContext interface {
|
|||||||
Request() *http.Request
|
Request() *http.Request
|
||||||
User() *database.User
|
User() *database.User
|
||||||
Render(data any)
|
Render(data any)
|
||||||
Data() any
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FormContext interface {
|
||||||
|
Context() context.Context
|
||||||
|
Request() *http.Request
|
||||||
|
User() *database.User
|
||||||
|
SetUser(user *database.User)
|
||||||
|
Render(data any)
|
||||||
|
UpdateSession(data login_process.LoginProcessData)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ButtonContext interface {
|
||||||
|
Context() context.Context
|
||||||
|
Request() *http.Request
|
||||||
|
Render(data any)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ TemplateContext = &BaseTemplateContext{}
|
||||||
|
|
||||||
type BaseTemplateContext struct {
|
type BaseTemplateContext struct {
|
||||||
req *http.Request
|
req *http.Request
|
||||||
user *database.User
|
user *database.User
|
||||||
data any
|
data any
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *BaseTemplateContext) Context() context.Context {
|
func (t *BaseTemplateContext) Context() context.Context { return t.req.Context() }
|
||||||
return t.req.Context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *BaseTemplateContext) Request() *http.Request {
|
func (t *BaseTemplateContext) Request() *http.Request { return t.req }
|
||||||
return t.req
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *BaseTemplateContext) User() *database.User {
|
func (t *BaseTemplateContext) User() *database.User { return t.user }
|
||||||
return t.user
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *BaseTemplateContext) Render(data any) {
|
func (t *BaseTemplateContext) Render(data any) { t.data = data }
|
||||||
t.data = data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *BaseTemplateContext) Data() any {
|
func (t *BaseTemplateContext) Data() any {
|
||||||
return t.data
|
return t.data
|
||||||
|
14
auth/login-process/login-process-data.go
Normal file
14
auth/login-process/login-process-data.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package login_process
|
||||||
|
|
||||||
|
import "github.com/1f349/mjwt"
|
||||||
|
|
||||||
|
var _ mjwt.Claims = (*LoginProcessData)(nil)
|
||||||
|
|
||||||
|
// TODO: add some actual session management
|
||||||
|
type LoginProcessData struct {
|
||||||
|
State byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d LoginProcessData) Valid() error { return nil }
|
||||||
|
|
||||||
|
func (d LoginProcessData) Type() string { return "login-process" }
|
47
auth/providers/base.go
Normal file
47
auth/providers/base.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package providers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1f349/lavender/auth"
|
||||||
|
"github.com/1f349/lavender/auth/authContext"
|
||||||
|
"github.com/1f349/lavender/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ auth.Provider = (*InitialLogin)(nil)
|
||||||
|
|
||||||
|
type InitialLogin struct{}
|
||||||
|
|
||||||
|
func (m *InitialLogin) AccessState() auth.State { return auth.StateUnauthorized }
|
||||||
|
|
||||||
|
func (m *InitialLogin) Name() string { return "base" }
|
||||||
|
|
||||||
|
func (m *InitialLogin) RenderTemplate(ctx authContext.FormContext) error {
|
||||||
|
type s struct {
|
||||||
|
UserEmail string
|
||||||
|
Redirect string
|
||||||
|
}
|
||||||
|
|
||||||
|
req := ctx.Request()
|
||||||
|
q := req.URL.Query()
|
||||||
|
cookie, err := req.Cookie("lavender-user-memory")
|
||||||
|
if err == nil && cookie.Valid() == nil {
|
||||||
|
ctx.Render(s{
|
||||||
|
UserEmail: cookie.Value,
|
||||||
|
Redirect: q.Get("redirect"),
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Render(s{
|
||||||
|
UserEmail: "",
|
||||||
|
Redirect: q.Get("redirect"),
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *InitialLogin) AttemptLogin(ctx authContext.FormContext) error {
|
||||||
|
req := ctx.Request()
|
||||||
|
userEmail := req.FormValue("email")
|
||||||
|
rememberMe := req.FormValue("remember-me")
|
||||||
|
logger.Logger.Debug("Hi", "em", userEmail, "rm", rememberMe)
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
package providers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/1f349/lavender/auth"
|
|
||||||
"github.com/1f349/lavender/auth/authContext"
|
|
||||||
"github.com/1f349/lavender/web"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ auth.Provider = (*MemoryLogin)(nil)
|
|
||||||
|
|
||||||
type MemoryLogin struct{}
|
|
||||||
|
|
||||||
func (m *MemoryLogin) AccessState() auth.State { return auth.StateUnauthorized }
|
|
||||||
|
|
||||||
func (m *MemoryLogin) Name() string { return "memory" }
|
|
||||||
|
|
||||||
func (m *MemoryLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
|
||||||
cookie, err := ctx.Request().Cookie("lavender-user-memory")
|
|
||||||
if err == nil && cookie.Valid() == nil {
|
|
||||||
ctx.Render(struct {
|
|
||||||
ServiceName string
|
|
||||||
LoginName string
|
|
||||||
Redirect string
|
|
||||||
}{
|
|
||||||
ServiceName: ,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryLogin) AttemptLogin(ctx authContext.TemplateContext) error {
|
|
||||||
//TODO implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
@ -47,13 +47,7 @@ func (o OAuthLogin) AccessState() auth.State { return auth.StateUnauthorized }
|
|||||||
|
|
||||||
func (o OAuthLogin) Name() string { return "oauth" }
|
func (o OAuthLogin) Name() string { return "oauth" }
|
||||||
|
|
||||||
func (o OAuthLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
func (o OAuthLogin) AttemptLogin(ctx authContext.FormContext) error {
|
||||||
// TODO: does this need to exist?
|
|
||||||
ctx.Render(map[string]any{"Error": "no"})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o OAuthLogin) AttemptLogin(ctx authContext.TemplateContext) error {
|
|
||||||
rCtx := ctx.Context()
|
rCtx := ctx.Context()
|
||||||
|
|
||||||
login, ok := rCtx.Value(oauthServiceLogin(0)).(*issuer.WellKnownOIDC)
|
login, ok := rCtx.Value(oauthServiceLogin(0)).(*issuer.WellKnownOIDC)
|
||||||
|
@ -30,7 +30,7 @@ func (o *OtpLogin) AccessState() auth.State { return auth.StateBasic }
|
|||||||
|
|
||||||
func (o *OtpLogin) Name() string { return "basic" }
|
func (o *OtpLogin) Name() string { return "basic" }
|
||||||
|
|
||||||
func (o *OtpLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
func (o *OtpLogin) RenderTemplate(ctx authContext.FormContext) error {
|
||||||
user := ctx.User()
|
user := ctx.User()
|
||||||
if user == nil || user.Subject == "" {
|
if user == nil || user.Subject == "" {
|
||||||
return fmt.Errorf("requires previous factor")
|
return fmt.Errorf("requires previous factor")
|
||||||
@ -48,7 +48,7 @@ func (o *OtpLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OtpLogin) AttemptLogin(ctx authContext.TemplateContext) error {
|
func (o *OtpLogin) AttemptLogin(ctx authContext.FormContext) error {
|
||||||
user := ctx.User()
|
user := ctx.User()
|
||||||
if user == nil || user.Subject == "" {
|
if user == nil || user.Subject == "" {
|
||||||
return fmt.Errorf("requires previous factor")
|
return fmt.Errorf("requires previous factor")
|
||||||
|
@ -2,9 +2,7 @@ package providers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"github.com/1f349/lavender/auth"
|
"github.com/1f349/lavender/auth"
|
||||||
"github.com/1f349/lavender/auth/authContext"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@ -26,38 +24,6 @@ func (p *PasskeyLogin) AccessState() auth.State { return auth.StateUnauthorized
|
|||||||
|
|
||||||
func (p *PasskeyLogin) Name() string { return "passkey" }
|
func (p *PasskeyLogin) Name() string { return "passkey" }
|
||||||
|
|
||||||
func (p *PasskeyLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
|
||||||
user := ctx.User()
|
|
||||||
if user == nil || user.Subject == "" {
|
|
||||||
return fmt.Errorf("requires previous factor")
|
|
||||||
}
|
|
||||||
if user.OtpSecret == "" {
|
|
||||||
return fmt.Errorf("user does not support factor")
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
var passkeyShortcut = true
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
passkeyShortcut = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PasskeyLogin) AttemptLogin(ctx authContext.TemplateContext) error {
|
|
||||||
user := ctx.User()
|
|
||||||
if user.Subject == "" && !passkeyShortcut {
|
|
||||||
return fmt.Errorf("requires previous factor")
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PasskeyLogin) ButtonName() string {
|
|
||||||
return "Login with Passkey"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PasskeyLogin) RenderButtonTemplate(ctx context.Context, req *http.Request) template.HTML {
|
func (p *PasskeyLogin) RenderButtonTemplate(ctx context.Context, req *http.Request) template.HTML {
|
||||||
return "<div>Passkey Button</div>"
|
return "<div>Passkey Button</div>"
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,25 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type basicLoginDB interface {
|
type passwordLoginDB interface {
|
||||||
auth.LookupUserDB
|
auth.LookupUserDB
|
||||||
CheckLogin(ctx context.Context, un, pw string) (database.CheckLoginResult, error)
|
CheckLogin(ctx context.Context, un, pw string) (database.CheckLoginResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ auth.Provider = (*BasicLogin)(nil)
|
var (
|
||||||
|
_ auth.Provider = (*PasswordLogin)(nil)
|
||||||
|
_ auth.Form = (*PasswordLogin)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
type BasicLogin struct {
|
type PasswordLogin struct {
|
||||||
DB basicLoginDB
|
DB passwordLoginDB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BasicLogin) AccessState() auth.State { return auth.StateUnauthorized }
|
func (b *PasswordLogin) AccessState() auth.State { return auth.StateBase }
|
||||||
|
|
||||||
func (b *BasicLogin) Name() string { return "basic" }
|
func (b *PasswordLogin) Name() string { return "password" }
|
||||||
|
|
||||||
func (b *BasicLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
func (b *PasswordLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
||||||
// TODO(melon): rewrite this
|
// TODO(melon): rewrite this
|
||||||
req := ctx.Request()
|
req := ctx.Request()
|
||||||
un := req.FormValue("login")
|
un := req.FormValue("login")
|
||||||
@ -43,7 +46,7 @@ func (b *BasicLogin) RenderTemplate(ctx authContext.TemplateContext) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BasicLogin) AttemptLogin(ctx authContext.TemplateContext) error {
|
func (b *PasswordLogin) AttemptLogin(ctx authContext.FormContext) error {
|
||||||
req := ctx.Request()
|
req := ctx.Request()
|
||||||
un := req.FormValue("username")
|
un := req.FormValue("username")
|
||||||
pw := req.FormValue("password")
|
pw := req.FormValue("password")
|
14
auth/redirect-error.go
Normal file
14
auth/redirect-error.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type RedirectError struct {
|
||||||
|
Target string
|
||||||
|
Code int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e RedirectError) TargetUrl() string { return e.Target }
|
||||||
|
|
||||||
|
func (e RedirectError) Error() string {
|
||||||
|
return fmt.Sprintf("redirect to '%s'", e.Target)
|
||||||
|
}
|
37
auth/user-safe-error.go
Normal file
37
auth/user-safe-error.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserSafeError struct {
|
||||||
|
Display string
|
||||||
|
Code int
|
||||||
|
Internal error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UserSafeError) Error() string {
|
||||||
|
return fmt.Sprintf("%s [%d]: %v", e.Display, e.Code, e.Internal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UserSafeError) Unwrap() error {
|
||||||
|
return e.Internal
|
||||||
|
}
|
||||||
|
|
||||||
|
func BasicUserSafeError(code int, message string) UserSafeError {
|
||||||
|
return UserSafeError{
|
||||||
|
Code: code,
|
||||||
|
Display: message,
|
||||||
|
Internal: errors.New(message),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AdminSafeError(inner error) UserSafeError {
|
||||||
|
return UserSafeError{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
Display: "Internal server error",
|
||||||
|
Internal: inner,
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
// source: manage-oauth.sql
|
// source: manage-oauth.sql
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
// source: manage-users.sql
|
// source: manage-users.sql
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
// source: otp.sql
|
// source: otp.sql
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
// source: profiles.sql
|
// source: profiles.sql
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
// source: roles.sql
|
// source: roles.sql
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.25.0
|
// sqlc v1.28.0
|
||||||
// source: users.sql
|
// source: users.sql
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
@ -54,7 +54,11 @@ func (h *httpServer) testAuthSources(req *http.Request, user *database.User, fac
|
|||||||
if i.AccessState() != factor {
|
if i.AccessState() != factor {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err := i.RenderTemplate(authContext.NewTemplateContext(req, user))
|
form, ok := i.(auth.Form)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err := form.RenderTemplate(authContext.NewTemplateContext(req, user))
|
||||||
authSource[i.Name()] = err == nil
|
authSource[i.Name()] = err == nil
|
||||||
clear(data)
|
clear(data)
|
||||||
}
|
}
|
||||||
@ -70,7 +74,7 @@ func (h *httpServer) getAuthWithState(state auth.State) auth.Provider {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpServer) renderAuthTemplate(req *http.Request, provider auth.Provider) (template.HTML, error) {
|
func (h *httpServer) renderAuthTemplate(req *http.Request, provider auth.Form) (template.HTML, error) {
|
||||||
tmpCtx := authContext.NewTemplateContext(req, new(database.User))
|
tmpCtx := authContext.NewTemplateContext(req, new(database.User))
|
||||||
|
|
||||||
err := provider.RenderTemplate(tmpCtx)
|
err := provider.RenderTemplate(tmpCtx)
|
||||||
@ -119,9 +123,18 @@ func (h *httpServer) loginGet(rw http.ResponseWriter, req *http.Request, _ httpr
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonTemplates := make([]template.HTML, len(h.authButtons))
|
buttonCtx := authContext.NewTemplateContext(req, new(database.User))
|
||||||
|
|
||||||
|
buttonTemplates := make([]template.HTML, 0, len(h.authButtons))
|
||||||
for i := range h.authButtons {
|
for i := range h.authButtons {
|
||||||
buttonTemplates[i] = h.authButtons[i].RenderButtonTemplate(req.Context(), req)
|
h.authButtons[i].RenderButtonTemplate(buttonCtx)
|
||||||
|
if buttonCtx.Data() != nil {
|
||||||
|
// TODO: finish the buttons here
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
web.RenderPageTemplate(buf, "auth-buttons/"+h.authButtons[i].Name(), buttonCtx.Data())
|
||||||
|
buttonTemplates = append(buttonTemplates, template.HTML(buf.String()))
|
||||||
|
buttonCtx.Render(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type loginError struct {
|
type loginError struct {
|
||||||
@ -133,8 +146,9 @@ func (h *httpServer) loginGet(rw http.ResponseWriter, req *http.Request, _ httpr
|
|||||||
provider := h.getAuthWithState(auth.StateUnauthorized)
|
provider := h.getAuthWithState(auth.StateUnauthorized)
|
||||||
|
|
||||||
// Maybe the admin has disabled some login providers but does have a button based provider available?
|
// Maybe the admin has disabled some login providers but does have a button based provider available?
|
||||||
if provider != nil {
|
form, ok := provider.(auth.Form)
|
||||||
renderTemplate, err = h.renderAuthTemplate(req, provider)
|
if provider != nil && ok {
|
||||||
|
renderTemplate, err = h.renderAuthTemplate(req, form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Logger.Warn("No provider for login")
|
logger.Logger.Warn("No provider for login")
|
||||||
web.RenderPageTemplate(rw, "login-error", loginError{Error: "No available provider for login"})
|
web.RenderPageTemplate(rw, "login-error", loginError{Error: "No available provider for login"})
|
||||||
|
@ -55,7 +55,7 @@ type mailLinkKey struct {
|
|||||||
func SetupRouter(r *httprouter.Router, config conf.Conf, mailSender *mail.Mail, db *database.Queries, signingKey *mjwt.Issuer) {
|
func SetupRouter(r *httprouter.Router, config conf.Conf, mailSender *mail.Mail, db *database.Queries, signingKey *mjwt.Issuer) {
|
||||||
// TODO: move auth provider init to main function
|
// TODO: move auth provider init to main function
|
||||||
// TODO: allow dynamically changing the providers based on database information
|
// TODO: allow dynamically changing the providers based on database information
|
||||||
authBasic := &providers.BasicLogin{DB: db}
|
authBasic := &providers.PasswordLogin{DB: db}
|
||||||
authOtp := &providers.OtpLogin{DB: db}
|
authOtp := &providers.OtpLogin{DB: db}
|
||||||
authOAuth := &providers.OAuthLogin{DB: db, BaseUrl: &config.BaseUrl}
|
authOAuth := &providers.OAuthLogin{DB: db, BaseUrl: &config.BaseUrl}
|
||||||
authOAuth.Init()
|
authOAuth.Init()
|
||||||
|
@ -8,5 +8,8 @@ export const partial = true;
|
|||||||
<label for="field_email">Email:</label>
|
<label for="field_email">Email:</label>
|
||||||
<input type="email" name="email" id="field_email" value="[[.UserEmail]]" required/>
|
<input type="email" name="email" id="field_email" value="[[.UserEmail]]" required/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Remember Me? <input type="checkbox" name="remember-me"/></label>
|
||||||
|
</div>
|
||||||
<button type="submit">Login</button>
|
<button type="submit">Login</button>
|
||||||
</form>
|
</form>
|
@ -4,10 +4,7 @@ export const partial = true;
|
|||||||
|
|
||||||
<form method="POST" action="/login">
|
<form method="POST" action="/login">
|
||||||
<input type="hidden" name="redirect" value="[[.Redirect]]"/>
|
<input type="hidden" name="redirect" value="[[.Redirect]]"/>
|
||||||
<div>
|
<input type="hidden" name="email" value="[[.UserEmail]]"/>
|
||||||
<label for="field_email">Email:</label>
|
|
||||||
<input type="email" name="email" id="field_email" value="[[.UserEmail]]" required/>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<label for="field_password">Password:</label>
|
<label for="field_password">Password:</label>
|
||||||
<input type="password" name="password" id="field_password" autofocus required/>
|
<input type="password" name="password" id="field_password" autofocus required/>
|
Loading…
x
Reference in New Issue
Block a user