@@ 1,12 1,27 @@
package oauth2
import (
- "fmt"
-
"github.com/labstack/echo/v4"
"hg.code.netlandish.com/~netlandish/gobwebs/validate"
)
+type AddPersonalTokenForm struct {
+ Comment string `form:"comment" validate:"-"`
+}
+
+func (a *AddPersonalTokenForm) Validate(c echo.Context) error {
+ // Binding each field specifically to use BindErrors
+ errs := validate.FormFieldBinder(c, a).
+ FailFast(false).
+ String("comment", &a.Comment).
+ BindErrors()
+ if errs != nil {
+ return validate.GetInputErrors(errs)
+ }
+
+ return c.Validate(a)
+}
+
type AddClientForm struct {
Name string `form:"name" validate:"required"`
Description string `form:"description" validate:"-"`
@@ 27,9 42,5 @@ func (a *AddClientForm) Validate(c echo.
return validate.GetInputErrors(errs)
}
- if err := c.Validate(a); err != nil {
- return err
- }
- fmt.Println("foo")
- return nil
+ return c.Validate(a)
}
@@ 1,6 1,9 @@
package oauth2
-import "time"
+import (
+ "database/sql"
+ "time"
+)
// Client ...
type Client struct {
@@ 20,11 23,11 @@ type Client struct {
// Grant ...
type Grant struct {
- ID int `db:"id"`
- Issued time.Time `db:"issued"`
- Expires time.Time `db:"expires"`
- Comment time.Time `db:"comment"`
- TokenHash string `db:"token_hash"`
- UserID int `db:"user_id"`
- ClientID int `db:"client_id"`
+ ID int `db:"id"`
+ Issued time.Time `db:"issued"`
+ Expires time.Time `db:"expires"`
+ Comment string `db:"comment"`
+ TokenHash string `db:"token_hash"`
+ UserID int `db:"user_id"`
+ ClientID sql.NullInt64 `db:"client_id"`
}
@@ 1,8 1,11 @@
package oauth2
import (
+ "crypto/sha512"
+ "encoding/hex"
"fmt"
"net/http"
+ "time"
sq "github.com/Masterminds/squirrel"
"github.com/labstack/echo/v4"
@@ 24,11 27,81 @@ func (s *Service) RegisterRoutes() {
s.eg.POST("/introspect", s.Introspect).Name = s.RouteName("introspect_post")
s.eg.Use(auth.AuthRequired())
+ s.eg.GET("/personal", s.ListPersonal).Name = s.RouteName("list_personal")
+ s.eg.GET("/personal/add", s.AddPersonal).Name = s.RouteName("add_personal")
+ s.eg.POST("/personal/add", s.AddPersonal).Name = s.RouteName("add_personal_post")
s.eg.GET("/clients", s.ListClients).Name = s.RouteName("list_clients")
s.eg.GET("/clients/add", s.AddClient).Name = s.RouteName("add_client")
s.eg.POST("/clients/add", s.AddClient).Name = s.RouteName("add_client_post")
}
+// ListPersonal ...
+func (s *Service) ListPersonal(c echo.Context) error {
+ gctx := c.(*server.Context)
+ opts := &database.FilterOptions{
+ Filter: sq.And{
+ sq.Eq{"user_id": gctx.User.GetID()},
+ sq.Expr("client_id IS NULL"),
+ sq.Expr("expires > NOW() at time zone 'UTC'"),
+ },
+ }
+ tokens, err := GetGrants(c.Request().Context(), opts)
+ if err != nil {
+ return err
+ }
+ return gctx.Render(http.StatusOK, "oauth2_personal_list.html", gobwebs.Map{
+ "tokens": tokens,
+ })
+}
+
+// AddPersonal ...
+func (s *Service) AddPersonal(c echo.Context) error {
+ gctx := c.(*server.Context)
+ form := &AddPersonalTokenForm{}
+ gmap := gobwebs.Map{
+ "form": form,
+ }
+
+ req := c.Request()
+ if req.Method == "POST" {
+ if err := form.Validate(c); err != nil {
+ gmap["errors"] = err
+ return gctx.Render(http.StatusOK, "oauth2_add_personal.html", gmap)
+ }
+
+ issued := time.Now().UTC()
+ expires := issued.Add(366 * 24 * time.Hour)
+
+ grant := BearerToken{
+ Version: TokenVersion,
+ Issued: ToTimestamp(issued),
+ Expires: ToTimestamp(expires),
+ Grants: "",
+ UserID: int(gctx.User.GetID()),
+ ClientID: "",
+ }
+ token := grant.Encode(c.Request().Context())
+ hash := sha512.Sum512([]byte(token))
+ tokenHash := hex.EncodeToString(hash[:])
+
+ dbgrant := &Grant{
+ Issued: issued,
+ Expires: expires,
+ Comment: form.Comment,
+ TokenHash: tokenHash,
+ UserID: int(gctx.User.GetID()),
+ }
+
+ if err := dbgrant.Store(c.Request().Context()); err != nil {
+ return err
+ }
+ gmap["token"] = token
+ return gctx.Render(http.StatusOK, "oauth2_add_personal_done.html", gmap)
+ }
+
+ return gctx.Render(http.StatusOK, "oauth2_add_personal.html", gmap)
+}
+
// ListClients ...
func (s *Service) ListClients(c echo.Context) error {
gctx := c.(*server.Context)
@@ 44,7 117,7 @@ func (s *Service) ListClients(c echo.Con
})
}
-// AddClient
+// AddClient ...
func (s *Service) AddClient(c echo.Context) error {
gctx := c.(*server.Context)
form := &AddClientForm{}