add /blogs/{blogID} and /blogs/lookup/{blogName} routes

This commit is contained in:
sam 2023-09-06 02:40:50 +02:00
parent dfc116d828
commit dd72a1f4c1
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
5 changed files with 104 additions and 1 deletions

View file

@ -53,6 +53,8 @@ const (
// Controls whether tokens have access to sensitive account data, NOT if they can use `/accounts/@me` endpoints. // Controls whether tokens have access to sensitive account data, NOT if they can use `/accounts/@me` endpoints.
TokenScopeAccountsMe TokenScope = "accounts.me" TokenScopeAccountsMe TokenScope = "accounts.me"
TokenScopeAccountsWrite TokenScope = "accounts.write" TokenScopeAccountsWrite TokenScope = "accounts.write"
TokenScopeBlogsRead TokenScope = "blogs.read"
TokenScopeBlogsWrite TokenScope = "blogs.write"
) )
func (s TokenScope) IsValid() bool { func (s TokenScope) IsValid() bool {

74
web/api/blogs/get_blog.go Normal file
View file

@ -0,0 +1,74 @@
package blogs
import (
"net/http"
"git.sleepycat.moe/sam/mercury/internal/database/sql"
"git.sleepycat.moe/sam/mercury/web/api"
"github.com/go-chi/chi/v5"
"github.com/oklog/ulid/v2"
"github.com/rs/zerolog/log"
)
func (app *App) GetID(w http.ResponseWriter, r *http.Request) (api.Blog, error) {
ctx := r.Context()
id, err := ulid.Parse(chi.URLParamFromCtx(ctx, "blogID"))
if err != nil {
return api.Blog{}, api.Error{Code: api.ErrBlogNotFound}
}
conn, err := app.Database.Acquire(ctx)
if err != nil {
log.Err(err).Msg("acquiring connection")
return api.Blog{}, err
}
defer conn.Release()
blog, err := app.Blog(conn).ByID(ctx, id)
if err != nil {
if err == sql.ErrNotFound {
return api.Blog{}, api.Error{Code: api.ErrBlogNotFound}
}
log.Err(err).Str("id", id.String()).Msg("fetching blog from database")
return api.Blog{}, err
}
acct, err := app.Account(conn).ByID(ctx, blog.AccountID)
if err != nil {
log.Err(err).Str("id", blog.AccountID.String()).Msg("fetching account from database")
return api.Blog{}, err
}
return api.DBBlogToBlog(blog, acct), nil
}
func (app *App) LookupName(w http.ResponseWriter, r *http.Request) (api.Blog, error) {
ctx := r.Context()
name := chi.URLParamFromCtx(ctx, "blogName")
conn, err := app.Database.Acquire(ctx)
if err != nil {
log.Err(err).Msg("acquiring connection")
return api.Blog{}, err
}
defer conn.Release()
blog, err := app.Blog(conn).ByName(ctx, name, "")
if err != nil {
if err == sql.ErrNotFound {
return api.Blog{}, api.Error{Code: api.ErrBlogNotFound}
}
log.Err(err).Str("name", name).Msg("fetching blog from database")
return api.Blog{}, err
}
acct, err := app.Account(conn).ByID(ctx, blog.AccountID)
if err != nil {
log.Err(err).Str("id", blog.AccountID.String()).Msg("fetching account from database")
return api.Blog{}, err
}
return api.DBBlogToBlog(blog, acct), nil
}

13
web/api/blogs/module.go Normal file
View file

@ -0,0 +1,13 @@
package blogs
import "git.sleepycat.moe/sam/mercury/web/app"
type App struct {
*app.App
}
func New(app *app.App) *App {
return &App{
App: app,
}
}

View file

@ -126,7 +126,10 @@ const (
ErrMissingScope = 1002 ErrMissingScope = 1002
// Account related // Account related
ErrAccountNotFound = 1003 ErrAccountNotFound = 2001
// Blog related
ErrBlogNotFound = 3001
) )
func ErrCodeMessage(code int) string { func ErrCodeMessage(code int) string {
@ -145,6 +148,8 @@ var errCodeMessages = map[int]string{
ErrMissingScope: "Token is missing required scope for this endpoint", ErrMissingScope: "Token is missing required scope for this endpoint",
ErrAccountNotFound: "Account not found", ErrAccountNotFound: "Account not found",
ErrBlogNotFound: "Blog not found",
} }
func ErrCodeStatus(code int) int { func ErrCodeStatus(code int) int {
@ -163,4 +168,6 @@ var errCodeStatuses = map[int]int{
ErrMissingScope: http.StatusForbidden, ErrMissingScope: http.StatusForbidden,
ErrAccountNotFound: http.StatusNotFound, ErrAccountNotFound: http.StatusNotFound,
ErrBlogNotFound: http.StatusNotFound,
} }

View file

@ -4,6 +4,7 @@ import (
"git.sleepycat.moe/sam/mercury/internal/database" "git.sleepycat.moe/sam/mercury/internal/database"
"git.sleepycat.moe/sam/mercury/web/api" "git.sleepycat.moe/sam/mercury/web/api"
"git.sleepycat.moe/sam/mercury/web/api/accounts" "git.sleepycat.moe/sam/mercury/web/api/accounts"
"git.sleepycat.moe/sam/mercury/web/api/blogs"
"git.sleepycat.moe/sam/mercury/web/app" "git.sleepycat.moe/sam/mercury/web/app"
"git.sleepycat.moe/sam/mercury/web/auth" "git.sleepycat.moe/sam/mercury/web/auth"
"git.sleepycat.moe/sam/mercury/web/frontend" "git.sleepycat.moe/sam/mercury/web/frontend"
@ -43,5 +44,11 @@ func Routes(app *app.App) {
Get("/accounts/{accountID}", api.WrapHandlerT(accounts.GetID)) Get("/accounts/{accountID}", api.WrapHandlerT(accounts.GetID))
r.With(app.APIAuth(database.TokenScopeAccountsMe, false)). r.With(app.APIAuth(database.TokenScopeAccountsMe, false)).
Get("/accounts/@me", api.WrapHandlerT(accounts.GetMe)) Get("/accounts/@me", api.WrapHandlerT(accounts.GetMe))
blogs := blogs.New(app)
r.With(app.APIAuth(database.TokenScopeBlogsRead, true)).
Get("/blogs/{blogID}", api.WrapHandlerT(blogs.GetID))
r.With(app.APIAuth(database.TokenScopeBlogsRead, true)).
Get("/blogs/lookup/{blogName}", api.WrapHandlerT(blogs.LookupName))
}) })
} }