feat: initial commit

This commit is contained in:
2025-02-22 09:42:15 +01:00
parent ee4a65b345
commit e6e5c9b04d
43 changed files with 1191 additions and 247 deletions

View File

@ -17,15 +17,15 @@ templ LoginPage(vmodel LoginPageVModel) {
<div class="is-flex is-justify-content-center is-align-items-center is-fullheight">
<nav class="panel is-link" style="min-width: 33%">
<p class="panel-heading">
<div class="title">ClearCase</div>
<span>&nbsp;- choose your provider</span>
<span class="title">ClearCase</span>
<span>&nbsp;- choose your platform</span>
</p>
for _, provider := range vmodel.Providers {
<a class="panel-block" href={ templ.URL("/auth/providers/" + provider.ID) } hx-boost="false">
<a class="panel-block py-5" href={ templ.URL("/auth/providers/" + provider.ID) } hx-boost="false">
<span class="panel-icon is-size-3">
<i class={ "fab", provider.Icon } aria-hidden="true"></i>
</span>
{ provider.Label }
<span class="is-size-5">{ provider.Label }</span>
</a>
}
</nav>

View File

@ -53,12 +53,12 @@ func LoginPage(vmodel LoginPageVModel) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"is-flex is-justify-content-center is-align-items-center is-fullheight\"><nav class=\"panel is-link\" style=\"min-width: 33%\"><p class=\"panel-heading\"><div class=\"title\">ClearCase</div><span>&nbsp;- choose your provider</span></p>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"is-flex is-justify-content-center is-align-items-center is-fullheight\"><nav class=\"panel is-link\" style=\"min-width: 33%\"><p class=\"panel-heading\"><span class=\"title\">ClearCase</span> <span>&nbsp;- choose your platform</span></p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for _, provider := range vmodel.Providers {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<a class=\"panel-block\" href=\"")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<a class=\"panel-block py-5\" href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -89,20 +89,20 @@ func LoginPage(vmodel LoginPageVModel) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" aria-hidden=\"true\"></i></span> ")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" aria-hidden=\"true\"></i></span> <span class=\"is-size-5\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(provider.Label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/http/handler/webui/auth/component/login_page.templ`, Line: 28, Col: 22}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/http/handler/webui/auth/component/login_page.templ`, Line: 28, Col: 46}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</a>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</span></a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@ -15,7 +15,6 @@ type Handler struct {
sessionStore sessions.Store
sessionName string
providers []Provider
defaultAdmin *DefaultAdmin
}
// ServeHTTP implements http.Handler.
@ -30,7 +29,6 @@ func NewHandler(sessionStore sessions.Store, funcs ...OptionFunc) *Handler {
sessionStore: sessionStore,
sessionName: opts.SessionName,
providers: opts.Providers,
defaultAdmin: opts.DefaultAdmin,
}
h.mux.HandleFunc("GET /login", h.getLoginPage)

View File

@ -1,14 +1,8 @@
package auth
type DefaultAdmin struct {
Provider string
Email string
}
type Options struct {
Providers []Provider
DefaultAdmin *DefaultAdmin
SessionName string
Providers []Provider
SessionName string
}
type OptionFunc func(opts *Options)
@ -16,7 +10,7 @@ type OptionFunc func(opts *Options)
func NewOptions(funcs ...OptionFunc) *Options {
opts := &Options{
Providers: make([]Provider, 0),
SessionName: "rkvst_auth",
SessionName: "clearcase_auth",
}
for _, fn := range funcs {
@ -32,12 +26,6 @@ func WithProviders(providers ...Provider) OptionFunc {
}
}
func WithDefaultAdmin(defaultAdmin DefaultAdmin) OptionFunc {
return func(opts *Options) {
opts.DefaultAdmin = &defaultAdmin
}
}
func WithSessionName(sessionName string) OptionFunc {
return func(opts *Options) {
opts.SessionName = sessionName

View File

@ -5,6 +5,7 @@ import (
"log/slog"
"net/http"
"forge.cadoles.com/wpetit/clearcase/internal/core/model"
"forge.cadoles.com/wpetit/clearcase/internal/http/handler/webui/common"
"github.com/markbates/goth/gothic"
"github.com/pkg/errors"
@ -19,7 +20,7 @@ func (h *Handler) handleProvider(w http.ResponseWriter, r *http.Request) {
}
func (h *Handler) handleProviderCallback(w http.ResponseWriter, r *http.Request) {
user, err := gothic.CompleteUserAuth(w, r)
gothUser, err := gothic.CompleteUserAuth(w, r)
if err != nil {
slog.ErrorContext(r.Context(), "could not complete user auth", slog.Any("error", errors.WithStack(err)))
http.Redirect(w, r, "/auth/logout", http.StatusTemporaryRedirect)
@ -28,9 +29,16 @@ func (h *Handler) handleProviderCallback(w http.ResponseWriter, r *http.Request)
ctx := r.Context()
slog.DebugContext(ctx, "authenticated user", slog.Any("user", user))
slog.DebugContext(ctx, "authenticated user", slog.Any("user", gothUser))
if err := h.storeSessionUser(w, r, &user); err != nil {
user := &model.User{
ID: gothUser.UserID,
Provider: gothUser.Provider,
AccessToken: gothUser.AccessToken,
IDToken: gothUser.IDToken,
}
if err := h.storeSessionUser(w, r, user); err != nil {
slog.ErrorContext(r.Context(), "could not store session user", slog.Any("error", errors.WithStack(err)))
http.Redirect(w, r, "/auth/logout", http.StatusTemporaryRedirect)
return

View File

@ -1,11 +1,12 @@
package auth
import (
"encoding/gob"
"log/slog"
"net/http"
"forge.cadoles.com/wpetit/clearcase/internal/core/model"
"github.com/gorilla/sessions"
"github.com/markbates/goth"
"github.com/pkg/errors"
)
@ -14,7 +15,11 @@ const tenantIDAttr = "t"
var errSessionNotFound = errors.New("session not found")
func (h *Handler) storeSessionUser(w http.ResponseWriter, r *http.Request, user *goth.User) error {
func init() {
gob.Register(&model.User{})
}
func (h *Handler) storeSessionUser(w http.ResponseWriter, r *http.Request, user *model.User) error {
sess, err := h.getSession(r)
if err != nil {
return errors.WithStack(err)
@ -29,13 +34,13 @@ func (h *Handler) storeSessionUser(w http.ResponseWriter, r *http.Request, user
return nil
}
func (h *Handler) retrieveSessionUser(r *http.Request) (*goth.User, error) {
func (h *Handler) retrieveSessionUser(r *http.Request) (*model.User, error) {
sess, err := h.getSession(r)
if err != nil {
return nil, errors.WithStack(err)
}
user, ok := sess.Values[userAttr].(*goth.User)
user, ok := sess.Values[userAttr].(*model.User)
if !ok {
return nil, errors.WithStack(errSessionNotFound)
}