Skip to content

Commit

Permalink
finish setting up middleware to verify requests
Browse files Browse the repository at this point in the history
  • Loading branch information
Cijin committed Oct 17, 2024
1 parent 6d22f79 commit 7902838
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 119 deletions.
14 changes: 0 additions & 14 deletions pkg/authenticator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,6 @@ func (a *Authenticator) Authenticate(r *http.Request, opts ...oauth2.AuthCodeOpt
return token, user, nil
}

func (a *Authenticator) VerifyIdToken(ctx context.Context, providerName string, token *oauth2.Token) (data.SessionUser, error) {
provider, ok := a.providers[providerName]
if !ok {
return data.SessionUser{}, fmt.Errorf("Provider:'%s' is not a registered provider", providerName)
}

idToken, err := provider.VerifyIdToken(ctx, token)
if err != nil {
return data.SessionUser{}, err
}

return provider.GetUserInfo(idToken)
}

func (a *Authenticator) RefreshToken(ctx context.Context, providerName, refreshToken string) (*oauth2.Token, error) {
provider, ok := a.providers[providerName]
if !ok {
Expand Down
12 changes: 0 additions & 12 deletions pkg/data/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,6 @@ func (su SessionUser) Valid(ctx context.Context) Problems {
return problems
}

func (su SessionUser) IsSessionEqual(cmp SessionUser) bool {
if su.Sub != cmp.Sub {
return false
}

if su.Email != cmp.Email {
return false
}

return true
}

type SessionVerifier struct {
Verifier string
State uuid.UUID
Expand Down
21 changes: 9 additions & 12 deletions pkg/handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package handlers

import (
"database/sql"
"errors"
"fmt"
"log/slog"
"net/http"
Expand All @@ -14,12 +13,13 @@ import (
"shave/views/home"
"shave/views/unauthorized"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"golang.org/x/oauth2"
)

const tokenExpiryThreshold = time.Minute * (-5)

type authedHandler func(w http.ResponseWriter, r *http.Request, sessionUser data.SessionUser)

func (h *HttpHandler) CheckAuthoziation(w http.ResponseWriter, r *http.Request) (data.SessionUser, error) {
Expand All @@ -35,19 +35,17 @@ func (h *HttpHandler) CheckAuthoziation(w http.ResponseWriter, r *http.Request)
return user, err
}

// TODO: this does not work without metadata in the token
// save session id and check saved access token instead??
idTokenUserInfo, err := h.authenticator.VerifyIdToken(r.Context(), session.Provider, &oauth2.Token{AccessToken: session.AccessToken, Expiry: session.Expiry})
savedSession, err := h.dbQueries.GetSession(r.Context(), user.Email)
if err != nil {
if _, ok := err.(*oidc.TokenExpiredError); ok {
return h.refreshToken(w, r, user, session)
}
return data.SessionUser{}, err
}

if savedSession.AccessToken != session.AccessToken || user.UserId.String() != savedSession.UserID {
return data.SessionUser{}, err
}

if !user.IsSessionEqual(idTokenUserInfo) {
return data.SessionUser{}, errors.New("session info does not match id token info")
if session.Expiry.Before(time.Now().Add(tokenExpiryThreshold)) {
return h.refreshToken(w, r, user, session)
}

return user, nil
Expand Down Expand Up @@ -240,6 +238,5 @@ func (h *HttpHandler) AuthCallback(w http.ResponseWriter, r *http.Request) {
return
}

w.Header().Set("HX-Push-Url", "/")
renderComponent(w, r, home.SessionedHome(sessionUser))
http.Redirect(w, r, "/", http.StatusSeeOther)
}
167 changes: 86 additions & 81 deletions views/components/navigation.templ
Original file line number Diff line number Diff line change
@@ -1,91 +1,96 @@
package components

import (
"fmt"
"shave/pkg/data"
"strings"
"fmt"
"shave/pkg/data"
"strings"
)

templ Navigation(user data.SessionUser) {
<nav class="uk-navbar-container uk-padding-medium uk-padding-remove-vertical">
<div uk-navbar>
<div class="uk-navbar-left" hx-boost="true">
<a class="flex flex-shrink-0 items-center cursor-pointer" href="/" aria-label="Back to Home">
<img class="h-8 w-auto" src="/assets/logo.svg" />
</a>
<ul class="uk-navbar-nav">
<li>
<a href="/todo">
Todo
</a>
</li>
</ul>
</div>
<div class="uk-navbar-right">
<div class="uk-navbar-item space-x-2">
if user.Email == "" {
<a href="/login/google" class="uk-button uk-button-default" aria-label="login with google">
<img width="20" height="20" src="/assets/google-icon.svg" class="uk-margin-small-right uk-preserve" uk-svg />
Login with Google
</a>
} else {
@UserMenu(user)
}
</div>
<div class="uk-navbar-item">
@ThemeSwitcher()
</div>
</div>
</div>
</nav>
<nav class="uk-navbar-container uk-padding-medium uk-padding-remove-vertical">
<div uk-navbar>
<div class="uk-navbar-left" hx-boost="true">
<a class="flex flex-shrink-0 items-center cursor-pointer" href="/" aria-label="Back to Home">
<img class="h-8 w-auto" src="/assets/logo.svg"/>
</a>
<ul class="uk-navbar-nav">
<li>
<a href="/todo">
Todo
</a>
</li>
</ul>
</div>
<div class="uk-navbar-right">
<div class="uk-navbar-item space-x-2">
if user.Email == "" {
<a href="/login/google" class="uk-button uk-button-default" aria-label="login with google">
<img width="20" height="20" src="/assets/google-icon.svg" class="uk-margin-small-right uk-preserve" uk-svg/>
Login with Google
</a>
} else {
@UserMenu(user)
}
</div>
<div class="uk-navbar-item">
@ThemeSwitcher()
</div>
</div>
</div>
</nav>
}

templ UserMenu(user data.SessionUser) {
<div class="flex-none">
<a class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-accent ring-ring focus:outline-none focus-visible:ring-1"
href="#">
<span class="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-full">
if user.AvatarURL == "" {
<img class="aspect-square h-full w-full" alt="@shadcn" src={
fmt.Sprintf("https://api.dicebear.com/9.x/initials/svg?seed=%s", strings.Split(user.Email, "@" )[0]) } />
} else {
<img class="aspect-square h-full w-full" alt="user image" src={ user.AvatarURL } />
}
</span>
</a>
<div hx-boost="true" class="uk-dropdown uk-drop" uk-dropdown="mode: click; pos: bottom-right">
<ul class="uk-dropdown-nav uk-nav">
<li class="px-2 py-1.5 text-sm">
<div class="flex flex-col space-y-2">
<p class="text-sm font-medium leading-none">{ strings.Split(user.Email, "@")[0] }</p>
<p class="text-xs leading-none text-muted-foreground">
{ user.Email }
</p>
</div>
</li>
<li class="uk-nav-divider"></li>
<li>
<a class="uk-drop-close justify-between" href="/permissions" uk-toggle>
Manage Permissions
</a>
</li>
<li>
<a class="uk-drop-close justify-between" href="#" uk-toggle>
Billing
</a>
</li>
<li>
<a class="uk-drop-close justify-between" href="#" uk-toggle>
Organization Settings
</a>
</li>
<li class="uk-nav-divider"></li>
<li>
<a class="uk-drop-close justify-between" href="/logout" uk-toggle>
Logout
</a>
</li>
</ul>
</div>
</div>
<div class="flex-none">
<a
class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-accent ring-ring focus:outline-none focus-visible:ring-1"
href="#"
>
<span class="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-full">
if user.AvatarURL == "" {
<img
class="aspect-square h-full w-full"
alt="@shadcn"
src={ fmt.Sprintf("https://api.dicebear.com/9.x/initials/svg?seed=%s", strings.Split(user.Email, "@")[0]) }
/>
} else {
<img class="aspect-square h-full w-full" alt="user image" src={ user.AvatarURL }/>
}
</span>
</a>
<div hx-boost="true" class="uk-dropdown uk-drop" uk-dropdown="mode: click; pos: bottom-right">
<ul class="uk-dropdown-nav uk-nav">
<li class="px-2 py-1.5 text-sm">
<div class="flex flex-col space-y-2">
<p class="text-sm font-medium leading-none">{ user.Name }</p>
<p class="text-xs leading-none text-muted-foreground">
{ user.Email }
</p>
</div>
</li>
<li class="uk-nav-divider"></li>
<li>
<a class="uk-drop-close justify-between" href="/permissions" uk-toggle>
Manage Permissions
</a>
</li>
<li>
<a class="uk-drop-close justify-between" href="#" uk-toggle>
Billing
</a>
</li>
<li>
<a class="uk-drop-close justify-between" href="#" uk-toggle>
Organization Settings
</a>
</li>
<li class="uk-nav-divider"></li>
<li>
<a class="uk-drop-close justify-between" href="/logout" uk-toggle>
Logout
</a>
</li>
</ul>
</div>
</div>
}

0 comments on commit 7902838

Please sign in to comment.