Adding grants record for display in authorized clients listing
4 files changed, 31 insertions(+), 15 deletions(-)

M grants.go
M models.go
M routes.go
M schema.sql
M grants.go +10 -6
@@ 19,8 19,10 @@ func GetGrants(ctx context.Context, opts
 	if err := database.WithTx(ctx, database.TxOptionsRO, func(tx *sql.Tx) error {
 		q := opts.GetBuilder(nil)
 		rows, err := q.
-			Columns("id", "issued", "expires", "comment", "token_hash", "user_id", "client_id").
-			From("oauth2_grants").
+			Columns("g.id", "g.issued", "g.expires", "g.comment", "g.grants", "g.token_hash",
+				"g.user_id", "g.client_id", "c.name").
+			From("oauth2_grants g").
+			LeftJoin("oauth2_clients c ON c.id = g.client_id").
 			PlaceholderFormat(sq.Dollar).
 			RunWith(tx).
 			QueryContext(ctx)

          
@@ 34,8 36,8 @@ func GetGrants(ctx context.Context, opts
 
 		for rows.Next() {
 			var g Grant
-			if err = rows.Scan(&g.ID, &g.Issued, &g.Expires, &g.Comment, &g.TokenHash,
-				&g.UserID, &g.ClientID); err != nil {
+			if err = rows.Scan(&g.ID, &g.Issued, &g.Expires, &g.Comment, &g.Grants, &g.TokenHash,
+				&g.UserID, &g.ClientID, &g.ClientName); err != nil {
 				return err
 			}
 			grants = append(grants, &g)

          
@@ 54,8 56,9 @@ func (g *Grant) Store(ctx context.Contex
 		if g.ID == 0 {
 			err = sq.
 				Insert("oauth2_grants").
-				Columns("issued", "expires", "comment", "token_hash", "user_id", "client_id").
-				Values(g.Issued, g.Expires, g.Comment, g.TokenHash, g.UserID, g.ClientID).
+				Columns("issued", "expires", "comment", "grants", "token_hash", "user_id",
+					"client_id").
+				Values(g.Issued, g.Expires, g.Comment, g.Grants, g.TokenHash, g.UserID, g.ClientID).
 				Suffix(`RETURNING (id)`).
 				PlaceholderFormat(sq.Dollar).
 				RunWith(tx).

          
@@ 66,6 69,7 @@ func (g *Grant) Store(ctx context.Contex
 				Set("issued", g.Issued).
 				Set("expires", g.Expires).
 				Set("comment", g.Comment).
+				Set("grants", g.Grants).
 				Set("token_hash", g.TokenHash).
 				Set("user_id", g.UserID).
 				Set("client_id", g.ClientID).

          
M models.go +3 -0
@@ 27,9 27,12 @@ type Grant struct {
 	Issued    time.Time     `db:"issued"`
 	Expires   time.Time     `db:"expires"`
 	Comment   string        `db:"comment"`
+	Grants    string        `db:"grants"`
 	TokenHash string        `db:"token_hash"`
 	UserID    int           `db:"user_id"`
 	ClientID  sql.NullInt64 `db:"client_id"`
+
+	ClientName sql.NullString `db:"-"`
 }
 
 // Authorization ...

          
M routes.go +17 -9
@@ 59,20 59,28 @@ func (s *Service) RegisterRoutes() {
 
 // ListPersonal ...
 func (s *Service) ListPersonal(c echo.Context) error {
+	var tokens, clients []*Grant
 	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'"),
+			sq.Eq{"g.user_id": gctx.User.GetID()},
+			sq.Expr("g.expires > NOW() at time zone 'UTC'"),
 		},
 	}
-	tokens, err := GetGrants(c.Request().Context(), opts)
+	grants, err := GetGrants(c.Request().Context(), opts)
 	if err != nil {
 		return err
 	}
+	for _, grant := range grants {
+		if !grant.ClientID.Valid {
+			tokens = append(tokens, grant)
+		} else {
+			clients = append(clients, grant)
+		}
+	}
 	return gctx.Render(http.StatusOK, "oauth2_personal_list.html", gobwebs.Map{
-		"tokens": tokens,
+		"tokens":  tokens,
+		"clients": clients,
 	})
 }
 

          
@@ 134,10 142,9 @@ func (s *Service) RevokePersonal(c echo.
 	gctx := c.(*server.Context)
 	opts := &database.FilterOptions{
 		Filter: sq.And{
-			sq.Eq{"id": id},
-			sq.Eq{"user_id": gctx.User.GetID()},
-			sq.Expr("client_id IS NULL"),
-			sq.Expr("expires > NOW() at time zone 'UTC'"),
+			sq.Eq{"g.id": id},
+			sq.Eq{"g.user_id": gctx.User.GetID()},
+			sq.Expr("g.expires > NOW() at time zone 'UTC'"),
 		},
 	}
 	tokens, err := GetGrants(c.Request().Context(), opts)

          
@@ 593,6 600,7 @@ func (s *Service) AccessTokenPOST(c echo
 	grant := &Grant{
 		Issued:    issued,
 		Expires:   expires,
+		Grants:    payload.Grants,
 		TokenHash: tokenHash,
 		UserID:    payload.UserID,
 		ClientID:  sql.NullInt64{Int64: int64(client.ID), Valid: true},

          
M schema.sql +1 -0
@@ 37,6 37,7 @@ CREATE TABLE oauth2_grants (
         issued TIMESTAMPTZ NOT NULL,
         expires TIMESTAMPTZ NOT NULL,
         comment character varying,
+        grants character varying,
         token_hash character varying(128) NOT NULL,
         user_id integer NOT NULL REFERENCES users (id) ON DELETE CASCADE,
         client_id integer REFERENCES oauth2_clients (id) ON DELETE CASCADE