aboutsummaryrefslogtreecommitdiff
path: root/server/server.go
blob: dc71c9572ebf91beb21adaf408799a1bc6f92d6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package server

import (
	"fmt"

	"github.com/fasthttp/router"
	"github.com/valyala/fasthttp"
	"github.com/zitadel/oidc/pkg/client/rp"
)

func IsAuthenticate(relayPartyProvider rp.RelyingParty, next fasthttp.RequestHandler) fasthttp.RequestHandler {
	return func(ctx *fasthttp.RequestCtx) {
		token := string(ctx.Request.Header.Cookie("token"))
		tokenVerifier := relayPartyProvider.IDTokenVerifier()
		_, err := rp.VerifyIDToken(ctx, token, tokenVerifier)
		if err != nil {
			ctx.Redirect("/login", 307)
			return
		}
		next(ctx)
	}
}

func NewS4OServer(clientID, clientSecret, issuer, callback, rootPath string, scopes []string) (*fasthttp.Server, error) {
	r := router.New()

	relayPartyProvider, err := rp.NewRelyingPartyOIDC(issuer, clientID, clientSecret, callback, scopes)
	if err != nil {
		return nil, err
	}

	fs := &fasthttp.FS{
		Root:               rootPath,
		IndexNames:         []string{"index.html"},
		GenerateIndexPages: true,
		AcceptByteRange:    true,
		Compress:           true,
	}

	r.Handle("GET", "/login", func(ctx *fasthttp.RequestCtx) {
		url := rp.AuthURL(" ", relayPartyProvider)
		ctx.Redirect(url, 307)
	})

	r.Handle("GET", "/callback", func(ctx *fasthttp.RequestCtx) {
		code := string(ctx.QueryArgs().Peek("code"))
		token, err := rp.CodeExchange(ctx, code, relayPartyProvider)
		if err != nil {
			ctx.WriteString(fmt.Sprintf("Error: %+v", err))
			return
		}

		cookie := &fasthttp.Cookie{}
		cookie.SetKey("token")
		cookie.SetValue(token.IDToken)
		cookie.SetExpire(token.Expiry)
		cookie.SetHTTPOnly(true)
		cookie.SetSameSite(fasthttp.CookieSameSiteDefaultMode)
		ctx.Response.Header.SetCookie(cookie)
		ctx.Redirect("/", 307)
	})

	r.Handle("GET", "/{filepath:*}", IsAuthenticate(relayPartyProvider, fs.NewRequestHandler()))

	return &fasthttp.Server{
		Handler: r.Handler,
	}, nil
}