0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 16:00:19 -05:00

🚧 Add project roles table.

This commit is contained in:
Andrey Antukh 2019-12-01 12:07:51 +01:00
parent 04464da1c8
commit f21ac8afbe
10 changed files with 160 additions and 39 deletions

View file

@ -17,9 +17,10 @@
;; vertx-clojure/vertx {:mvn/version "0.0.0-SNAPSHOT"}
metosin/reitit-core {:mvn/version "0.3.10"}
metosin/sieppari {:mvn/version "0.0.0-alpha8"}
io.vertx/vertx-core {:mvn/version "3.8.1"}
io.vertx/vertx-web {:mvn/version "3.8.1"}
io.vertx/vertx-pg-client {:mvn/version "3.8.1"}
io.vertx/vertx-core {:mvn/version "3.8.4"}
io.vertx/vertx-web {:mvn/version "3.8.4"}
io.vertx/vertx-web-client {:mvn/version "3.8.4"}
io.vertx/vertx-pg-client {:mvn/version "3.8.4"}
;; end verx deps
lambdaisland/uri {:mvn/version "1.1.0"}

View file

@ -11,43 +11,37 @@ CREATE TABLE IF NOT EXISTS projects (
name text NOT NULL
);
CREATE TABLE IF NOT EXISTS project_shares (
project uuid PRIMARY KEY REFERENCES projects(id) ON DELETE CASCADE,
CREATE TABLE IF NOT EXISTS projects_roles (
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
token text
role text NOT NULL,
PRIMARY KEY (user_id, project_id)
);
CREATE TABLE IF NOT EXISTS project_shares (
project_id uuid PRIMARY KEY REFERENCES projects(id) ON DELETE CASCADE,
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
token text NOT NULL
);
-- Indexes
CREATE INDEX projects_user_idx
ON projects(user_id);
CREATE INDEX projects_user_idx ON projects(user_id);
CREATE INDEX projects_roles_user_id_idx ON projects_roles(project_id);
CREATE INDEX projects_roles_project_id_idx ON projects_roles(user_id);
CREATE UNIQUE INDEX projects_shares_token_idx
ON project_shares(token);
CREATE UNIQUE INDEX projects_shares_token_idx ON project_shares(token);
-- Triggers
CREATE OR REPLACE FUNCTION handle_project_create()
RETURNS TRIGGER AS $$
DECLARE
token text;
BEGIN
SELECT encode(digest(gen_random_bytes(128), 'sha256'), 'hex')
INTO token;
INSERT INTO project_shares (project, token)
VALUES (NEW.id, token);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER project_on_create_tgr
AFTER INSERT ON projects
FOR EACH ROW EXECUTE PROCEDURE handle_project_create();
CREATE TRIGGER projects_modified_at_tgr
BEFORE UPDATE ON projects
FOR EACH ROW EXECUTE PROCEDURE update_modified_at();

View file

@ -22,6 +22,7 @@
[buddy.core.nonce :as nonce]
[mount.core :as mount]
[uxbox.main]
[uxbox.util.sql :as sql]
[uxbox.util.blob :as blob])
(:gen-class))

View file

