From c9dfecc519860a239ebd2c75ede3f9f792af6a06 Mon Sep 17 00:00:00 2001 From: ston1th Date: Sun, 10 Jul 2022 15:51:31 +0200 Subject: [PATCH] first working version --- .gitignore | 1 + pkg/core/config.go | 2 +- pkg/core/types.go | 1 + pkg/db/db.go | 10 +- pkg/db/user.go | 14 +- pkg/server/context.go | 191 ++++++++++--------------- pkg/server/handler.go | 94 ++++++++---- pkg/server/helper.go | 2 + pkg/server/routes.go | 42 +++--- pkg/server/templates.go | 2 + pkg/server/templates/consent.html | 14 +- pkg/server/templates/forbidden.html | 17 +++ pkg/server/templates/login.html | 2 + pkg/server/templates/loginTotp.html | 2 + pkg/server/templates/menu.html | 10 +- pkg/server/templates/userDel.html | 2 +- pkg/server/templates/userEdit.html | 10 ++ pkg/server/templates/userNew.html | 6 + pkg/server/templates/userSessions.html | 50 +++++++ pkg/server/templates/users.html | 4 +- scripts/install_openbsd.sh | 2 +- 21 files changed, 298 insertions(+), 180 deletions(-) create mode 100644 pkg/server/templates/forbidden.html create mode 100644 pkg/server/templates/userSessions.html diff --git a/.gitignore b/.gitignore index 396bae6..42911bc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ tmp run.sh TODO.txt +consent.json diff --git a/pkg/core/config.go b/pkg/core/config.go index 270b8b6..b7b1ade 100644 --- a/pkg/core/config.go +++ b/pkg/core/config.go @@ -31,6 +31,6 @@ type Config struct { HydraAdminURL string `json:"hydra_admin_url"` Issuer string `json:"issuer"` Version string `json:"-"` - Admin bool `json:"admin,omitempty"` + AdminDisabled bool `json:"admin_disabled,omitempty"` SecureCookie bool `json:"secure_cookie,omitempty"` } diff --git a/pkg/core/types.go b/pkg/core/types.go index 19cfdf6..82f4bdf 100644 --- a/pkg/core/types.go +++ b/pkg/core/types.go @@ -9,6 +9,7 @@ type User struct { Created string Secret string Admin bool + Disabled bool Locked int } diff --git a/pkg/db/db.go b/pkg/db/db.go index 8ad0ce9..8c025aa 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -21,12 +21,11 @@ const ( type DB struct { log logr.Logger - admin bool store store.Store } func NewPlain(log logr.Logger, cfg *core.Config) (db *DB, err error) { - db = &DB{log: log, admin: cfg.Admin} + db = &DB{log: log} dbFile := filepath.Join(cfg.DataDir, storeFile) //err = godrop.Unveil(dbFile, "rwc") //if err != nil { @@ -42,7 +41,12 @@ func New(log logr.Logger, cfg *core.Config) (db *DB, err error) { return } if db.UserExists(defUser) != nil { - err = db.CreateUser(defUser, defEmail, defPassword, true) + err = db.CreateUser(defUser, defEmail, defPassword, true, cfg.AdminDisabled) + if err != nil { + return + } + } else { + err = db.AdminUpdateUser(defUser, "", true, cfg.AdminDisabled) if err != nil { return } diff --git a/pkg/db/user.go b/pkg/db/user.go index eb51d93..3a005c3 100644 --- a/pkg/db/user.go +++ b/pkg/db/user.go @@ -62,7 +62,7 @@ func (db *DB) UserExists(username string) error { return db.store.Get(userPrefix+username, nil) } -func (db *DB) CreateUser(username, email, password string, admin bool) error { +func (db *DB) CreateUser(username, email, password string, admin, disabled bool) error { username = userRe.ReplaceAllString(username, "") if err := db.UserExists(username); err == nil { return errUserExists @@ -77,18 +77,19 @@ func (db *DB) CreateUser(username, email, password string, admin bool) error { Password: string(hash), Created: strconv.Itoa(int(jwt.Now())), Admin: admin, + Disabled: disabled, }) } func (db *DB) Login(username, password string) (u *core.User, err error) { - if username == defUser && !db.admin { - err = errors.New("db: user disabled") - return - } u, err = db.GetUser(username) if err != nil { return } + if u.Disabled { + err = errors.New("db: user disabled") + return + } if u.Locked == 3 { err = errUserLocked return @@ -185,7 +186,7 @@ func (db *DB) ResetAdmin() error { return db.UpdateUserPassword(defUser, defPassword) } -func (db *DB) AdminUpdateUser(username, password string, admin bool) error { +func (db *DB) AdminUpdateUser(username, password string, admin, disabled bool) error { if username == defUser && !admin { return errors.New("user '" + defUser + "' cannot lose admin privileges") } @@ -194,6 +195,7 @@ func (db *DB) AdminUpdateUser(username, password string, admin bool) error { return err } u.Admin = admin + u.Disabled = disabled if password != "" { hash, err := bcrypt.GenerateFromPassword(validatePassword(password), bcryptCost) if err != nil { diff --git a/pkg/server/context.go b/pkg/server/context.go index 6ea5981..cebce91 100644 --- a/pkg/server/context.go +++ b/pkg/server/context.go @@ -4,7 +4,6 @@ package server import ( "context" - "encoding/json" "errors" "html/template" "net/http" @@ -87,7 +86,7 @@ type loginData struct { type consentData struct { ConsentChallenge string - Info *consentInfo + Info *client.ConsentRequest } func (c *Context) Exec() { @@ -302,155 +301,117 @@ func (c *Context) Admin() bool { return c.Token.Claims.GetBool(adminClaim) } -type respBody struct { - URL string `json:"redirect_to,omitempty"` - Error string `json:"error,omitempty"` -} - func (c *Context) ApproveLogin(user, challenge string) (rdr string, err error) { - req := c.Srv.API.AdminApi.AcceptLoginRequest(context.Background()) - req.AcceptLoginRequest(*client.NewAcceptLoginRequest(user)) - req.LoginChallenge(challenge) - _, resp, err := req.Execute() + cr, resp, err := c.Srv.API.AdminApi.AcceptLoginRequest(context.Background()). + AcceptLoginRequest(*client.NewAcceptLoginRequest(user)). + LoginChallenge(challenge). + Execute() if err != nil { return } defer resp.Body.Close() - rb := new(respBody) - err = json.NewDecoder(resp.Body).Decode(rb) - if err != nil { - return - } - if rb.Error != "" { - err = errors.New(rb.Error) - return - } - rdr = rb.URL + rdr = cr.RedirectTo return } func (c *Context) ApproveConsent(challenge string) (rdr string, err error) { - req := c.Srv.API.AdminApi.AcceptConsentRequest(context.Background()). - AcceptConsentRequest(*client.NewAcceptConsentRequest()). - ConsentChallenge(challenge) - _, resp, err := req.Execute() + ci, err := c.Consent(challenge) + if err != nil { + return + } + accept := client.NewAcceptConsentRequest() + accept.GrantScope = ci.RequestedScope + accept.GrantAccessTokenAudience = ci.RequestedAccessTokenAudience + accept.Remember = new(bool) + *accept.Remember = true + cr, resp, err := c.Srv.API.AdminApi.AcceptConsentRequest(context.Background()). + AcceptConsentRequest(*accept). + ConsentChallenge(challenge). + Execute() if err != nil { return } defer resp.Body.Close() - rb := new(respBody) - err = json.NewDecoder(resp.Body).Decode(rb) - if err != nil { - return - } - if rb.Error != "" { - err = errors.New(rb.Error) - return - } - rdr = rb.URL + rdr = cr.RedirectTo return } func (c *Context) RejectConsent(challenge string) (rdr string, err error) { - req := c.Srv.API.AdminApi.RejectConsentRequest(context.Background()). + cr, resp, err := c.Srv.API.AdminApi.RejectConsentRequest(context.Background()). RejectRequest(*client.NewRejectRequest()). - ConsentChallenge(challenge) - _, resp, err := req.Execute() + ConsentChallenge(challenge). + Execute() if err != nil { return } defer resp.Body.Close() - rb := new(respBody) - err = json.NewDecoder(resp.Body).Decode(rb) - if err != nil { - return - } - if rb.Error != "" { - err = errors.New(rb.Error) - return - } - rdr = rb.URL + rdr = cr.RedirectTo return } -func (c *Context) Consent(challenge string) (ci *consentInfo, err error) { - req := c.Srv.API.AdminApi.GetConsentRequest(context.Background()). - ConsentChallenge(challenge) - _, resp, err := req.Execute() +func (c *Context) Consent(challenge string) (cr *client.ConsentRequest, err error) { + cr, resp, err := c.Srv.API.AdminApi.GetConsentRequest(context.Background()). + ConsentChallenge(challenge). + Execute() if err != nil { return } defer resp.Body.Close() - ci = new(consentInfo) - err = json.NewDecoder(resp.Body).Decode(ci) + return +} + +type sess struct { + ID string + Time string +} + +func (c *Context) Sessions(user string) (m map[string]sess, err error) { + ss, resp, err := c.Srv.API.AdminApi.ListSubjectConsentSessions(context.Background()). + Subject(user). + Execute() if err != nil { return } - if ci.Error != "" { - err = errors.New(ci.Error) + defer resp.Body.Close() + m = make(map[string]sess) + for _, s := range ss { + name := s.ConsentRequest.Client.ClientName + if name == nil { + continue + } + n := *name + cid := s.ConsentRequest.Client.ClientId + if cid == nil { + continue + } + id := *cid + if _, ok := m[n]; !ok { + m[n] = sess{ + id, + s.HandledAt.Format(timeFmt), + } + } } return } -type consentInfo struct { - Acr string `json:"acr"` - Amr []string `json:"amr"` - Challenge string `json:"challenge"` - Error string `json:"error,omitempty"` - Client struct { - AllowedCorsOrigins []string `json:"allowed_cors_origins"` - Audience []string `json:"audience"` - BackchannelLogoutSessionRequired bool `json:"backchannel_logout_session_required"` - BackchannelLogoutURI string `json:"backchannel_logout_uri"` - ClientID string `json:"client_id"` - ClientName string `json:"client_name"` - ClientSecret string `json:"client_secret"` - ClientSecretExpiresAt int `json:"client_secret_expires_at"` - ClientURI string `json:"client_uri"` - Contacts []string `json:"contacts"` - CreatedAt time.Time `json:"created_at"` - FrontchannelLogoutSessionRequired bool `json:"frontchannel_logout_session_required"` - FrontchannelLogoutURI string `json:"frontchannel_logout_uri"` - GrantTypes []string `json:"grant_types"` - Jwks struct { - } `json:"jwks"` - JwksURI string `json:"jwks_uri"` - LogoURI string `json:"logo_uri"` - Metadata struct { - } `json:"metadata"` - Owner string `json:"owner"` - PolicyURI string `json:"policy_uri"` - PostLogoutRedirectUris []string `json:"post_logout_redirect_uris"` - RedirectUris []string `json:"redirect_uris"` - RegistrationAccessToken string `json:"registration_access_token"` - RegistrationClientURI string `json:"registration_client_uri"` - RequestObjectSigningAlg string `json:"request_object_signing_alg"` - RequestUris []string `json:"request_uris"` - ResponseTypes []string `json:"response_types"` - Scope string `json:"scope"` - SectorIdentifierURI string `json:"sector_identifier_uri"` - SubjectType string `json:"subject_type"` - TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"` - TokenEndpointAuthSigningAlg string `json:"token_endpoint_auth_signing_alg"` - TosURI string `json:"tos_uri"` - UpdatedAt time.Time `json:"updated_at"` - UserinfoSignedResponseAlg string `json:"userinfo_signed_response_alg"` - } `json:"client"` - LoginChallenge string `json:"login_challenge"` - LoginSessionID string `json:"login_session_id"` - OidcContext struct { - AcrValues []string `json:"acr_values"` - Display string `json:"display"` - IDTokenHintClaims struct { - } `json:"id_token_hint_claims"` - LoginHint string `json:"login_hint"` - UILocales []string `json:"ui_locales"` - } `json:"oidc_context"` - RequestURL string `json:"request_url"` - RequestedAccessTokenAudience []string `json:"requested_access_token_audience"` - RequestedScope []string `json:"requested_scope"` - Skip bool `json:"skip"` - Subject string `json:"subject"` +func (c *Context) RevokeSession(user, client string, all bool) (err error) { + if client == "" && !all { + return + } + req := c.Srv.API.AdminApi.RevokeConsentSessions(context.Background()). + Subject(user) + if all { + req = req.All(all) + } else { + req = req.Client(client) + } + resp, err := req.Execute() + if err != nil { + return + } + defer resp.Body.Close() + return } type ctxHandler func(*Context) diff --git a/pkg/server/handler.go b/pkg/server/handler.go index bf4054e..f963a36 100644 --- a/pkg/server/handler.go +++ b/pkg/server/handler.go @@ -106,8 +106,8 @@ func indexHandler(ctx *Context) { ctx.Redirect(login, http.StatusFound) } -func profileHandler(ctx *Context) { - ctx.Redirect(uroot+"edit/"+ctx.User(), http.StatusFound) +func sessionsHandler(ctx *Context) { + ctx.Redirect(uroot+"sessions/"+ctx.User(), http.StatusFound) } func loginHandler(ctx *Context) { @@ -123,7 +123,7 @@ func loginHandler(ctx *Context) { BodyTitle: "Login", } if ctx.LoggedOn() { - rdr := profile + rdr := sessions if data.LoginChallenge != "" { rdr, err = ctx.ApproveLogin(ctx.User(), data.LoginChallenge) if err != nil { @@ -172,7 +172,7 @@ func loginHandler(ctx *Context) { } log.Info("user logged in", "user", data.User) ctx.Login(u, remember) - rdr := profile + rdr := sessions if data.LoginChallenge != "" { rdr, err = ctx.ApproveLogin(data.User, data.LoginChallenge) if err != nil { @@ -187,7 +187,7 @@ func loginHandler(ctx *Context) { func loginTotpHandler(ctx *Context) { if ctx.LoggedOn() { - ctx.Redirect(profile, http.StatusFound) + ctx.Redirect(sessions, http.StatusFound) return } ctx.Template("loginTotpHandler") @@ -222,7 +222,7 @@ func loginTotpHandler(ctx *Context) { } log.Info("totp successful") ctx.Login(u, ctx.Remember()) - rdr := root + rdr := sessions if data.LoginChallenge != "" { rdr, err = ctx.ApproveLogin(user, data.LoginChallenge) if err != nil { @@ -239,21 +239,30 @@ func loginTotpHandler(ctx *Context) { func consentHandler(ctx *Context) { ctx.Template("consentHandler") ctx.Data = webData{ - Title: "Consent", - BodyTitle: "Consent", + Title: "Authorize", + BodyTitle: "Authorize", } var data consentData switch ctx.Method() { case "GET": data.ConsentChallenge = ctx.Query("consent_challenge") ctx.Data.Data = data - ci, err := ctx.Consent(data.ConsentChallenge) + cr, err := ctx.Consent(data.ConsentChallenge) if err != nil { ctx.log.Error(err, "error getting consent info") ctx.Error("error getting consent info") return } - data.Info = ci + if cr.GetSkip() { + rdr, err := ctx.ApproveConsent(data.ConsentChallenge) + if err != nil { + ctx.log.Error(err, "error approving consent") + ctx.Error("error approving consent") + return + } + ctx.Redirect(rdr, http.StatusFound) + } + data.Info = cr ctx.Data.Data = data ctx.Exec() case "POST": @@ -321,11 +330,8 @@ func userNewHandler(ctx *Context) { email := ctx.Form("email") password := ctx.Form("password") repeat := ctx.Form("repeat") - admin := ctx.Form("admin") - adm := false - if admin == "0" { - adm = true - } + admin := ctx.Form("admin") == "0" + disabled := ctx.Form("disabled") == "0" if user == "" || email == "" || password == "" { ctx.Error("empty user, email or password") @@ -335,11 +341,11 @@ func userNewHandler(ctx *Context) { ctx.Error("passwords do not match") return } - if err := ctx.Srv.DB.CreateUser(user, email, password, adm); err != nil { + if err := ctx.Srv.DB.CreateUser(user, email, password, admin, disabled); err != nil { ctx.Error(err) return } - ctx.log.Info("user created", "user", user, "actor", ctx.User()) + ctx.log.Info("user created", "user", user, "actor", ctx.User(), "admin", admin, "disabled", disabled) ctx.Redirect(users, http.StatusFound) } } @@ -364,25 +370,27 @@ func userEditHandler(ctx *Context) { return } user := ctx.Var("user") - log := ctx.log.WithValues("user", user, "actor", ctx.User()) + self := ctx.User() + log := ctx.log.WithValues("user", user, "actor", self) password := ctx.Form("password") repeat := ctx.Form("repeat") - admin := ctx.Form("admin") - adm := false - if admin == "0" { - adm = true - } + admin := ctx.Form("admin") == "0" + disabled := ctx.Form("disabled") == "0" if password != repeat { ctx.Error("passwords do not match") return } if ctx.Admin() { - if err := ctx.Srv.DB.AdminUpdateUser(user, password, adm); err != nil { + if err := ctx.Srv.DB.AdminUpdateUser(user, password, admin, disabled); err != nil { ctx.Error(err) return } - log.Info("user updated", "admin", adm) + log.Info("user updated", "admin", admin, "disabled", disabled) + if user == self { + logoutHandler(ctx) + return + } ctx.Redirect(users, http.StatusFound) return } @@ -461,6 +469,40 @@ func userTotpHandler(ctx *Context) { } } +func userSessionsHandler(ctx *Context) { + ctx.Template("userSessionsHandler") + ctx.Data = webData{ + Title: "Sessions", + BodyTitle: "Sessions", + } + user := ctx.Var("user") + log := ctx.log.WithValues("user", user) + switch ctx.Method() { + case "GET": + s, err := ctx.Sessions(user) + if err != nil { + log.Error(err, "error getting sessions") + ctx.Error("error getting sessions") + return + } + ctx.Data.Data = s + ctx.Exec() + case "POST": + if !ctx.CheckXsrf() { + return + } + client := ctx.Form("client") + all := ctx.Form("all") == "all" + err := ctx.RevokeSession(user, client, all) + if err != nil { + log.Error(err, "error revoking session", "client", client, "all", all) + ctx.Error("error revoking session") + return + } + sessionsHandler(ctx) + } +} + func userUnlockHandler(ctx *Context) { user := ctx.Var("user") log := ctx.log.WithValues("user", user, "actor", ctx.User()) @@ -502,7 +544,7 @@ func userDelHandler(ctx *Context) { log.Info("delete successful") } if user == self { - ctx.Redirect(logout, http.StatusFound) + logoutHandler(ctx) return } ctx.Redirect(users, http.StatusFound) diff --git a/pkg/server/helper.go b/pkg/server/helper.go index 51829eb..ac956f3 100644 --- a/pkg/server/helper.go +++ b/pkg/server/helper.go @@ -10,4 +10,6 @@ const ( day = time.Hour * 24 min = time.Second * 30 max = day * 90 + + timeFmt = "2006-01-02 15:04:05" ) diff --git a/pkg/server/routes.go b/pkg/server/routes.go index 78af794..2c5197b 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -9,20 +9,21 @@ type route struct { } const ( - root = "/" - login = root + "login" - totp = root + "totp" - profile = root + "profile" - consent = root + "consent" - users = root + "users" - logout = root + "logout" - uroot = root + "user/" + root = "/" + login = root + "login" + totp = root + "totp" + sessions = root + "sessions" + consent = root + "consent" + users = root + "users" + logout = root + "logout" + uroot = root + "user/" - userNew = uroot + "new" - userEdit = uroot + "edit/{user:[a-zA-Z0-9]+$}" - userDel = uroot + "del/{user:[a-zA-Z0-9]+$}" - userTotp = uroot + "totp/{user:[a-zA-Z0-9]+$}" - userUnlock = uroot + "unlock/{user:[a-zA-Z0-9]+$}" + userNew = uroot + "new" + userEdit = uroot + "edit/{user:[a-zA-Z0-9]+$}" + userDel = uroot + "del/{user:[a-zA-Z0-9]+$}" + userTotp = uroot + "totp/{user:[a-zA-Z0-9]+$}" + userSessions = uroot + "sessions/{user:[a-zA-Z0-9]+$}" + userUnlock = uroot + "unlock/{user:[a-zA-Z0-9]+$}" ) var routes = []route{ @@ -48,15 +49,15 @@ var routes = []route{ { consent, jwtHandler( - userAuthHandler( + authHandler( consentHandler)), []string{"GET", "POST"}, }, { - profile, + sessions, jwtHandler( - userAuthHandler( - profileHandler)), + authHandler( + sessionsHandler)), []string{"GET"}, }, { @@ -100,6 +101,13 @@ var routes = []route{ userTotpHandler)), []string{"GET", "POST"}, }, + { + userSessions, + jwtHandler( + userAuthHandler( + userSessionsHandler)), + []string{"GET", "POST"}, + }, { userUnlock, jwtHandler( diff --git a/pkg/server/templates.go b/pkg/server/templates.go index 83dcf98..fed0ee7 100644 --- a/pkg/server/templates.go +++ b/pkg/server/templates.go @@ -43,6 +43,7 @@ func (s *Server) loadTemplates() (err error) { // pages s.ts.Parse(tfs, "notFoundHandler", "index.html", "menu.html", "notFound.html") + s.ts.Parse(tfs, "forbiddenHandler", "index.html", "menu.html", "forbidden.html") s.ts.Parse(tfs, "loginHandler", "index.html", "menu.html", "login.html") s.ts.Parse(tfs, "loginTotpHandler", "index.html", "menu.html", "loginTotp.html") s.ts.Parse(tfs, "consentHandler", "index.html", "menu.html", "consent.html") @@ -51,6 +52,7 @@ func (s *Server) loadTemplates() (err error) { s.ts.Parse(tfs, "userNewHandler", "index.html", "menu.html", "userNew.html") s.ts.Parse(tfs, "userEditHandler", "index.html", "menu.html", "userEdit.html") s.ts.Parse(tfs, "userDelHandler", "index.html", "menu.html", "userDel.html") + s.ts.Parse(tfs, "userSessionsHandler", "index.html", "menu.html", "userSessions.html") // totp s.ts.Parse(tfs, "userTotpHandler", "index.html", "menu.html", "userTotp.html") diff --git a/pkg/server/templates/consent.html b/pkg/server/templates/consent.html index 9543359..a470bf0 100644 --- a/pkg/server/templates/consent.html +++ b/pkg/server/templates/consent.html @@ -1,15 +1,19 @@ {{define "body"}} {{if .Data}}
-
+
- {{.BodyTitle}} + {{.BodyTitle}} - {{.Data.Info.Client.ClientName}}
-
-{{.Data.Info}}
-
+ The client {{.Data.Info.Client.ClientName}} is requesting access to your data.
+ Requested Scopes: +
    + {{range $item := .Data.Info.RequestedScope}} +
  • {{$item}}
  • + {{end}} +
diff --git a/pkg/server/templates/forbidden.html b/pkg/server/templates/forbidden.html new file mode 100644 index 0000000..dcf22f7 --- /dev/null +++ b/pkg/server/templates/forbidden.html @@ -0,0 +1,17 @@ +{{define "body"}} + +{{end}} diff --git a/pkg/server/templates/login.html b/pkg/server/templates/login.html index 6856a89..8d58a2c 100644 --- a/pkg/server/templates/login.html +++ b/pkg/server/templates/login.html @@ -9,7 +9,9 @@
+ {{if .Data}} + {{end}}
diff --git a/pkg/server/templates/loginTotp.html b/pkg/server/templates/loginTotp.html index 84d649b..3911e60 100644 --- a/pkg/server/templates/loginTotp.html +++ b/pkg/server/templates/loginTotp.html @@ -9,7 +9,9 @@
+ {{if .Data}} + {{end}}
diff --git a/pkg/server/templates/menu.html b/pkg/server/templates/menu.html index 3cfee1d..e0fab8e 100644 --- a/pkg/server/templates/menu.html +++ b/pkg/server/templates/menu.html @@ -1,11 +1,13 @@ {{define "menu"}} +{{if .Admin}} + +{{end}}
-

You are about to delete user {{.Data.Username}}.

+

You are about to delete user {{.Data.Username}}.

diff --git a/pkg/server/templates/userEdit.html b/pkg/server/templates/userEdit.html index da32e7b..e49afe9 100644 --- a/pkg/server/templates/userEdit.html +++ b/pkg/server/templates/userEdit.html @@ -41,6 +41,16 @@
+
+
+ {{if .Data.Disabled}} + + {{else}} + + {{end}} + +
+
{{end}} {{if .Admin}} diff --git a/pkg/server/templates/userNew.html b/pkg/server/templates/userNew.html index 7a7c8f9..0ce5d4f 100644 --- a/pkg/server/templates/userNew.html +++ b/pkg/server/templates/userNew.html @@ -30,6 +30,12 @@
+
+
+ + +
+
Back
diff --git a/pkg/server/templates/userSessions.html b/pkg/server/templates/userSessions.html new file mode 100644 index 0000000..c13bd3e --- /dev/null +++ b/pkg/server/templates/userSessions.html @@ -0,0 +1,50 @@ +{{define "body"}} + +{{$user := .User}} +{{$token := .Token}} +{{if .Data}} +
+
+
+ + + +
+
+
+{{end}} +
+
+ {{if .Data}} + + + + + + + + {{range $name, $s := .Data}} + + + + + + {{end}} + +
Client NameCreatedOptions
{{$name}}{{$s.Time}} +
+ + + +
+
+ {{else}} + No active sessions found. + {{end}} +
+
+{{end}} diff --git a/pkg/server/templates/users.html b/pkg/server/templates/users.html index c18a11e..b1bf840 100644 --- a/pkg/server/templates/users.html +++ b/pkg/server/templates/users.html @@ -31,13 +31,15 @@ {{$item.Username}} {{$item.Email}} + {{if $item.Admin}}admin{{end}} {{if $item.Secret}}totp{{end}} {{if eq $item.Locked 3}}locked{{end}} - {{if $item.Admin}}admin{{end}} + {{if $item.Disabled}}disabled{{end}}
{{if $admin}} + Sessions Edit Delete {{else}} diff --git a/scripts/install_openbsd.sh b/scripts/install_openbsd.sh index 87c3059..133e55e 100755 --- a/scripts/install_openbsd.sh +++ b/scripts/install_openbsd.sh @@ -34,7 +34,7 @@ cat < /var/acc/goacc.conf "listen": "127.0.0.1:4443", "secret": "$(openssl rand -hex 32)", "hydra_admin_url": "http://127.0.0.1:4445", - "admin": true, + "admin_disabled": false, "secure_cookie": true } EOF