mirror of
https://github.com/1f349/tulip.git
synced 2024-12-22 16:24:10 +00:00
Pass config directly to server
This commit is contained in:
parent
9d9d982d7c
commit
96df1deadf
@ -55,7 +55,7 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...any) subcomm
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
var config startUpConfig
|
||||
var config server.Conf
|
||||
err = json.NewDecoder(openConf).Decode(&config)
|
||||
if err != nil {
|
||||
log.Println("[Tulip] Error: invalid config file: ", err)
|
||||
@ -71,7 +71,7 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...any) subcomm
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
func normalLoad(startUp startUpConfig, wd string) {
|
||||
func normalLoad(startUp server.Conf, wd string) {
|
||||
key := genHmacKey()
|
||||
|
||||
db, err := database.Open(filepath.Join(wd, "tulip.db.sqlite"))
|
||||
@ -91,7 +91,7 @@ func normalLoad(startUp startUpConfig, wd string) {
|
||||
log.Fatal("[Tulip] Failed to load mail templates:", err)
|
||||
}
|
||||
|
||||
srv := server.NewHttpServer(startUp.Listen, startUp.BaseUrl, startUp.OtpIssuer, startUp.ServiceName, startUp.Mail, db, key)
|
||||
srv := server.NewHttpServer(startUp, db, key)
|
||||
log.Printf("[Tulip] Starting HTTP server on '%s'\n", srv.Addr)
|
||||
go utils.RunBackgroundHttp("HTTP", srv)
|
||||
|
||||
@ -122,7 +122,7 @@ func checkDbHasUser(db *database.DB) error {
|
||||
defer tx.Rollback()
|
||||
if err := tx.HasUser(); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
_, err := tx.InsertUser("Admin", "admin", "admin", "admin@localhost", database.RoleAdmin, false)
|
||||
_, err := tx.InsertUser("Admin", "admin", "admin", "admin@localhost", false, database.RoleAdmin, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add user: %w", err)
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ CREATE TABLE IF NOT EXISTS users
|
||||
locale TEXT DEFAULT "en-US" NOT NULL,
|
||||
role INTEGER DEFAULT 0 NOT NULL,
|
||||
updated_at DATETIME,
|
||||
registered INTEGER DEFAULT 0,
|
||||
active INTEGER DEFAULT 1
|
||||
);
|
||||
|
||||
|
@ -37,13 +37,13 @@ func (t *Tx) HasUser() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Tx) InsertUser(name, un, pw, email string, role UserRole, active bool) (uuid.UUID, error) {
|
||||
func (t *Tx) InsertUser(name, un, pw, email string, verifyEmail bool, role UserRole, active bool) (uuid.UUID, error) {
|
||||
pwHash, err := password.HashPassword(pw)
|
||||
if err != nil {
|
||||
return uuid.UUID{}, err
|
||||
}
|
||||
u := uuid.New()
|
||||
_, err = t.tx.Exec(`INSERT INTO users (subject, name, username, password, email, role, updated_at, active) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, u, name, un, pwHash, email, role, updatedAt(), active)
|
||||
_, err = t.tx.Exec(`INSERT INTO users (subject, name, username, password, email, email_verified, role, updated_at, active) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, u, name, un, pwHash, email, verifyEmail, role, updatedAt(), active)
|
||||
return u, err
|
||||
}
|
||||
|
||||
@ -235,18 +235,18 @@ func (t *Tx) InsertClientApp(name, domain string, sso, active bool, owner uuid.U
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *Tx) UpdateClientApp(subject uuid.UUID, name, domain string, sso, active bool) error {
|
||||
_, err := t.tx.Exec(`UPDATE client_store SET name = ?, domain = ?, sso = ?, active = ? WHERE subject = ?`, name, domain, sso, active, subject.String())
|
||||
func (t *Tx) UpdateClientApp(subject, owner uuid.UUID, name, domain string, sso, active bool) error {
|
||||
_, err := t.tx.Exec(`UPDATE client_store SET name = ?, domain = ?, sso = ?, active = ? WHERE subject = ? AND owner = ?`, name, domain, sso, active, subject.String(), owner.String())
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *Tx) ResetClientAppSecret(subject uuid.UUID, secret string) error {
|
||||
func (t *Tx) ResetClientAppSecret(subject, owner uuid.UUID) (string, error) {
|
||||
secret, err := password.GenerateApiSecret(70)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
_, err = t.tx.Exec(`UPDATE client_store SET secret = ? WHERE subject = ?`, secret, subject.String())
|
||||
return err
|
||||
_, err = t.tx.Exec(`UPDATE client_store SET secret = ? WHERE subject = ? AND owner = ?`, secret, subject.String(), owner.String())
|
||||
return secret, err
|
||||
}
|
||||
|
||||
func (t *Tx) GetUserList(offset int) ([]User, error) {
|
||||
|
@ -2,6 +2,30 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{.ServiceName}}</title>
|
||||
<script>
|
||||
window.addEventListener("load", function () {
|
||||
selectText("app-secret");
|
||||
});
|
||||
|
||||
// Thanks again: https://stackoverflow.com/a/987376
|
||||
function selectText(nodeId) {
|
||||
const node = document.getElementById(nodeId);
|
||||
|
||||
if (document.body.createTextRange) {
|
||||
const range = document.body.createTextRange();
|
||||
range.moveToElementText(node);
|
||||
range.select();
|
||||
} else if (window.getSelection) {
|
||||
const selection = window.getSelection();
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(node);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
} else {
|
||||
console.warn("Could not select text in node: Unsupported browser.");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
@ -12,6 +36,10 @@
|
||||
<button type="submit">Home</button>
|
||||
</form>
|
||||
|
||||
{{if .NewAppSecret}}
|
||||
<div>New application secret: <span id="app-secret">{{.NewAppSecret}}</span> for {{.NewAppName}}</div>
|
||||
{{end}}
|
||||
|
||||
{{if .Edit}}
|
||||
<h2>Edit Client Application</h2>
|
||||
<form method="POST" action="/manage/apps">
|
||||
@ -31,11 +59,13 @@
|
||||
</div>
|
||||
{{if .IsAdmin}}
|
||||
<div>
|
||||
<label for="field_sso">SSO: <input type="checkbox" name="sso" id="field_sso" {{if .Edit.SSO}}checked{{end}}/></label>
|
||||
<label for="field_sso">SSO: <input type="checkbox" name="sso" id="field_sso"
|
||||
{{if .Edit.SSO}}checked{{end}}/></label>
|
||||
</div>
|
||||
{{end}}
|
||||
<div>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active" {{if .Edit.Active}}checked{{end}}/></label>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active"
|
||||
{{if .Edit.Active}}checked{{end}}/></label>
|
||||
</div>
|
||||
<button type="submit">Edit</button>
|
||||
</form>
|
||||
@ -75,6 +105,12 @@
|
||||
<input type="hidden" name="edit" value="{{.Sub}}"/>
|
||||
<button type="submit">Edit</button>
|
||||
</form>
|
||||
<form method="POST" action="/manage/apps?offset={{$.Offset}}">
|
||||
<input type="hidden" name="action" value="secret"/>
|
||||
<input type="hidden" name="offset" value="{{$.Offset}}"/>
|
||||
<input type="hidden" name="subject" value="{{.Sub}}"/>
|
||||
<button type="submit">Reset Secret</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
@ -100,7 +136,8 @@
|
||||
</div>
|
||||
{{end}}
|
||||
<div>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active" checked/></label>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active"
|
||||
checked/></label>
|
||||
</div>
|
||||
<button type="submit">Create</button>
|
||||
</form>
|
||||
|
@ -37,7 +37,8 @@
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active" checked/></label>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active"
|
||||
checked/></label>
|
||||
</div>
|
||||
<button type="submit">Edit</button>
|
||||
</form>
|
||||
@ -98,6 +99,10 @@
|
||||
<input type="hidden" name="edit" value="{{.Sub}}"/>
|
||||
<button type="submit">Edit</button>
|
||||
</form>
|
||||
<form method="POST" action="/reset-password">
|
||||
<input type="hidden" name="email" value="{{.Email}}"/>
|
||||
<button type="submit">Send Reset Password Email</button>
|
||||
</form>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
@ -127,6 +132,8 @@
|
||||
</div>
|
||||
<div>
|
||||
<label for="field_email">Email:</label>
|
||||
<p>Using an `@{{.Namespace}}` email address will automatically verify as it is owned by this login
|
||||
service.</p>
|
||||
<input type="text" name="email" id="field_email" required/>
|
||||
</div>
|
||||
<div>
|
||||
@ -137,7 +144,8 @@
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active" checked/></label>
|
||||
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active"
|
||||
checked/></label>
|
||||
</div>
|
||||
<button type="submit">Create</button>
|
||||
</form>
|
||||
|
@ -1,11 +1,12 @@
|
||||
package main
|
||||
package server
|
||||
|
||||
import "github.com/1f349/tulip/mail"
|
||||
|
||||
type startUpConfig struct {
|
||||
type Conf struct {
|
||||
Listen string `json:"listen"`
|
||||
BaseUrl string `json:"base_url"`
|
||||
OtpIssuer string `json:"otp_issuer"`
|
||||
ServiceName string `json:"service_name"`
|
||||
Namespace string `json:"namespace"`
|
||||
Mail mail.Mail `json:"mail"`
|
||||
}
|
@ -31,7 +31,7 @@ func (h *HttpServer) EditGet(rw http.ResponseWriter, _ *http.Request, _ httprout
|
||||
return
|
||||
}
|
||||
pages.RenderPageTemplate(rw, "edit", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"User": user,
|
||||
"Nonce": lNonce,
|
||||
"FieldPronoun": user.Pronouns.String(),
|
||||
|
@ -14,7 +14,7 @@ func (h *HttpServer) Home(rw http.ResponseWriter, req *http.Request, _ httproute
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
if auth.IsGuest() {
|
||||
pages.RenderPageTemplate(rw, "index-guest", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -37,7 +37,7 @@ func (h *HttpServer) Home(rw http.ResponseWriter, req *http.Request, _ httproute
|
||||
return
|
||||
}
|
||||
pages.RenderPageTemplate(rw, "index", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"Auth": auth,
|
||||
"User": userWithName,
|
||||
"Nonce": lNonce,
|
||||
|
@ -43,7 +43,7 @@ func (h *HttpServer) LoginGet(rw http.ResponseWriter, req *http.Request, _ httpr
|
||||
rw.Header().Set("Content-Type", "text/html")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
pages.RenderPageTemplate(rw, "login", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"Redirect": req.URL.Query().Get("redirect"),
|
||||
"Mismatch": req.URL.Query().Get("mismatch"),
|
||||
"LoginName": loginName,
|
||||
@ -100,8 +100,8 @@ func (h *HttpServer) LoginPost(rw http.ResponseWriter, req *http.Request, _ http
|
||||
h.mailLinkCache.Set(mailLinkKey{mailLinkVerifyEmail, u}, userInfo.Sub, time.Now().Add(10*time.Minute))
|
||||
|
||||
// try to send email
|
||||
err = h.mailer.SendEmailTemplate("mail-verify", "Verify Email", userInfo.Name, address, map[string]any{
|
||||
"VerifyUrl": h.domain + "/mail/verify/" + u.String(),
|
||||
err = h.conf.Mail.SendEmailTemplate("mail-verify", "Verify Email", userInfo.Name, address, map[string]any{
|
||||
"VerifyUrl": h.conf.BaseUrl + "/mail/verify/" + u.String(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Println("[Tulip] Login: Failed to send verification email:", err)
|
||||
|
@ -68,7 +68,7 @@ func (h *HttpServer) MailPassword(rw http.ResponseWriter, req *http.Request, par
|
||||
}
|
||||
|
||||
pages.RenderPageTemplate(rw, "reset-password", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
})
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ func (h *HttpServer) MailDelete(rw http.ResponseWriter, req *http.Request, param
|
||||
return
|
||||
}
|
||||
|
||||
err = h.mailer.SendEmailTemplate("mail-account-delete", "Account Deletion", userInfo.Name, address, nil)
|
||||
err = h.conf.Mail.SendEmailTemplate("mail-account-delete", "Account Deletion", userInfo.Name, address, nil)
|
||||
if err != nil {
|
||||
http.Error(rw, "Failed to send confirmation email.", http.StatusInternalServerError)
|
||||
return
|
||||
|
@ -3,6 +3,7 @@ package server
|
||||
import (
|
||||
"github.com/1f349/tulip/database"
|
||||
"github.com/1f349/tulip/pages"
|
||||
"github.com/go-oauth2/oauth2/v4"
|
||||
"github.com/google/uuid"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"net/http"
|
||||
@ -36,10 +37,12 @@ func (h *HttpServer) ManageAppsGet(rw http.ResponseWriter, req *http.Request, _
|
||||
}
|
||||
|
||||
m := map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"Apps": appList,
|
||||
"Offset": offset,
|
||||
"IsAdmin": role == database.RoleAdmin,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"Apps": appList,
|
||||
"Offset": offset,
|
||||
"IsAdmin": role == database.RoleAdmin,
|
||||
"NewAppName": q.Get("NewAppName"),
|
||||
"NewAppSecret": q.Get("NewAppSecret"),
|
||||
}
|
||||
if q.Has("edit") {
|
||||
for _, i := range appList {
|
||||
@ -99,10 +102,43 @@ func (h *HttpServer) ManageAppsPost(rw http.ResponseWriter, req *http.Request, _
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.UpdateClientApp(sub, name, domain, sso, active)
|
||||
return tx.UpdateClientApp(sub, auth.Data.ID, name, domain, sso, active)
|
||||
}) {
|
||||
return
|
||||
}
|
||||
case "secret":
|
||||
var info oauth2.ClientInfo
|
||||
var secret string
|
||||
if h.DbTx(rw, func(tx *database.Tx) error {
|
||||
sub, err := uuid.Parse(req.Form.Get("subject"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err = tx.GetClientInfo(sub.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secret, err = tx.ResetClientAppSecret(sub, auth.Data.ID)
|
||||
return err
|
||||
}) {
|
||||
return
|
||||
}
|
||||
|
||||
appName := "Unknown..."
|
||||
if getName, ok := info.(interface{ GetName() string }); ok {
|
||||
appName = getName.GetName()
|
||||
}
|
||||
|
||||
h.ManageAppsGet(rw, &http.Request{
|
||||
URL: &url.URL{
|
||||
RawQuery: url.Values{
|
||||
"offset": []string{offset},
|
||||
"NewAppName": []string{appName},
|
||||
"NewAppSecret": []string{secret},
|
||||
}.Encode(),
|
||||
},
|
||||
}, httprouter.Params{}, auth)
|
||||
return
|
||||
default:
|
||||
http.Error(rw, "400 Bad Request: Invalid action", http.StatusBadRequest)
|
||||
return
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -44,11 +45,12 @@ func (h *HttpServer) ManageUsersGet(rw http.ResponseWriter, req *http.Request, _
|
||||
}
|
||||
|
||||
m := map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"Users": userList,
|
||||
"Offset": offset,
|
||||
"EmailShow": req.URL.Query().Has("show-email"),
|
||||
"CurrentAdmin": auth.Data.ID,
|
||||
"Namespace": h.conf.Namespace,
|
||||
}
|
||||
if q.Has("edit") {
|
||||
for _, i := range userList {
|
||||
@ -100,28 +102,33 @@ func (h *HttpServer) ManageUsersPost(rw http.ResponseWriter, req *http.Request,
|
||||
|
||||
switch action {
|
||||
case "create":
|
||||
var userSub uuid.UUID
|
||||
if h.DbTx(rw, func(tx *database.Tx) (err error) {
|
||||
userSub, err = tx.InsertUser(name, username, "", email, newRole, active)
|
||||
return err
|
||||
}) {
|
||||
return
|
||||
}
|
||||
|
||||
// parse email for headers
|
||||
address, err := mail.ParseAddress(email)
|
||||
if err != nil {
|
||||
http.Error(rw, "500 Internal Server Error: Failed to parse user email address", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
n := strings.IndexByte(address.Address, '@')
|
||||
// This case should never happen and fail the above address parsing
|
||||
if n == -1 {
|
||||
return
|
||||
}
|
||||
addrDomain := address.Address[n+1:]
|
||||
|
||||
var userSub uuid.UUID
|
||||
if h.DbTx(rw, func(tx *database.Tx) (err error) {
|
||||
userSub, err = tx.InsertUser(name, username, "", email, addrDomain == h.conf.Namespace, newRole, active)
|
||||
return err
|
||||
}) {
|
||||
return
|
||||
}
|
||||
|
||||
u, u2 := uuid.New(), uuid.New()
|
||||
h.mailLinkCache.Set(mailLinkKey{mailLinkResetPassword, u}, userSub, time.Now().Add(10*time.Minute))
|
||||
h.mailLinkCache.Set(mailLinkKey{mailLinkDelete, u2}, userSub, time.Now().Add(10*time.Minute))
|
||||
|
||||
err = h.mailer.SendEmailTemplate("mail-register-delete", "Register", name, address, map[string]any{
|
||||
"ResetUrl": h.domain + "/mail/password/" + u.String(),
|
||||
"DeleteUrl": h.domain + "/mail/delete/" + u2.String(),
|
||||
err = h.conf.Mail.SendEmailTemplate("mail-register-admin", "Register", name, address, map[string]any{
|
||||
"RegisterUrl": h.conf.BaseUrl + "/mail/password/" + u.String(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Println("[Tulip] Login: Failed to send register email:", err)
|
||||
|
@ -95,7 +95,7 @@ func (h *HttpServer) authorizeEndpoint(rw http.ResponseWriter, req *http.Request
|
||||
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
pages.RenderPageTemplate(rw, "oauth-authorize", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"AppName": appName,
|
||||
"AppDomain": appDomain,
|
||||
"User": user,
|
||||
|
@ -19,7 +19,7 @@ func (h *HttpServer) LoginOtpGet(rw http.ResponseWriter, req *http.Request, _ ht
|
||||
}
|
||||
|
||||
pages.RenderPageTemplate(rw, "login-otp", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"Redirect": req.URL.Query().Get("redirect"),
|
||||
})
|
||||
}
|
||||
@ -53,7 +53,7 @@ func (h *HttpServer) fetchAndValidateOtp(rw http.ResponseWriter, sub uuid.UUID,
|
||||
return
|
||||
}
|
||||
if hasOtp {
|
||||
otp, err = tx.GetTwoFactor(sub, h.otpIssuer)
|
||||
otp, err = tx.GetTwoFactor(sub, h.conf.OtpIssuer)
|
||||
}
|
||||
return
|
||||
}) {
|
||||
@ -121,7 +121,7 @@ func (h *HttpServer) EditOtpGet(rw http.ResponseWriter, req *http.Request, _ htt
|
||||
|
||||
// generate OTP key
|
||||
var err error
|
||||
otp, err = twofactor.NewTOTP(email, h.otpIssuer, crypto.SHA512, digits)
|
||||
otp, err = twofactor.NewTOTP(email, h.conf.OtpIssuer, crypto.SHA512, digits)
|
||||
if err != nil {
|
||||
http.Error(rw, "500 Internal Server Error: Failed to generate OTP key", http.StatusInternalServerError)
|
||||
return
|
||||
@ -150,7 +150,7 @@ func (h *HttpServer) EditOtpGet(rw http.ResponseWriter, req *http.Request, _ htt
|
||||
|
||||
// render page
|
||||
pages.RenderPageTemplate(rw, "edit-otp", map[string]any{
|
||||
"ServiceName": h.serviceName,
|
||||
"ServiceName": h.conf.ServiceName,
|
||||
"OtpQr": template.URL("data:image/png;base64," + base64.StdEncoding.EncodeToString(otpQr)),
|
||||
"OtpUrl": otpUrl,
|
||||
})
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"github.com/1f349/cache"
|
||||
clientStore "github.com/1f349/tulip/client-store"
|
||||
"github.com/1f349/tulip/database"
|
||||
"github.com/1f349/tulip/mail"
|
||||
"github.com/1f349/tulip/openid"
|
||||
scope2 "github.com/1f349/tulip/scope"
|
||||
"github.com/go-oauth2/oauth2/v4/errors"
|
||||
@ -28,15 +27,12 @@ import (
|
||||
var errInvalidScope = errors.New("missing required scope")
|
||||
|
||||
type HttpServer struct {
|
||||
r *httprouter.Router
|
||||
oauthSrv *server.Server
|
||||
oauthMgr *manage.Manager
|
||||
db *database.DB
|
||||
domain string
|
||||
privKey []byte
|
||||
otpIssuer string
|
||||
serviceName string
|
||||
mailer mail.Mail
|
||||
r *httprouter.Router
|
||||
oauthSrv *server.Server
|
||||
oauthMgr *manage.Manager
|
||||
db *database.DB
|
||||
conf Conf
|
||||
privKey []byte
|
||||
|
||||
// mailLinkCache contains a mapping of verify uuids to user uuids
|
||||
mailLinkCache *cache.Cache[mailLinkKey, uuid.UUID]
|
||||
@ -71,10 +67,18 @@ func (h *HttpServer) SafeRedirect(rw http.ResponseWriter, req *http.Request) {
|
||||
http.Redirect(rw, req, parse.String(), http.StatusFound)
|
||||
}
|
||||
|
||||
func NewHttpServer(listen, domain, otpIssuer, serviceName string, mailer mail.Mail, db *database.DB, privKey []byte) *http.Server {
|
||||
func NewHttpServer(conf Conf, db *database.DB, privKey []byte) *http.Server {
|
||||
r := httprouter.New()
|
||||
|
||||
openIdConf := openid.GenConfig(domain, []string{"openid", "name", "username", "profile", "email", "birthdate", "age", "zoneinfo", "locale"}, []string{"sub", "name", "preferred_username", "profile", "picture", "website", "email", "email_verified", "gender", "birthdate", "zoneinfo", "locale", "updated_at"})
|
||||
// remove last slash from baseUrl
|
||||
{
|
||||
l := len(conf.BaseUrl)
|
||||
if conf.BaseUrl[l-1] == '/' {
|
||||
conf.BaseUrl = conf.BaseUrl[:l-1]
|
||||
}
|
||||
}
|
||||
|
||||
openIdConf := openid.GenConfig(conf.BaseUrl, []string{"openid", "name", "username", "profile", "email", "birthdate", "age", "zoneinfo", "locale"}, []string{"sub", "name", "preferred_username", "profile", "picture", "website", "email", "email_verified", "gender", "birthdate", "zoneinfo", "locale", "updated_at"})
|
||||
openIdBytes, err := json.Marshal(openIdConf)
|
||||
if err != nil {
|
||||
log.Fatalln("Failed to generate OpenID configuration:", err)
|
||||
@ -83,15 +87,12 @@ func NewHttpServer(listen, domain, otpIssuer, serviceName string, mailer mail.Ma
|
||||
oauthManager := manage.NewDefaultManager()
|
||||
oauthSrv := server.NewServer(server.NewConfig(), oauthManager)
|
||||
hs := &HttpServer{
|
||||
r: httprouter.New(),
|
||||
oauthSrv: oauthSrv,
|
||||
oauthMgr: oauthManager,
|
||||
db: db,
|
||||
domain: domain,
|
||||
privKey: privKey,
|
||||
otpIssuer: otpIssuer,
|
||||
serviceName: serviceName,
|
||||
mailer: mailer,
|
||||
r: httprouter.New(),
|
||||
oauthSrv: oauthSrv,
|
||||
oauthMgr: oauthManager,
|
||||
db: db,
|
||||
conf: conf,
|
||||
privKey: privKey,
|
||||
|
||||
mailLinkCache: cache.New[mailLinkKey, uuid.UUID](),
|
||||
}
|
||||
@ -220,10 +221,10 @@ func NewHttpServer(listen, domain, otpIssuer, serviceName string, mailer mail.Ma
|
||||
m["name"] = userData.Name
|
||||
}
|
||||
if claims["username"] {
|
||||
m["preferred_username"] = userData.Name
|
||||
m["preferred_username"] = userData.Username
|
||||
}
|
||||
if claims["profile"] {
|
||||
m["profile"] = domain + "/user/" + userData.Username
|
||||
m["profile"] = conf.BaseUrl + "/user/" + userData.Username
|
||||
m["picture"] = userData.Picture.String()
|
||||
m["website"] = userData.Website.String()
|
||||
}
|
||||
@ -249,7 +250,7 @@ func NewHttpServer(listen, domain, otpIssuer, serviceName string, mailer mail.Ma
|
||||
})
|
||||
|
||||
return &http.Server{
|
||||
Addr: listen,
|
||||
Addr: conf.Listen,
|
||||
Handler: r,
|
||||
ReadTimeout: time.Minute,
|
||||
ReadHeaderTimeout: time.Minute,
|
||||
|
Loading…
Reference in New Issue
Block a user