[server] Extract common api functionality, bootstrap response with login

This commit is contained in:
Abhishek Shroff
2025-05-28 01:06:38 +05:30
parent 8470282a7c
commit 69cf9d1382
5 changed files with 131 additions and 117 deletions
+10 -21
View File
@@ -5,6 +5,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/shroff/phylum/server/internal/api/authenticator"
"github.com/shroff/phylum/server/internal/api/v1/my"
"github.com/shroff/phylum/server/internal/api/v1/responses"
"github.com/shroff/phylum/server/internal/core/errors"
"github.com/shroff/phylum/server/internal/core/user"
@@ -26,11 +27,6 @@ type resetPasswordParams struct {
Password string `json:"password" form:"password" binding:"required"`
}
type loginResponse struct {
AccessToken string `json:"access_token"`
User responses.LoggedInUser `json:"user"`
}
func SetupRoutes(r *gin.RouterGroup) {
group := r.Group("/auth")
group.POST("/password", handlePasswordAuth)
@@ -49,24 +45,17 @@ func handlePasswordAuth(c *gin.Context) {
userManager := user.ManagerFromContext(c.Request.Context())
if user, err := userManager.VerifyUserPassword(params.Email, params.Password); err != nil {
panic(err)
} else if token, err := userManager.CreateAccessToken(user); err != nil {
panic(err)
} else if bootstrap, err := my.Bootstrap(c.Request.Context(), user, 0); err != nil {
panic(err)
} else {
if token, err := userManager.CreateAccessToken(user); err != nil {
panic(err)
} else {
c.JSON(200, loginResponse{
AccessToken: token,
User: responses.LoggedInUser{
User: responses.User{
ID: user.ID,
Email: user.Email,
Name: user.Name,
},
Home: user.Home,
Permissions: user.Permissions,
},
})
}
c.JSON(200, responses.Login{
AccessToken: token,
Bootstrap: bootstrap,
})
}
}
func handleRequestPasswordReset(c *gin.Context) {
+42 -26
View File
@@ -1,24 +1,22 @@
package my
import (
"context"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/shroff/phylum/server/internal/api/authenticator"
"github.com/shroff/phylum/server/internal/api/v1/responses"
"github.com/shroff/phylum/server/internal/core/errors"
"github.com/shroff/phylum/server/internal/core/user"
)
type bookmarksResponse struct {
Bookmarks []Bookmark `json:"bookmarks"`
Until int64 `json:"until"`
}
type Bookmark struct {
ResourceID uuid.UUID `json:"resource_id"`
Name string `json:"name"`
Dir bool `json:"dir"`
Created int64 `json:"created"`
Bookmarks []responses.Bookmark `json:"bookmarks"`
Until int64 `json:"until"`
}
type bookmarkAddParams struct {
@@ -38,24 +36,24 @@ func setupBookmarksRoutes(r *gin.RouterGroup) {
}
func handleBookmarksGetRoute(c *gin.Context) {
u := authenticator.GetUser(c)
res, err := user.ManagerFromContext(c.Request.Context()).ListBookmarks(u, 0)
if err != nil {
panic(err)
}
bookmarks := make([]Bookmark, len(res))
for i, b := range res {
bookmarks[i] = Bookmark{
ResourceID: b.ResourceID,
Name: b.Name,
Dir: b.Dir,
Created: b.Created.UnixMilli(),
var since int64
if s := c.Request.URL.Query().Get("since"); s != "" {
var err error
since, err = strconv.ParseInt(s, 10, 64)
if err != nil {
panic(errors.NewError(http.StatusBadRequest, "invalid_parameters", "Invalid Parameters"))
}
}
c.JSON(200, bookmarksResponse{
Bookmarks: bookmarks,
Until: time.Now().UnixMilli() - 100,
})
u := authenticator.GetUser(c)
if bookmarks, err := ListBookmarks(c.Request.Context(), u, since); err != nil {
panic(err)
} else {
c.JSON(200, bookmarksResponse{
Bookmarks: bookmarks,
Until: time.Now().UnixMilli() - 100,
})
}
}
func handleBookmarksAddRoute(c *gin.Context) {
@@ -72,7 +70,7 @@ func handleBookmarksAddRoute(c *gin.Context) {
panic(err)
}
c.JSON(200,
Bookmark{
responses.Bookmark{
ResourceID: b.ResourceID,
Name: b.Name,
Dir: b.Dir,
@@ -91,3 +89,21 @@ func handleBookmarksRemoveRoute(c *gin.Context) {
}
c.JSON(200, gin.H{})
}
func ListBookmarks(ctx context.Context, u user.User, since int64) ([]responses.Bookmark, error) {
var bookmarks []responses.Bookmark
if res, err := user.ManagerFromContext(ctx).ListBookmarks(u, since); err != nil {
return bookmarks, err
} else {
bookmarks = make([]responses.Bookmark, len(res))
for i, b := range res {
bookmarks[i] = responses.Bookmark{
ResourceID: b.ResourceID,
Name: b.Name,
Dir: b.Dir,
Created: b.Created.UnixMilli(),
}
}
return bookmarks, nil
}
}
+31 -53
View File
@@ -1,6 +1,7 @@
package my
import (
"context"
"net/http"
"strconv"
"time"
@@ -8,71 +9,48 @@ import (
"github.com/gin-gonic/gin"
"github.com/shroff/phylum/server/internal/api/authenticator"
"github.com/shroff/phylum/server/internal/api/v1/responses"
"github.com/shroff/phylum/server/internal/api/v1/users"
"github.com/shroff/phylum/server/internal/core/errors"
"github.com/shroff/phylum/server/internal/core/user"
)
type bootstrapResponse struct {
User responses.LoggedInUser `json:"user"`
Bookmarks []Bookmark `json:"bookmarks"`
Users []responses.User `json:"users"`
Until int `json:"until"`
}
func handleBootstrapRoute(c *gin.Context) {
var since int
if sinceStr := c.Request.URL.Query().Get("since"); sinceStr != "" {
var since int64
if s := c.Request.URL.Query().Get("since"); s != "" {
var err error
since, err = strconv.Atoi(sinceStr)
since, err = strconv.ParseInt(s, 10, 64)
if err != nil {
panic(errors.NewError(http.StatusBadRequest, "invalid_parameters", "Invalid Parameters"))
}
}
u := authenticator.GetUser(c)
var bookmarks []Bookmark
var users []responses.User
if res, err := user.ManagerFromContext(c.Request.Context()).ListBookmarks(u, int64(since)); err != nil {
if response, err := Bootstrap(c.Request.Context(), authenticator.GetUser(c), since); err != nil {
panic(err)
} else {
bookmarks = make([]Bookmark, len(res))
for i, b := range res {
bookmarks[i] = Bookmark{
ResourceID: b.ResourceID,
Name: b.Name,
Dir: b.Dir,
Created: b.Created.UnixMilli(),
}
}
c.JSON(200, response)
}
if res, err := user.ManagerFromContext(c.Request.Context()).ListUsers(int64(since)); err != nil {
panic(err)
} else {
users = make([]responses.User, len(res))
for i, u := range res {
users[i] = responses.User{
ID: u.ID,
Email: u.Email,
Name: u.Name,
}
}
}
response := bootstrapResponse{
User: responses.LoggedInUser{
User: responses.User{
ID: u.ID,
Email: u.Email,
Name: u.Name,
},
Home: u.Home,
Permissions: u.Permissions,
},
Bookmarks: bookmarks,
Users: users,
Until: int(time.Now().UnixMilli()) - 100,
}
c.JSON(200, response)
}
func Bootstrap(ctx context.Context, u user.User, since int64) (responses.Bootstrap, error) {
if bookmarks, err := ListBookmarks(ctx, u, since); err != nil {
return responses.Bootstrap{}, err
} else if users, err := users.ListUsers(ctx, since); err != nil {
return responses.Bootstrap{}, err
} else {
return responses.Bootstrap{
User: responses.LoggedInUser{
User: responses.User{
ID: u.ID,
Email: u.Email,
Name: u.Name,
},
Home: u.Home,
Permissions: u.Permissions,
},
Bookmarks: bookmarks,
Users: users,
Until: int(time.Now().UnixMilli()) - 100,
}, nil
}
}
@@ -58,3 +58,22 @@ type Publink struct {
Protected bool `json:"protected"`
Expires int64 `json:"expires"`
}
type Login struct {
AccessToken string `json:"access_token"`
Bootstrap
}
type Bookmark struct {
ResourceID uuid.UUID `json:"resource_id"`
Name string `json:"name"`
Dir bool `json:"dir"`
Created int64 `json:"created"`
}
type Bootstrap struct {
User LoggedInUser `json:"user"`
Bookmarks []Bookmark `json:"bookmarks"`
Users []User `json:"users"`
Until int `json:"until"`
}
+29 -17
View File
@@ -1,10 +1,13 @@
package users
import (
"context"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/shroff/phylum/server/internal/api/v1/responses"
"github.com/shroff/phylum/server/internal/core/errors"
"github.com/shroff/phylum/server/internal/core/user"
)
@@ -16,28 +19,37 @@ func SetupUserRoutes(r *gin.RouterGroup) {
func handleUsersListRoute(c *gin.Context) {
var since int64
sinceStr := c.Query("since")
if sinceStr != "" {
if s := c.Request.URL.Query().Get("since"); s != "" {
var err error
since, err = strconv.ParseInt(sinceStr, 10, 64)
since, err = strconv.ParseInt(s, 10, 64)
if err != nil {
panic(err)
}
}
users, err := user.ManagerFromContext(c.Request.Context()).ListUsers(since)
if err != nil {
panic(err)
}
result := make([]responses.User, len(users))
for i, u := range users {
result[i] = responses.User{
ID: u.ID,
Email: u.Email,
Name: u.Name,
panic(errors.NewError(http.StatusBadRequest, "invalid_parameters", "Invalid Parameters"))
}
}
users, err := ListUsers(c.Request.Context(), since)
if err != nil {
panic(err)
}
c.JSON(200, gin.H{
"users": result,
"users": users,
})
}
func ListUsers(ctx context.Context, since int64) ([]responses.User, error) {
var users []responses.User
if res, err := user.ManagerFromContext(ctx).ListUsers(since); err != nil {
return users, err
} else {
users = make([]responses.User, len(res))
for i, u := range res {
users[i] = responses.User{
ID: u.ID,
Email: u.Email,
Name: u.Name,
}
}
return users, nil
}
}