aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAKP <tom@tdpain.net>2022-08-13 23:01:45 +0100
committerAKP <tom@tdpain.net>2022-08-13 23:01:45 +0100
commit2f0fdd25d62bdf0297f3b2f28e51713e82718013 (patch)
tree39df8bc902915553fc6849d948b68c26bdea79e7
parentb91f9d6a5ebc3c8499430102aa4f2e1dbfbdd121 (diff)
Add OIDC support
Signed-off-by: AKP <tom@tdpain.net>
-rw-r--r--go.mod9
-rw-r--r--go.sum25
-rw-r--r--walrss/internal/core/users.go22
-rw-r--r--walrss/internal/http/auth.go113
-rw-r--r--walrss/internal/http/http.go28
-rw-r--r--walrss/internal/http/views/signin.qtpl.html5
-rw-r--r--walrss/internal/http/views/signin.qtpl.html.go13
-rw-r--r--walrss/internal/state/state.go6
-rw-r--r--walrss/internal/urls/urls.go9
9 files changed, 223 insertions, 7 deletions
diff --git a/go.mod b/go.mod
index 773c7ff..19a041d 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.19
require (
github.com/bwmarrin/go-alone v0.0.0-20190806015146-742bb55d1631
github.com/carlmjohnson/requests v0.22.2
+ github.com/coreos/go-oidc v2.2.1+incompatible
github.com/gofiber/fiber/v2 v2.31.0
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
github.com/kkyr/fig v0.3.0
@@ -21,6 +22,7 @@ require (
github.com/valyala/fasthttp v1.34.0
github.com/valyala/quicktemplate v1.7.0
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
+ golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7
)
require (
@@ -31,6 +33,7 @@ require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/andybalholm/cascadia v1.1.0 // indirect
github.com/fatih/color v1.13.0 // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
@@ -49,6 +52,7 @@ require (
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml v1.9.3 // indirect
+ github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
@@ -56,9 +60,12 @@ require (
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
- golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
+ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/text v0.3.7 // indirect
+ google.golang.org/appengine v1.6.7 // indirect
+ google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/russross/blackfriday.v2 v2.0.0 // indirect
+ gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index 4fa2365..f35d214 100644
--- a/go.sum
+++ b/go.sum
@@ -17,6 +17,8 @@ github.com/bwmarrin/go-alone v0.0.0-20190806015146-742bb55d1631 h1:Xb5rra6jJt5Z1
github.com/bwmarrin/go-alone v0.0.0-20190806015146-742bb55d1631/go.mod h1:P86Dksd9km5HGX5UMIocXvX87sEp2xUARle3by+9JZ4=
github.com/carlmjohnson/requests v0.22.2 h1:hccG5g9ITJlnDip54OVa810AkB366kthFjvA90N4owM=
github.com/carlmjohnson/requests v0.22.2/go.mod h1:Hw4fFOk3xDlHQbNRTGo4oc52TUTpVEq93sNy/H+mrQM=
+github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
+github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -27,7 +29,13 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofiber/fiber/v2 v2.31.0 h1:M2rWPQbD5fDVAjcoOLjKRXTIlHesI5Eq7I5FEQPt4Ow=
github.com/gofiber/fiber/v2 v2.31.0/go.mod h1:1Ega6O199a3Y7yDGuM9FyXDPYQfv+7/y48wl6WCwUF4=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -86,6 +94,8 @@ github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
+github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
@@ -132,6 +142,7 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -139,8 +150,11 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ=
+golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7 h1:dtndE8FcEta75/4kHF3AbpuWzV6f1LjnLrM4pe2SZrw=
+golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -171,11 +185,20 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/russross/blackfriday.v2 v2.0.0 h1:+FlnIV8DSQnT7NZ43hcVKcdJdzZoeCmJj4Ql8gq5keA=
gopkg.in/russross/blackfriday.v2 v2.0.0/go.mod h1:6sSBNz/GtOm/pJTuh5UmBK2ZHfmnxGbl2NZg1UliSOI=
+gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
+gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
diff --git a/walrss/internal/core/users.go b/walrss/internal/core/users.go
index 5c17251..dfd2c86 100644
--- a/walrss/internal/core/users.go
+++ b/walrss/internal/core/users.go
@@ -45,12 +45,34 @@ func RegisterUser(st *state.State, email, password string) (*db.User, error) {
return u, nil
}
+func RegisterUserOIDC(st *state.State, email string) (*db.User, error) {
+ u := &db.User{
+ ID: shortuuid.New(),
+ Email: email,
+ }
+
+ if _, err := st.Data.NewInsert().Model(u).Exec(context.Background()); err != nil {
+ if e, ok := err.(*sqlite3.Error); ok {
+ if e.Code == sqlite3.ErrConstraint {
+ return nil, NewUserError("email address in use")
+ }
+ }
+ return nil, err
+ }
+
+ return u, nil
+}
+
func AreUserCredentialsCorrect(st *state.State, email, password string) (bool, error) {
user, err := GetUserByEmail(st, email)
if err != nil {
return false, err
}
+ if len(user.Password) == 0 {
+ return false, nil
+ }
+
if err := bcrypt.CompareHashAndPassword(user.Password, combineStringAndSalt(password, user.Salt)); err != nil {
if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
return false, nil
diff --git a/walrss/internal/http/auth.go b/walrss/internal/http/auth.go
index a9ceca6..af098fa 100644
--- a/walrss/internal/http/auth.go
+++ b/walrss/internal/http/auth.go
@@ -1,12 +1,15 @@
package http
import (
+ "context"
"errors"
"github.com/codemicro/walrss/walrss/internal/core"
"github.com/codemicro/walrss/walrss/internal/http/views"
"github.com/codemicro/walrss/walrss/internal/urls"
"github.com/gofiber/fiber/v2"
"github.com/stevelacy/daz"
+ "math/rand"
+ "sync"
"time"
)
@@ -74,7 +77,8 @@ success:
func (s *Server) authSignIn(ctx *fiber.Ctx) error {
page := &views.SignInPage{
- Problem: ctx.Query("problem"),
+ Problem: ctx.Query("problem"),
+ OIDCEnabled: s.state.Config.OIDC.Enable,
}
if getCurrentUserID(ctx) != "" {
@@ -127,3 +131,110 @@ incorrectUsernameOrPassword:
ctx.Status(fiber.StatusUnauthorized)
return views.SendPage(ctx, &views.SignInPage{Problem: "Incorrect username or password"})
}
+
+var (
+ knownStates = make(map[string]time.Time)
+ stateLock sync.Mutex
+)
+
+func init() {
+ rand.Seed(time.Now().Unix())
+
+ go func() {
+ time.Sleep(time.Minute * 5)
+ stateLock.Lock()
+
+ var toDelete []string
+
+ for k, v := range knownStates {
+ if !v.After(time.Now().UTC()) {
+ toDelete = append(toDelete, k)
+ }
+ }
+
+ for _, k := range toDelete {
+ delete(knownStates, k)
+ }
+
+ stateLock.Unlock()
+ }()
+}
+
+func (s *Server) authOIDCOutbound(ctx *fiber.Ctx) error {
+ if !s.state.Config.OIDC.Enable {
+ return core.NewUserErrorWithStatus(fiber.StatusForbidden, "OIDC is disabled")
+ }
+
+ b := make([]byte, 30)
+ for i := 0; i < len(b); i++ {
+ b[i] = byte(65 + rand.Intn(25))
+ }
+ knownStates[string(b)] = time.Now().UTC().Add(time.Minute * 2)
+
+ return ctx.Redirect(s.oauth2Config.AuthCodeURL(string(b)))
+}
+
+func (s *Server) authOIDCCallback(ctx *fiber.Ctx) error {
+ if !s.state.Config.OIDC.Enable {
+ return core.NewUserErrorWithStatus(fiber.StatusForbidden, "OIDC is disabled")
+ }
+
+ providedState := ctx.Query("state")
+ stateLock.Lock()
+ if exp, ok := knownStates[providedState]; ok && exp.After(time.Now().UTC()) {
+ delete(knownStates, providedState)
+ stateLock.Unlock()
+ } else {
+ stateLock.Unlock()
+ return core.NewUserError("Invalid state")
+ }
+
+ oauth2Token, err := s.oauth2Config.Exchange(context.Background(), ctx.Query("code"))
+ if err != nil {
+ return err
+ }
+
+ rawIDToken, ok := oauth2Token.Extra("id_token").(string)
+ if !ok {
+ return errors.New("missing ID token")
+ }
+
+ idToken, err := s.oidcVerifier.Verify(context.Background(), rawIDToken)
+ if err != nil {
+ return err
+ }
+
+ var claims struct {
+ Email string `json:"email"`
+ }
+ if err := idToken.Claims(&claims); err != nil {
+ return err
+ }
+
+ user, err := core.GetUserByEmail(s.state, claims.Email)
+ if err != nil {
+ if errors.Is(err, core.ErrNotFound) {
+ if s.state.Config.Platform.DisableRegistration {
+ return core.NewUserError("Cannot register user on-demand as registrations are disabled.")
+ }
+ user, err = core.RegisterUserOIDC(s.state, claims.Email)
+ if err != nil {
+ return err
+ }
+ } else {
+ return err
+ }
+ }
+
+ token := core.GenerateSessionToken(user.ID)
+
+ ctx.Cookie(&fiber.Cookie{
+ Name: sessionCookieKey,
+ Value: token,
+ Expires: time.Now().UTC().Add(sessionDuration),
+ Secure: s.state.Config.EnableSecureCookies(),
+ HTTPOnly: true,
+ })
+
+ return ctx.Redirect(urls.Index)
+}
diff --git a/walrss/internal/http/http.go b/walrss/internal/http/http.go
index 36255bc..892b261 100644
--- a/walrss/internal/http/http.go
+++ b/walrss/internal/http/http.go
@@ -1,15 +1,19 @@
package http
import (
+ "context"
"github.com/codemicro/walrss/walrss/internal/core"
"github.com/codemicro/walrss/walrss/internal/http/views"
"github.com/codemicro/walrss/walrss/internal/state"
"github.com/codemicro/walrss/walrss/internal/static"
"github.com/codemicro/walrss/walrss/internal/urls"
+ "github.com/coreos/go-oidc"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
"github.com/stevelacy/daz"
+ "golang.org/x/oauth2"
"net/url"
+ "strings"
"time"
)
@@ -22,6 +26,10 @@ const (
type Server struct {
state *state.State
app *fiber.App
+
+ oidcProvider *oidc.Provider
+ oidcVerifier *oidc.IDTokenVerifier
+ oauth2Config *oauth2.Config
}
func New(st *state.State) (*Server, error) {
@@ -53,6 +61,23 @@ func New(st *state.State) (*Server, error) {
app: app,
}
+ if st.Config.OIDC.Enable {
+ provider, err := oidc.NewProvider(context.Background(), st.Config.OIDC.Issuer)
+ if err != nil {
+ return nil, err
+ }
+
+ s.oidcProvider = provider
+ s.oidcVerifier = provider.Verifier(&oidc.Config{ClientID: st.Config.OIDC.ClientID})
+ s.oauth2Config = &oauth2.Config{
+ ClientID: st.Config.OIDC.ClientID,
+ ClientSecret: st.Config.OIDC.ClientSecret,
+ Endpoint: provider.Endpoint(),
+ RedirectURL: strings.TrimSuffix(st.Config.Server.ExternalURL, "/") + urls.AuthOIDCCallback,
+ Scopes: []string{"email", "profile", "openid"},
+ }
+ }
+
s.registerHandlers()
return s, nil
@@ -78,6 +103,9 @@ func (s *Server) registerHandlers() {
s.app.Get(urls.AuthSignIn, s.authSignIn)
s.app.Post(urls.AuthSignIn, s.authSignIn)
+ s.app.Get(urls.AuthOIDCOutbound, s.authOIDCOutbound)
+ s.app.Get(urls.AuthOIDCCallback, s.authOIDCCallback)
+
s.app.Put(urls.EditEnabledState, s.editEnabledState)
s.app.Put(urls.EditTimings, s.editTimings)
diff --git a/walrss/internal/http/views/signin.qtpl.html b/walrss/internal/http/views/signin.qtpl.html
index 3022f7f..b0c7d4a 100644
--- a/walrss/internal/http/views/signin.qtpl.html
+++ b/walrss/internal/http/views/signin.qtpl.html
@@ -3,6 +3,7 @@
{% code type SignInPage struct {
BasePage
Problem string
+ OIDCEnabled bool
} %}
{% func (p *SignInPage) Title() %}Sign in{% endfunc %}
@@ -29,5 +30,9 @@
</form>
<br>
<a href="{%s= urls.AuthRegister %}">No account? Click here to register</a>
+ <br>
+ {% if p.OIDCEnabled %}
+ <a href="{%s= urls.AuthOIDCOutbound %}">Click here to login with OIDC</a>
+ {% endif %}
</div>
{% endfunc %} \ No newline at end of file
diff --git a/walrss/internal/http/views/signin.qtpl.html.go b/walrss/internal/http/views/signin.qtpl.html.go
index ba433dd..35e9fb7 100644
--- a/walrss/internal/http/views/signin.qtpl.html.go
+++ b/walrss/internal/http/views/signin.qtpl.html.go
@@ -18,7 +18,8 @@ var (
type SignInPage struct {
BasePage
- Problem string
+ Problem string
+ OIDCEnabled bool
}
func (p *SignInPage) StreamTitle(qw422016 *qt422016.Writer) {
@@ -73,6 +74,16 @@ func (p *SignInPage) StreamBody(qw422016 *qt422016.Writer) {
<a href="`)
qw422016.N().S(urls.AuthRegister)
qw422016.N().S(`">No account? Click here to register</a>
+ <br>
+ `)
+ if p.OIDCEnabled {
+ qw422016.N().S(`
+ <a href="`)
+ qw422016.N().S(urls.AuthOIDCOutbound)
+ qw422016.N().S(`">Click here to login with OIDC</a>
+ `)
+ }
+ qw422016.N().S(`
</div>
`)
}
diff --git a/walrss/internal/state/state.go b/walrss/internal/state/state.go
index a65a261..227f49e 100644
--- a/walrss/internal/state/state.go
+++ b/walrss/internal/state/state.go
@@ -37,6 +37,12 @@ type Config struct {
DisableRegistration bool `fig:"disableRegistration"`
DisableSecureCookies bool `fig:"disableSecureCookies"`
}
+ OIDC struct {
+ Enable bool `fig:"enable"`
+ ClientID string `fig:"clientID"`
+ ClientSecret string `fig:"clientSecret"`
+ Issuer string `fig:"issuer"`
+ }
Debug bool `fig:"debug"`
}
diff --git a/walrss/internal/urls/urls.go b/walrss/internal/urls/urls.go
index 5cf166b..5b2fc69 100644
--- a/walrss/internal/urls/urls.go
+++ b/walrss/internal/urls/urls.go
@@ -8,9 +8,12 @@ import (
const (
Index = "/"
- Auth = "/auth"
- AuthSignIn = Auth + "/signin"
- AuthRegister = Auth + "/register"
+ Auth = "/auth"
+ AuthSignIn = Auth + "/signin"
+ AuthRegister = Auth + "/register"
+ AuthOIDC = Auth + "/oidc"
+ AuthOIDCOutbound = AuthOIDC + "/outbound"
+ AuthOIDCCallback = AuthOIDC + "/callback"
Edit = "/edit"
EditEnabledState = Edit + "/enabled"