-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial server security example...no code yet
- Loading branch information
Showing
16 changed files
with
281 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Query Security | ||
|
||
IN PROGRESS...NO CODE YET, BUT DESCRIPTION IS GOOD | ||
|
||
This recipe walks you through a suggestion on handling query security. It | ||
uses Spectre to walk the query data structure. | ||
|
||
## Running the code | ||
|
||
You want to run both a figwheel build and a server. See the top-level | ||
README for instructions. Be sure you access the app through the server | ||
port or the remote load will not work. | ||
|
||
## UI Query Security | ||
|
||
If you examine any UI query it will have a tree form. That is the nature of Datomic pull syntax | ||
and UI's. For any such query, you can imagine it as a graph walk: | ||
|
||
Take this query: | ||
|
||
``` | ||
[:a {:join1 [:b {:join2 [:c :d]}]}] | ||
``` | ||
|
||
``` | ||
QUERY PART IMPLIED DATABASE graph | ||
[:a {:join1 { :a 6 :join1 [:tableX id1] } | ||
\ | ||
\ | ||
\| | ||
[:b {:join2 :tableX { id1 { :id id1 :join2 [:tableY id2] | ||
/ | ||
/ | ||
|/ | ||
[:c :d]}]}] :tableY { id2 { :id id2 :c 4 :d 5 }} | ||
``` | ||
|
||
One idea that works pretty well for us is based on this realization: There is a starting point of this walk...and | ||
it *must* be specified (or implied at least) by the incoming query. A tradition logic check needs to be run on | ||
this object to see if it is OK for the user to *start* reading the database there. | ||
|
||
Two things remain from there: | ||
|
||
1. Verify the user is allowed to read the specific *data* at the node of the graph (e.g. :a, :c, and :d) | ||
2. Verify the user is allowed to *walk* across a given *reference* at that node of the graph. | ||
|
||
However, since both of those cases are essentially the same in practice (can the user read the given property), the | ||
algorithm simplifies to: | ||
|
||
- Verify the user is allowed to read the "top" object. If not, disallow the query. | ||
- Create a whitelist of keywords that are allowed to be read by the query in question. This can be a one-time | ||
declarative configuration, or something dynamic based on user rights. | ||
- Walk the query, and gather up all keywords | ||
- Find the set difference of the whitelist and the query keywords. | ||
- If the difference if not empty, refuse to run the query |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
(ns cljs.user | ||
(:require | ||
[app.core :refer [app]] | ||
[untangled.client.core :as core] | ||
[cljs.pprint :refer [pprint]] | ||
[devtools.core :as devtools] | ||
[untangled.client.logging :as log] | ||
[app.ui :as ui])) | ||
|
||
(enable-console-print!) | ||
|
||
; Use Chrome...these enable proper formatting of cljs data structures! | ||
(devtools/enable-feature! :sanity-hints) | ||
(devtools/install!) | ||
|
||
; Mount the app and remember it. | ||
(reset! app (core/mount @app ui/Root "app")) | ||
|
||
; use this from REPL to view bits of the application db | ||
(defn log-app-state | ||
"Helper for logging the app-state, pass in top-level keywords from the app-state and it will print only those | ||
keys and their values." | ||
[& keywords] | ||
(pprint (let [app-state @(:reconciler @app)] | ||
(if (= 0 (count keywords)) | ||
app-state | ||
(select-keys app-state keywords))))) | ||
|
||
; Om/dev logging level | ||
;(log/set-level :none) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
(ns user | ||
(:require | ||
[clojure.pprint :refer (pprint)] | ||
[clojure.stacktrace :refer (print-stack-trace)] | ||
[clojure.tools.namespace.repl :refer [disable-reload! refresh clear set-refresh-dirs]] | ||
[com.stuartsierra.component :as component] | ||
[figwheel-sidecar.repl-api :as ra] | ||
[app.system :as sys] | ||
[taoensso.timbre :as timbre])) | ||
|
||
;;FIGWHEEL | ||
|
||
(def figwheel-config | ||
{:figwheel-options {:css-dirs ["resources/public/css"]} | ||
:build-ids ["dev"] | ||
:all-builds (figwheel-sidecar.repl/get-project-cljs-builds)}) | ||
|
||
(defn start-figwheel | ||
"Start Figwheel on the given builds, or defaults to build-ids in `figwheel-config`." | ||
([] | ||
(let [props (System/getProperties) | ||
all-builds (->> figwheel-config :all-builds (mapv :id))] | ||
(start-figwheel (keys (select-keys props all-builds))))) | ||
([build-ids] | ||
(let [default-build-ids (:build-ids figwheel-config) | ||
build-ids (if (empty? build-ids) default-build-ids build-ids)] | ||
(println "STARTING FIGWHEEL ON BUILDS: " build-ids) | ||
(ra/start-figwheel! (assoc figwheel-config :build-ids build-ids)) | ||
(ra/cljs-repl)))) | ||
|
||
(set-refresh-dirs "src/server") | ||
|
||
(defonce system (atom nil)) | ||
|
||
(defn init | ||
"Create a web server from configurations. Use `start` to start it." | ||
[] | ||
(reset! system (sys/make-system))) | ||
|
||
(defn start "Start (an already initialized) web server." [] (swap! system component/start)) | ||
|
||
(defn stop "Stop the running web server." [] | ||
(when @system | ||
(swap! system component/stop) | ||
(reset! system nil))) | ||
|
||
(defn go "Load the overall web server system and start it." [] | ||
(init) | ||
(start)) | ||
|
||
(defn reset | ||
"Stop the web server, refresh all namespace source code from disk, then restart the web server." | ||
[] | ||
(stop) | ||
(refresh :after 'user/go)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
(defproject untangled/demo "1.0.0" | ||
:description "Untangled Cookbook Recipe" | ||
:url "" | ||
:license {:name "MIT" | ||
:url "https://opensource.org/licenses/MIT"} | ||
|
||
:dependencies [[com.datomic/datomic-free "0.9.5206" :exclusions [joda-time]] | ||
[com.taoensso/timbre "4.3.1"] | ||
[commons-codec "1.10"] | ||
[org.clojure/clojure "1.7.0"] | ||
[org.clojure/clojurescript "1.7.228"] | ||
[org.omcljs/om "1.0.0-alpha31"] | ||
[binaryage/devtools "0.5.2" :exclusions [environ]] | ||
[figwheel-sidecar "0.5.0-3" :exclusions [ring/ring-core joda-time org.clojure/tools.reader]] | ||
[com.cemerick/piggieback "0.2.1"] | ||
[org.clojure/tools.nrepl "0.2.12"] | ||
[juxt/dirwatch "0.2.3"] | ||
[navis/untangled-client "0.4.6" :exclusions [cljsjs/react org.omcljs/om]] | ||
[navis/untangled-server "0.4.5"] | ||
[navis/untangled-datomic "0.4.4" :exclusions [com.datomic/datomic-free org.clojure/tools.cli]]] | ||
|
||
:plugins [[lein-cljsbuild "1.1.2"] [lein-environ "1.0.0"]] | ||
|
||
:source-paths ["dev/server" "src/server"] | ||
:jvm-opts ["-server" "-Xmx1024m" "-Xms512m" "-XX:-OmitStackTraceInFastThrow"] | ||
:clean-targets ^{:protect false} ["resources/public/js" "target"] | ||
|
||
:cljsbuild {:builds | ||
[{:id "dev" | ||
:source-paths ["src/client" "dev/client"] | ||
:figwheel true | ||
:compiler {:main cljs.user | ||
:asset-path "js/compiled/dev" | ||
:output-to "resources/public/js/compiled/app.js" | ||
:output-dir "resources/public/js/compiled/dev" | ||
:optimizations :none | ||
:parallel-build false | ||
:verbose false | ||
:recompile-dependents true | ||
:source-map-timestamp true}}]} | ||
|
||
:figwheel {:css-dirs ["resources/public/css"]} | ||
|
||
:repl-options {:init-ns user | ||
:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{:port 8080} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>Untangled Recipe</title> | ||
<link rel="stylesheet" href="css/base.css"> | ||
<link rel="stylesheet" href="css/index.css"> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
<script src="js/compiled/app.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(require '[user :refer [start-figwheel]]) | ||
|
||
(start-figwheel) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
(ns app.core | ||
(:require | ||
app.mutations | ||
[untangled.client.core :as uc] | ||
[untangled.i18n :refer-macros [tr trf]] | ||
[untangled.client.data-fetch :as df] | ||
[om.next :as om])) | ||
|
||
(def initial-state {:ui/react-key "abc"}) | ||
|
||
(defonce app (atom (uc/new-untangled-client | ||
:initial-state initial-state | ||
:started-callback | ||
(fn [{:keys [reconciler]}] | ||
; TODO | ||
)))) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(ns app.mutations | ||
(:require [untangled.client.mutations :as m])) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
(ns app.ui | ||
(:require [om.dom :as dom] | ||
[om.next :as om :refer-macros [defui]] | ||
[untangled.i18n :refer-macros [tr trf]] | ||
yahoo.intl-messageformat-with-locales | ||
[untangled.client.data-fetch :as df])) | ||
|
||
(defui ^:once Child | ||
Object | ||
(render [this] (dom/p nil "TODO"))) | ||
|
||
(def ui-child (om/factory Child)) | ||
|
||
(defui ^:once Root | ||
static om/IQuery | ||
(query [this] [:ui/react-key]) | ||
Object | ||
(render [this] | ||
(let [{:keys [ui/react-key] :or {ui/react-key "ROOT"} :as props} (om/props this)] | ||
(dom/div #js {:key react-key} (ui-child))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
(ns app.api | ||
(:require [om.next.server :as om] | ||
[om.next.impl.parser :as op] | ||
[taoensso.timbre :as timbre])) | ||
|
||
(defmulti apimutate om/dispatch) | ||
(defmulti api-read om/dispatch) | ||
|
||
(defmethod apimutate :default [e k p] | ||
(timbre/error "Unrecognized mutation " k)) | ||
|
||
(defmethod api-read :default [{:keys [ast query] :as env} dispatch-key params] | ||
(timbre/error "Unrecognized query " (op/ast->expr ast))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
(ns app.system | ||
(:require | ||
[untangled.server.core :as core] | ||
[app.api :as api] | ||
[om.next.server :as om] | ||
[taoensso.timbre :as timbre] | ||
[om.next.impl.parser :as op])) | ||
|
||
(defn logging-mutate [env k params] | ||
(timbre/info "Mutation Request: " k) | ||
(api/apimutate env k params)) | ||
|
||
(defn logging-query [{:keys [ast] :as env} k params] | ||
(timbre/info "Query: " (op/ast->expr ast)) | ||
(api/api-read env k params)) | ||
|
||
(defn make-system [] | ||
(core/make-untangled-server | ||
:config-path "config/recipe.edn" | ||
:parser (om/parser {:read logging-query :mutate logging-mutate}) | ||
:parser-injections #{} | ||
:components {})) |