@ -36,6 +36,7 @@
{:http-server-port (lookup-env env :uxbox-http-server-port 6060)
:http-server-debug (lookup-env env :uxbox-http-server-debug true)
:http-server-cors (lookup-env env :uxbox-http-server-cors "http://localhost:3449")
:database-username (lookup-env env :uxbox-database-username nil)
:database-password (lookup-env env :uxbox-database-password nil)
:database-uri (lookup-env env :uxbox-database-uri "postgresql://127.0.0.1/uxbox")
@ -44,6 +45,8 @@
:assets-directory (lookup-env env :uxbox-assets-directory "resources/public/static")
:assets-uri (lookup-env env :uxbox-assets-uri "http://localhost:6060/static/")
:google-api-key (lookup-env env :uxbox-google-api-key nil)
:email-reply-to (lookup-env env :uxbox-email-reply-to "no-reply@uxbox.io")
:email-from (lookup-env env :uxbox-email-from "no-reply@uxbox.io")

View file

@ -48,13 +48,21 @@
values ($1, $2, $3)
returning *;")
(def create-project-role-sql
"insert into projects_roles (project_id, user_id, role)
values ($1, $2, 'owner');")
(defn create-project
[conn [pjid uid]]
(println "create project" pjid "(for user=" uid ")")
(db/query-one conn [create-project-sql
(mk-uuid "project" pjid uid)
(mk-uuid "user" uid)
(str "sample project " pjid)]))
(p/do!
(db/query-one conn [create-project-sql
(mk-uuid "project" pjid uid)
(mk-uuid "user" uid)
(str "sample project " pjid)])
(db/query-one conn [create-project-role-sql
(mk-uuid "project" pjid uid)
(mk-uuid "user" uid)])))
;; --- Pages creation

View file

@ -0,0 +1,63 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.fonts
(:require
[clojure.spec.alpha :as s]
[vertx.web.client :as vwc]
[mount.core :as mount :refer [defstate]]
[promesa.core :as p]
[uxbox.core :refer [system]]
[uxbox.config :as cfg]
[uxbox.db :as db]
[uxbox.services.core :as sv]
[uxbox.services.users :as users]
[uxbox.util.transit :as t]
[uxbox.util.spec :as us]
[uxbox.util.uuid :as uuid]
[uxbox.util.data :as data]
[uxbox.util.exceptions :as ex]))
(defstate webclient
:start (vwc/create system)
:stop (.close webclient))
(s/def ::google-fonts any?)
(def fonts-url
"https://www.googleapis.com/webfonts/v1/webfonts?key=")
(def api-key
"AIzaSyD3iPn7K0sJp5oOi3BRohLDuAA2SKOFJw4")
(defn fetch-and-store
[]
(let [ses (vwc/session webclient)]
(-> (vwc/get ses (str fonts-url api-key))
(p/then' (fn [{:keys [status body]}]
(get (t/decode body) "items" [])))
(p/then' data/normalize-attrs)
(p/then (fn [result]
(-> (sv/mutation {::sv/type :upsert-kvstore
:key "google-fonts"
:user uuid/zero
:value result})
(p/catch (fn [err]
(prn "KAKA" err)
(throw err)))
(p/then (constantly result))))))))
(sv/defquery ::google-fonts
"Returns a cached version of google fonts."
[params]
(-> (sv/query {::sv/type :kvstore-entry
:key "google-fonts"
:user uuid/zero})
(p/catch (fn [err]
(let [edata (ex-data err)]
(if (= :not-found (:type edata))
(fetch-and-store)
(p/rejected err)))))))

View file

@ -113,7 +113,6 @@
(-> (db/query-one db/pool [sql id user project-id name data mdata])
(p/then' decode-row))))
;; --- Mutation: Update Page
(s/def ::update-page

View file

@ -34,9 +34,8 @@
(declare -handle-body)
(defn ->headers
[^HttpServerRequest request]
(let [headers (.headers request)
it (.iterator ^MultiMap headers)]
[^MultiMap headers]
(let [it (.iterator ^MultiMap headers)]
(loop [m (transient {})]
(if (.hasNext it)
(let [^Map$Entry me (.next it)
@ -49,7 +48,7 @@
[^HttpServerRequest request]
{:method (-> request .rawMethod .toLowerCase keyword)
:path (.path request)
:headers (->headers request)
:headers (->headers (.headers request))
::request request
::response (.response request)})

View file

@ -47,7 +47,7 @@
^Vertx system (.vertx routing-context)]
{:body (.getBody routing-context)
:path (.path request)
:headers (vh/->headers request)
:headers (vh/->headers (.headers request))
:method (-> request .rawMethod .toLowerCase keyword)
::vh/request request
::vh/response response

View file

@ -0,0 +1,53 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
(ns vertx.web.client
"High level http client."
(:refer-clojure :exclude [get])
(:require
[clojure.tools.logging :as log]
[clojure.spec.alpha :as s]
[promesa.core :as p]
[sieppari.core :as sp]
[reitit.core :as rt]
[vertx.http :as vh]
[vertx.util :as vu])
(:import
clojure.lang.IPersistentMap
clojure.lang.Keyword
io.vertx.core.Future
io.vertx.core.Handler
io.vertx.core.Vertx
io.vertx.core.buffer.Buffer
io.vertx.core.http.HttpMethod
io.vertx.ext.web.client.HttpRequest
io.vertx.ext.web.client.HttpResponse
io.vertx.ext.web.client.WebClientSession
io.vertx.ext.web.client.WebClient))
;; TODO: accept options
(defn create
([vsm] (create vsm {}))
([vsm opts]
(let [^Vertx system (vu/resolve-system vsm)]
(WebClient/create system))))
(defn session
[client]
(WebClientSession/create client))
(defn get
([session url] (get session url {}))
([session url opts]
(let [^HttpRequest req (.getAbs session url)
d (p/deferred)]
(.send req (vu/deferred->handler d))
(p/then d (fn [^HttpResponse res]
{:body (.bodyAsBuffer res)
:status (.statusCode res)
:headers (vh/->headers (.headers res))})))))