Fixed site ownership
This commit is contained in:
parent
cb54057305
commit
50f7e9632e
|
@ -12,7 +12,7 @@ exclude_file = []
|
||||||
exclude_regex = ["_test.go", "build/.*"]
|
exclude_regex = ["_test.go", "build/.*"]
|
||||||
exclude_unchanged = false
|
exclude_unchanged = false
|
||||||
follow_symlink = false
|
follow_symlink = false
|
||||||
full_bin = "export $(cat .env | xargs) ; cd build ; ./hugo-cms"
|
full_bin = "export $(cat .env | xargs) ; make init-db ; cd build ; ./hugo-cms"
|
||||||
include_dir = []
|
include_dir = []
|
||||||
include_ext = ["go", "tpl", "tmpl", "html", "gohtml", "css", "js"]
|
include_ext = ["go", "tpl", "tmpl", "html", "gohtml", "css", "js"]
|
||||||
include_file = []
|
include_file = []
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -1,7 +1,7 @@
|
||||||
.Phony: clean
|
.Phony: clean
|
||||||
clean:
|
clean:
|
||||||
-docker-compose down -v
|
-docker-compose down -v
|
||||||
-rm -r build
|
-rm -rf build
|
||||||
|
|
||||||
.Phony: prep
|
.Phony: prep
|
||||||
prep:
|
prep:
|
||||||
|
@ -14,5 +14,4 @@ compile: prep
|
||||||
|
|
||||||
.Phony: init-db
|
.Phony: init-db
|
||||||
init-db:
|
init-db:
|
||||||
export $(cat .env | xargs)
|
go run . -user test@example.com -password test123
|
||||||
./build/hugo-cms -user test@example.com -password test123
|
|
|
@ -160,7 +160,6 @@ type Site struct {
|
||||||
OwnerUserID int64
|
OwnerUserID int64
|
||||||
Name string
|
Name string
|
||||||
Title string
|
Title string
|
||||||
Url string
|
|
||||||
Theme string
|
Theme string
|
||||||
Props []byte
|
Props []byte
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const getSiteWithID = `-- name: GetSiteWithID :one
|
const getSiteWithID = `-- name: GetSiteWithID :one
|
||||||
SELECT id, owner_user_id, name, title, url, theme, props FROM sites WHERE id = $1 LIMIT 1
|
SELECT id, owner_user_id, name, title, theme, props FROM sites WHERE id = $1 LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetSiteWithID(ctx context.Context, id int64) (Site, error) {
|
func (q *Queries) GetSiteWithID(ctx context.Context, id int64) (Site, error) {
|
||||||
|
@ -21,7 +21,6 @@ func (q *Queries) GetSiteWithID(ctx context.Context, id int64) (Site, error) {
|
||||||
&i.OwnerUserID,
|
&i.OwnerUserID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.Title,
|
&i.Title,
|
||||||
&i.Url,
|
|
||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.Props,
|
&i.Props,
|
||||||
)
|
)
|
||||||
|
@ -29,7 +28,7 @@ func (q *Queries) GetSiteWithID(ctx context.Context, id int64) (Site, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const listSites = `-- name: ListSites :one
|
const listSites = `-- name: ListSites :one
|
||||||
SELECT id, owner_user_id, name, title, url, theme, props FROM sites
|
SELECT id, owner_user_id, name, title, theme, props FROM sites
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) ListSites(ctx context.Context) (Site, error) {
|
func (q *Queries) ListSites(ctx context.Context) (Site, error) {
|
||||||
|
@ -40,7 +39,6 @@ func (q *Queries) ListSites(ctx context.Context) (Site, error) {
|
||||||
&i.OwnerUserID,
|
&i.OwnerUserID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.Title,
|
&i.Title,
|
||||||
&i.Url,
|
|
||||||
&i.Theme,
|
&i.Theme,
|
||||||
&i.Props,
|
&i.Props,
|
||||||
)
|
)
|
||||||
|
@ -52,10 +50,9 @@ INSERT INTO sites (
|
||||||
name,
|
name,
|
||||||
owner_user_id,
|
owner_user_id,
|
||||||
title,
|
title,
|
||||||
url,
|
|
||||||
theme,
|
theme,
|
||||||
props
|
props
|
||||||
) VALUES ($1, $2, $3, $4, $5, $6)
|
) VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -63,7 +60,6 @@ type NewSiteParams struct {
|
||||||
Name string
|
Name string
|
||||||
OwnerUserID int64
|
OwnerUserID int64
|
||||||
Title string
|
Title string
|
||||||
Url string
|
|
||||||
Theme string
|
Theme string
|
||||||
Props []byte
|
Props []byte
|
||||||
}
|
}
|
||||||
|
@ -73,7 +69,6 @@ func (q *Queries) NewSite(ctx context.Context, arg NewSiteParams) (int64, error)
|
||||||
arg.Name,
|
arg.Name,
|
||||||
arg.OwnerUserID,
|
arg.OwnerUserID,
|
||||||
arg.Title,
|
arg.Title,
|
||||||
arg.Url,
|
|
||||||
arg.Theme,
|
arg.Theme,
|
||||||
arg.Props,
|
arg.Props,
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,6 +9,29 @@ import (
|
||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getTargetOfSiteRole = `-- name: GetTargetOfSiteRole :one
|
||||||
|
SELECT id, site_id, role, target_type, url, target_ref FROM publish_targets WHERE site_id = $1 AND role = $2 LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetTargetOfSiteRoleParams struct {
|
||||||
|
SiteID int64
|
||||||
|
Role TargetRole
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetTargetOfSiteRole(ctx context.Context, arg GetTargetOfSiteRoleParams) (PublishTarget, error) {
|
||||||
|
row := q.db.QueryRow(ctx, getTargetOfSiteRole, arg.SiteID, arg.Role)
|
||||||
|
var i PublishTarget
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.SiteID,
|
||||||
|
&i.Role,
|
||||||
|
&i.TargetType,
|
||||||
|
&i.Url,
|
||||||
|
&i.TargetRef,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
const insertPublishTarget = `-- name: InsertPublishTarget :one
|
const insertPublishTarget = `-- name: InsertPublishTarget :one
|
||||||
INSERT INTO publish_targets (
|
INSERT INTO publish_targets (
|
||||||
site_id,
|
site_id,
|
||||||
|
@ -41,12 +64,12 @@ func (q *Queries) InsertPublishTarget(ctx context.Context, arg InsertPublishTarg
|
||||||
return id, err
|
return id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const listPublishTargetsOfRole = `-- name: ListPublishTargetsOfRole :many
|
const listTargetsOfSite = `-- name: ListTargetsOfSite :many
|
||||||
SELECT id, site_id, role, target_type, url, target_ref FROM publish_targets WHERE site_id = $1 AND role = 'production'
|
SELECT id, site_id, role, target_type, url, target_ref FROM publish_targets WHERE site_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) ListPublishTargetsOfRole(ctx context.Context, siteID int64) ([]PublishTarget, error) {
|
func (q *Queries) ListTargetsOfSite(ctx context.Context, siteID int64) ([]PublishTarget, error) {
|
||||||
rows, err := q.db.Query(ctx, listPublishTargetsOfRole, siteID)
|
rows, err := q.db.Query(ctx, listTargetsOfSite, siteID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"lmika.dev/lmika/hugo-cms/models"
|
"lmika.dev/lmika/hugo-cms/models"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetUser(c *fiber.Ctx) models.User {
|
func GetUser(c *fiber.Ctx) models.User {
|
||||||
|
@ -21,3 +23,35 @@ func GetSite(c *fiber.Ctx) models.Site {
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdatePrefCookie(c *fiber.Ctx, update func(prefs *models.PrefCookie)) {
|
||||||
|
cookie := GetPrefCookie(c)
|
||||||
|
update(&cookie)
|
||||||
|
setPrefCookie(c, cookie)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPrefCookie(c *fiber.Ctx) models.PrefCookie {
|
||||||
|
prefCookieValue := c.Cookies(models.PrefCookieName)
|
||||||
|
if prefCookieValue == "" {
|
||||||
|
return models.PrefCookie{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var prefCookie models.PrefCookie
|
||||||
|
err := json.Unmarshal([]byte(prefCookieValue), &prefCookie)
|
||||||
|
if err != nil {
|
||||||
|
return models.PrefCookie{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefCookie
|
||||||
|
}
|
||||||
|
|
||||||
|
func setPrefCookie(c *fiber.Ctx, prefCookie models.PrefCookie) {
|
||||||
|
if prefJson, err := json.Marshal(prefCookie); err == nil {
|
||||||
|
c.Cookie(&fiber.Cookie{
|
||||||
|
Name: models.PrefCookieName,
|
||||||
|
Value: string(prefJson),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log.Printf("unable to save pref cookie: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
19
handlers/index.go
Normal file
19
handlers/index.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexHandler struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h IndexHandler) Index(c *fiber.Ctx) error {
|
||||||
|
prefs := GetPrefCookie(c)
|
||||||
|
if prefs.SiteID > 0 {
|
||||||
|
return c.Redirect(fmt.Sprintf("/sites/%v/posts", prefs.SiteID), http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Render("index", fiber.Map{}, "layouts/main")
|
||||||
|
}
|
|
@ -1,9 +1,13 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
"lmika.dev/lmika/hugo-cms/models"
|
||||||
"lmika.dev/lmika/hugo-cms/services/sites"
|
"lmika.dev/lmika/hugo-cms/services/sites"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,6 +23,10 @@ func (s *Site) Create(c *fiber.Ctx) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdatePrefCookie(c, func(prefs *models.PrefCookie) {
|
||||||
|
prefs.SiteID = site.ID
|
||||||
|
})
|
||||||
|
|
||||||
return c.Redirect(fmt.Sprintf("/sites/%v/posts", site.ID))
|
return c.Redirect(fmt.Sprintf("/sites/%v/posts", site.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +55,7 @@ func (s *Site) Rebuild(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) WithSite() fiber.Handler {
|
func (s *Site) WithSite() fiber.Handler {
|
||||||
return func(c *fiber.Ctx) error {
|
return func(c *fiber.Ctx) (err error) {
|
||||||
id, err := c.ParamsInt("siteId")
|
id, err := c.ParamsInt("siteId")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -58,7 +66,19 @@ func (s *Site) WithSite() fiber.Handler {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user := GetUser(c)
|
||||||
|
if site.OwnerUserID != user.ID {
|
||||||
|
return c.Status(http.StatusForbidden).SendString("not permitted")
|
||||||
|
}
|
||||||
|
|
||||||
c.Locals("site", site)
|
c.Locals("site", site)
|
||||||
|
|
||||||
|
if prodTarget, err := s.Site.GetProdTargetOfSite(c.UserContext(), int(site.ID)); err == nil {
|
||||||
|
c.Locals("prodTarget", prodTarget)
|
||||||
|
} else if !errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
main.go
5
main.go
|
@ -78,6 +78,7 @@ func main() {
|
||||||
siteService := sites.NewService(cfg, dbp, themesProvider, siteBuilderService, jobService)
|
siteService := sites.NewService(cfg, dbp, themesProvider, siteBuilderService, jobService)
|
||||||
postService := posts.New(dbp, siteBuilderService, jobService)
|
postService := posts.New(dbp, siteBuilderService, jobService)
|
||||||
|
|
||||||
|
indexHandlers := handlers.IndexHandler{}
|
||||||
siteHandlers := handlers.Site{Site: siteService}
|
siteHandlers := handlers.Site{Site: siteService}
|
||||||
postHandlers := handlers.Post{Post: postService}
|
postHandlers := handlers.Post{Post: postService}
|
||||||
authHandlers := handlers.AuthHandler{UserService: userService}
|
authHandlers := handlers.AuthHandler{UserService: userService}
|
||||||
|
@ -115,9 +116,7 @@ func main() {
|
||||||
app.Post("/auth/login", authHandlers.Login)
|
app.Post("/auth/login", authHandlers.Login)
|
||||||
app.Use(authHandlers.RequireAuth)
|
app.Use(authHandlers.RequireAuth)
|
||||||
|
|
||||||
app.Get("/", func(c *fiber.Ctx) error {
|
app.Get("/", indexHandlers.Index)
|
||||||
return c.Render("index", fiber.Map{}, "layouts/main")
|
|
||||||
})
|
|
||||||
app.Post("/sites", siteHandlers.Create)
|
app.Post("/sites", siteHandlers.Create)
|
||||||
app.Get("/sites/:siteId", siteHandlers.Show)
|
app.Get("/sites/:siteId", siteHandlers.Show)
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,13 @@ package models
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AuthCookieName = "hugocrm_auth"
|
AuthCookieName = "hugocrm_auth"
|
||||||
|
PrefCookieName = "hugocrm_pref"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthCookie struct {
|
type AuthCookie struct {
|
||||||
UserID int64 `json:"uid"`
|
UserID int64 `json:"uid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PrefCookie struct {
|
||||||
|
SiteID int64 `json:"siteId"`
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,5 @@ type Site struct {
|
||||||
OwnerUserID int64
|
OwnerUserID int64
|
||||||
Name string
|
Name string
|
||||||
Title string
|
Title string
|
||||||
URL string
|
|
||||||
Theme string
|
Theme string
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
package db
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"lmika.dev/lmika/hugo-cms/gen/sqlc/dbq"
|
|
||||||
"lmika.dev/lmika/hugo-cms/models"
|
|
||||||
"lmika.dev/pkg/modash/moslice"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (db *DB) InsertPublishTarget(ctx context.Context, target *models.PublishTarget) error {
|
|
||||||
id, err := db.q.InsertPublishTarget(ctx, dbq.InsertPublishTargetParams{
|
|
||||||
SiteID: target.SiteID,
|
|
||||||
Role: dbq.TargetRole(target.Role),
|
|
||||||
TargetType: dbq.TargetType(target.Type),
|
|
||||||
Url: target.URL,
|
|
||||||
TargetRef: target.TargetRef,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
target.ID = id
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) GetPublishTargets(ctx context.Context, siteID int64) ([]models.PublishTarget, error) {
|
|
||||||
res, err := db.q.ListPublishTargetsOfRole(ctx, siteID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return moslice.Map(res, func(m dbq.PublishTarget) models.PublishTarget {
|
|
||||||
return models.PublishTarget{
|
|
||||||
ID: m.ID,
|
|
||||||
SiteID: m.SiteID,
|
|
||||||
Role: models.TargetRole(m.Role),
|
|
||||||
Type: models.TargetType(m.TargetType),
|
|
||||||
URL: m.Url,
|
|
||||||
TargetRef: m.TargetRef,
|
|
||||||
}
|
|
||||||
}), nil
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ func (db *DB) InsertSite(ctx context.Context, site *models.Site) error {
|
||||||
Name: site.Name,
|
Name: site.Name,
|
||||||
Title: site.Title,
|
Title: site.Title,
|
||||||
OwnerUserID: site.OwnerUserID,
|
OwnerUserID: site.OwnerUserID,
|
||||||
Url: site.URL,
|
|
||||||
Theme: site.Theme,
|
Theme: site.Theme,
|
||||||
Props: []byte("{}"),
|
Props: []byte("{}"),
|
||||||
})
|
})
|
||||||
|
@ -29,10 +28,10 @@ func (db *DB) GetSite(ctx context.Context, id int64) (models.Site, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return models.Site{
|
return models.Site{
|
||||||
ID: site.ID,
|
ID: site.ID,
|
||||||
Name: site.Name,
|
OwnerUserID: site.OwnerUserID,
|
||||||
Title: site.Title,
|
Name: site.Name,
|
||||||
URL: site.Url,
|
Title: site.Title,
|
||||||
Theme: site.Theme,
|
Theme: site.Theme,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
56
providers/db/targets.go
Normal file
56
providers/db/targets.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"lmika.dev/lmika/hugo-cms/gen/sqlc/dbq"
|
||||||
|
"lmika.dev/lmika/hugo-cms/models"
|
||||||
|
"lmika.dev/pkg/modash/moslice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (db *DB) InsertPublishTarget(ctx context.Context, target *models.PublishTarget) error {
|
||||||
|
id, err := db.q.InsertPublishTarget(ctx, dbq.InsertPublishTargetParams{
|
||||||
|
SiteID: target.SiteID,
|
||||||
|
Role: dbq.TargetRole(target.Role),
|
||||||
|
TargetType: dbq.TargetType(target.Type),
|
||||||
|
Url: target.URL,
|
||||||
|
TargetRef: target.TargetRef,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
target.ID = id
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) GetPublishTargets(ctx context.Context, siteID int64) ([]models.PublishTarget, error) {
|
||||||
|
res, err := db.q.ListTargetsOfSite(ctx, siteID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return moslice.Map(res, dbTargetToTarget), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) GetPublishTargetBySiteRole(ctx context.Context, siteID int64, role models.TargetRole) (models.PublishTarget, error) {
|
||||||
|
target, err := db.q.GetTargetOfSiteRole(ctx, dbq.GetTargetOfSiteRoleParams{
|
||||||
|
SiteID: siteID,
|
||||||
|
Role: dbq.TargetRole(role),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return models.PublishTarget{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbTargetToTarget(target), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbTargetToTarget(m dbq.PublishTarget) models.PublishTarget {
|
||||||
|
return models.PublishTarget{
|
||||||
|
ID: m.ID,
|
||||||
|
SiteID: m.SiteID,
|
||||||
|
Role: models.TargetRole(m.Role),
|
||||||
|
Type: models.TargetType(m.TargetType),
|
||||||
|
URL: m.Url,
|
||||||
|
TargetRef: m.TargetRef,
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,13 +41,16 @@ func (s *Service) GetSite(ctx context.Context, id int) (models.Site, error) {
|
||||||
return s.db.GetSite(ctx, int64(id))
|
return s.db.GetSite(ctx, int64(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetProdTargetOfSite(ctx context.Context, siteID int) (models.PublishTarget, error) {
|
||||||
|
return s.db.GetPublishTargetBySiteRole(ctx, int64(siteID), models.TargetRoleProduction)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) CreateSite(ctx context.Context, user models.User, name string) (models.Site, error) {
|
func (s *Service) CreateSite(ctx context.Context, user models.User, name string) (models.Site, error) {
|
||||||
newSite := models.Site{
|
newSite := models.Site{
|
||||||
Name: normaliseName(name),
|
Name: normaliseName(name),
|
||||||
OwnerUserID: user.ID,
|
OwnerUserID: user.ID,
|
||||||
Title: name,
|
Title: name,
|
||||||
Theme: "bear",
|
Theme: "bear",
|
||||||
URL: "https://meek-meringue-060cfc.netlify.app/",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok := s.themes.Lookup(newSite.Theme)
|
_, ok := s.themes.Lookup(newSite.Theme)
|
||||||
|
|
|
@ -9,8 +9,7 @@ INSERT INTO sites (
|
||||||
name,
|
name,
|
||||||
owner_user_id,
|
owner_user_id,
|
||||||
title,
|
title,
|
||||||
url,
|
|
||||||
theme,
|
theme,
|
||||||
props
|
props
|
||||||
) VALUES ($1, $2, $3, $4, $5, $6)
|
) VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING id;
|
RETURNING id;
|
|
@ -1,5 +1,8 @@
|
||||||
-- name: ListPublishTargetsOfRole :many
|
-- name: ListTargetsOfSite :many
|
||||||
SELECT * FROM publish_targets WHERE site_id = $1 AND role = 'production';
|
SELECT * FROM publish_targets WHERE site_id = $1;
|
||||||
|
|
||||||
|
-- name: GetTargetOfSiteRole :one
|
||||||
|
SELECT * FROM publish_targets WHERE site_id = $1 AND role = $2 LIMIT 1;
|
||||||
|
|
||||||
-- name: InsertPublishTarget :one
|
-- name: InsertPublishTarget :one
|
||||||
INSERT INTO publish_targets (
|
INSERT INTO publish_targets (
|
||||||
|
|
|
@ -22,7 +22,6 @@ CREATE TABLE sites (
|
||||||
owner_user_id BIGINT NOT NULL,
|
owner_user_id BIGINT NOT NULL,
|
||||||
name TEXT NOT NULL UNIQUE,
|
name TEXT NOT NULL UNIQUE,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
url TEXT NOT NULL,
|
|
||||||
theme TEXT NOT NULL,
|
theme TEXT NOT NULL,
|
||||||
props JSON NOT NULL,
|
props JSON NOT NULL,
|
||||||
|
|
||||||
|
@ -50,5 +49,6 @@ CREATE TABLE publish_targets (
|
||||||
url TEXT NOT NULL,
|
url TEXT NOT NULL,
|
||||||
target_ref TEXT NOT NULL,
|
target_ref TEXT NOT NULL,
|
||||||
|
|
||||||
FOREIGN KEY (site_id) REFERENCES sites (id) ON DELETE CASCADE
|
FOREIGN KEY (site_id) REFERENCES sites (id) ON DELETE CASCADE,
|
||||||
|
UNIQUE (site_id, role)
|
||||||
);
|
);
|
|
@ -1,5 +1,7 @@
|
||||||
<h1>Thing</h1>
|
<h1>Thing</h1>
|
||||||
|
|
||||||
|
User = {{.user.Email}}
|
||||||
|
|
||||||
<form method="post" action="/sites">
|
<form method="post" action="/sites">
|
||||||
<input type="submit" value="Create Site">
|
<input type="submit" value="Create Site">
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
<h1>Hugo CMS</h1>
|
<h1>Hugo CMS</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<span>{{.site.Name}}</span>
|
<span>{{.site.Name}}</span>
|
||||||
<a href="{{.site.URL}}">Visit</a>
|
{{ if .prodTarget }}
|
||||||
|
<a href="{{.prodTarget.URL}}" target="_blank">Visit</a>
|
||||||
|
{{ end }}
|
||||||
<a href="#">User</a>
|
<a href="#">User</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
Loading…
Reference in a new issue