From e425c56ec2a5feaa075e6ccd404d872192e30e50 Mon Sep 17 00:00:00 2001
From: simon
Date: Sat, 1 Apr 2017 15:11:50 +0100
Subject: [PATCH 01/20] #5: Started work on roles switching
---
doc/specification/database.md | 218 ++++++++++++++++++
.../entity-relationship-diagram.svg | 67 +++++-
...170401115900-basic-reference-data-down.sql | 0
...20170401115900-basic-reference-data-up.sql | 58 +++++
resources/sql/queries.sql | 1 +
resources/templates/base-authenticated.html | 74 ++++++
resources/templates/base-unauthenticated.html | 58 +++++
resources/templates/roles.html | 13 ++
src/clj/youyesyet/db/core.clj | 8 +-
src/clj/youyesyet/handler.clj | 23 ++
src/clj/youyesyet/routes/authenticated.clj | 35 +++
src/clj/youyesyet/routes/home.clj | 78 ++++++-
src/cljc/youyesyet/validation.cljc | 23 ++
src/cljs/youyesyet/ajax.cljs | 24 ++
14 files changed, 661 insertions(+), 19 deletions(-)
create mode 100644 doc/specification/database.md
create mode 100644 resources/migrations/20170401115900-basic-reference-data-down.sql
create mode 100644 resources/migrations/20170401115900-basic-reference-data-up.sql
create mode 100644 resources/templates/base-authenticated.html
create mode 100644 resources/templates/base-unauthenticated.html
create mode 100644 resources/templates/roles.html
create mode 100644 src/clj/youyesyet/routes/authenticated.clj
diff --git a/doc/specification/database.md b/doc/specification/database.md
new file mode 100644
index 0000000..2656621
--- /dev/null
+++ b/doc/specification/database.md
@@ -0,0 +1,218 @@
+# Database Specification
+
+Note that this is a work in progress. Read it in concert with the Entity-Relationship Diagram.
+
+Tables are listed in alphabetical order.
+
+## Address
+
+The postal address of a dwelling at which electors are registered.
+
+ CREATE TABLE IF NOT EXISTS addresses (
+ id integer NOT NULL,
+ address character varying(256) NOT NULL,
+ postcode character varying(16),
+ phone character varying(16),
+ district_id integer,
+ latitude real,
+ longitude real
+ );
+
+## Authority
+
+An *oauth* authority which authenticates canvassers. *Note that* there will need to be substantially more in this table but I don't yet know what.
+
+ CREATE TABLE IF NOT EXISTS authorities (
+ id character varying(32) NOT NULL
+ );
+
+
+## Canvasser
+
+A user of the system.
+
+ CREATE TABLE IF NOT EXISTS canvassers (
+ id serial,
+ username character varying(32) NOT NULL,
+ fullname character varying(64) NOT NULL,
+ elector_id integer,
+ address_id integer NOT NULL,
+ phone character varying(16),
+ email character varying(128),
+ authority_id character varying(32) NOT NULL,
+ authorised boolean
+ );
+
+
+## District
+
+An electoral district.
+
+ CREATE TABLE IF NOT EXISTS districts (
+ id integer NOT NULL,
+ name character varying(64) NOT NULL
+ );
+
+
+## Elector
+
+Someone entitled to cast a vote in the referendum.
+
+ CREATE TABLE IF NOT EXISTS electors (
+ id integer NOT NULL,
+ name character varying(64) NOT NULL,
+ address_id integer NOT NULL,
+ phone character varying(16),
+ email character varying(128)
+ );
+
+## Followup Action
+
+An action performed by an issue expert in response to a followup request.
+
+ CREATE TABLE IF NOT EXISTS followupactions (
+ id integer NOT NULL,
+ request_id integer NOT NULL,
+ actor integer NOT NULL,
+ date timestamp with time zone DEFAULT now() NOT NULL,
+ notes text,
+ closed boolean
+ );
+
+## Followup Method
+
+A method for responding to a followup request; reference data.
+
+ CREATE TABLE IF NOT EXISTS followupmethods (
+ id character varying(32) NOT NULL
+ );
+
+ insert into followupmethods values ('Telephone');
+ insert into followupmethods values ('eMail');
+ insert into followupmethods values ('Post');
+
+## Followup Request
+
+A request recorded by a canvasser for an issue expert to contact an elector with regard to a particular issue.
+
+ CREATE TABLE IF NOT EXISTS followuprequests (
+ id integer NOT NULL,
+ elector_id integer NOT NULL,
+ visit_id integer NOT NULL,
+ issue_id character varying(32) NOT NULL,
+ method_id character varying(32) NOT NULL
+ );
+
+## Intention
+
+An intention, by an elector, to vote for an option; captured by a canvasser during a visit.
+
+ CREATE TABLE IF NOT EXISTS intentions (
+ id serial not null,
+ elector integer not null references elector(id),
+ option varchar(32) not null references option(id),
+ visit integer not null references visit(id),
+ date timestamp with time zone DEFAULT now() NOT NULL
+ );
+
+
+## Issue
+
+An issue which might affect electors' decisions regarding their intention.
+
+ CREATE TABLE IF NOT EXISTS issues (
+ id character varying(32) NOT NULL,
+ url character varying(256),
+ content varchar(1024),
+ current default false
+ );
+
+
+## Issue expertise
+
+Expertise of a canvasser able to use a method, in an issue.
+
+ CREATE TABLE IF NOT EXISTS issueexpertise (
+ canvasser_id integer NOT NULL,
+ issue_id character varying(32) NOT NULL,
+ method_id character varying(32) NOT NULL
+ );
+
+
+## Option
+
+An option for which an elector may have an intention to vote.
+
+ CREATE TABLE IF NOT EXISTS options (
+ id character varying(32) NOT NULL
+ );
+
+
+## Role
+
+A role (other than basic *Canvasser*) that a user may have in the system. Reference data.
+
+ create table if not exists roles (
+ id serial primary key,
+ name varchar(64) not null
+ );
+
+
+## Role Member
+
+Membership of a user (*Canvasser*) of an additional role; link table.
+
+ create table if not exists rolememberships (
+ role_id integer not null references roles(id),
+ canvasser_id integer not null references canvassers(id)
+ );
+
+
+## Team
+
+A team of canvassers in a locality who are known to one another and frequently
+canvas together.
+
+ create table if not exists teams (
+ id serial primary key,
+ name varchar(64) not null,
+ district_id integer not null references districts(id),
+ latitude real,
+ longitude real
+ );
+
+
+## Team Member
+
+Membership of a user (*Canvasser*) of a particular team. Canvassers may join multiple teams. Link table.
+
+ create table if not exists teammemberships (
+ team_id integer not null references teams(id),
+ canvasser_id integer not null references canvassers(id)
+ );
+
+
+## Team Organiser
+
+A relationship which defines a user (*Canvasser*) as an organiser of a team. A team may
+have more than one organiser. An organiser (if they also have the role 'Recruiter', which
+they often will have) may recruit additional Canvassers as members of their team, or
+accept applications by canvassers to join their team. An organiser may promote a member of
+the team to organiser of the team, and may also exclude a member from the team.
+
+ create table if not exists teamorganiserships (
+ team_id integer not null references teams(id),
+ canvasser_id integer not null references canvassers(id)
+ );
+
+
+## Visit
+
+A visit by a canvasser to an address on a date to solicit intentions from electors.
+
+ CREATE TABLE IF NOT EXISTS visits (
+ id integer NOT NULL,
+ address_id integer NOT NULL,
+ canvasser_id integer NOT NULL,
+ date timestamp with time zone DEFAULT now() NOT NULL
+ );
diff --git a/doc/specification/entity-relationship-diagram.svg b/doc/specification/entity-relationship-diagram.svg
index 0de6cf0..7068dd2 100644
--- a/doc/specification/entity-relationship-diagram.svg
+++ b/doc/specification/entity-relationship-diagram.svg
@@ -25,9 +25,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="1.979899"
- inkscape:cx="833.70674"
- inkscape:cy="324.89697"
+ inkscape:zoom="2.8"
+ inkscape:cx="764.16287"
+ inkscape:cy="256.90499"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -58,12 +58,13 @@
id="layer1"
transform="translate(0,-308.26772)">
+ x="8.484766"
+ y="312.36221"
+ sodipodi:insensitive="true" />
Addresss
+ sodipodi:role="line">Address
@@ -613,14 +614,14 @@
y="394.48404"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:Arial;-inkscape-font-specification:Arial">Version: 0.2Version: 0.3Date: 20170315Date: 20170401
+
+ FollowupMethod
+
+
+
+
diff --git a/resources/migrations/20170401115900-basic-reference-data-down.sql b/resources/migrations/20170401115900-basic-reference-data-down.sql
new file mode 100644
index 0000000..e69de29
diff --git a/resources/migrations/20170401115900-basic-reference-data-up.sql b/resources/migrations/20170401115900-basic-reference-data-up.sql
new file mode 100644
index 0000000..6ca3028
--- /dev/null
+++ b/resources/migrations/20170401115900-basic-reference-data-up.sql
@@ -0,0 +1,58 @@
+
+-- We don't explicitly instantiate the 'Canvasser' role since every user is
+-- deemed to be a canvasser.
+
+
+-- an 'Expert' is someone with expertise in one or more issues, who is
+-- trusted to discuss those issues in detail with electors.
+insert into roles (name) values ('Expert');
+
+
+-- an 'Administrator' is someone entitled to broadly alter reference data
+-- throughout the system.
+insert into roles (name) values ('Administrator');
+
+
+-- a 'Recruiter' is someone entitled to invite other people to become users
+-- ('Canvassers'). A Recruiter is entitled to lock the account of anyone they
+-- have recruited, recursively.
+insert into roles (name) values ('Recruiter');
+
+
+-- an 'Organiser' is someone who organises one or more local teams. An Organiser
+-- is entitled to exclude any Canvasser from any team they organise.
+insert into roles (name) values ('Organiser');
+
+
+-- an 'Editor' is someone entitled to add and edit issues.
+insert into roles (name) values ('Editor');
+
+-- issue text is local; there may still in addition be a further link to more
+-- information, but the basic issue text should be part of the issue record.
+-- The text should fit on a phone screen without scrolling, so is reasonably
+-- short.
+alter table issues add column content varchar(1024);
+
+-- an issue may be current or not current; when not current it is not deleted
+-- from the system but kept because it may become current again later. Only
+-- current issues are shown in the app. Typically not fewer than three and not
+-- more than about seven issues should be current at any time.
+alter table issues add column current default false;
+
+insert into issues (id, content, current) values ('Currency',
+ 'Scotland could keep the Pound, or use the Euro. But we could also set up a new currency of our own.',
+ true);
+
+insert into issues (id, content, current) values ('Monarchy',
+ 'Scotland could keep the Queen. This is an issue to be decided after independence.',
+ true);
+
+insert into issues (id, content, current) values ('Defence',
+ 'Scotland will not have nuclear weapons, and will probably not choose to engage in far-off wars. But we could remain members of NATO.',
+ true);
+
+
+insert into options (id) values ('Yes');
+
+insert into options (id) values ('No');
+
diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql
index 4191f67..ab15d8e 100644
--- a/resources/sql/queries.sql
+++ b/resources/sql/queries.sql
@@ -19,3 +19,4 @@ WHERE id = :id
-- :doc delete a user given the id
DELETE FROM users
WHERE id = :id
+
diff --git a/resources/templates/base-authenticated.html b/resources/templates/base-authenticated.html
new file mode 100644
index 0000000..79c1558
--- /dev/null
+++ b/resources/templates/base-authenticated.html
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+ {% block title %}{% endblock %}{{title}}
+
+
+
+
+ {% endfor %}
+{% endblock %}
diff --git a/src/clj/youyesyet/db/core.clj b/src/clj/youyesyet/db/core.clj
index 536cc3b..a0eec57 100644
--- a/src/clj/youyesyet/db/core.clj
+++ b/src/clj/youyesyet/db/core.clj
@@ -15,9 +15,13 @@
Timestamp
PreparedStatement]))
+;; TODO: I am CERTANLY misunderstanding something here. We ought to be getting
+;; the database connection string and credentials fomr profiles.clj
+;; (def ^:dynamic *db* {:name "java:comp/env/jdbc/EmployeeDB"})
(defstate ^:dynamic *db*
- :start (conman/connect! {:jdbc-url (env :database-url)})
- :stop (conman/disconnect! *db*))
+ :start (conman/connect! {:jdbc-url (env :database-url)
+ :driver-class-name "org.postgresql.Driver"})
+ :stop (conman/disconnect! *db*))
(conman/bind-connection *db* "sql/queries.sql")
diff --git a/src/clj/youyesyet/handler.clj b/src/clj/youyesyet/handler.clj
index f898fe5..ad5462d 100644
--- a/src/clj/youyesyet/handler.clj
+++ b/src/clj/youyesyet/handler.clj
@@ -10,6 +10,29 @@
[clojure.tools.logging :as log]
[youyesyet.config :refer [env]]))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; youyesyet.handler: handlers for starting and stopping the webapp.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2016 Simon Brooke for Radical Independence Campaign
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(mount/defstate init-app
:start ((or (:init defaults) identity))
:stop ((or (:stop defaults) identity)))
diff --git a/src/clj/youyesyet/routes/authenticated.clj b/src/clj/youyesyet/routes/authenticated.clj
new file mode 100644
index 0000000..b5c2644
--- /dev/null
+++ b/src/clj/youyesyet/routes/authenticated.clj
@@ -0,0 +1,35 @@
+(ns youyesyet.routes.authenticated
+ (:require [clojure.walk :refer [keywordize-keys]]
+ [noir.response :as nresponse]
+ [noir.util.route :as route]
+ [youyesyet.layout :as layout]
+ [youyesyet.db.core :as db-core]
+ [compojure.core :refer [defroutes GET POST]]
+ [ring.util.http-response :as response]
+ [clojure.java.io :as io]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; youyesyet.routes.authenticated: routes and pages for authenticated users.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2016 Simon Brooke for Radical Independence Campaign
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; (defn roles-page [request]
+;; (if
diff --git a/src/clj/youyesyet/routes/home.clj b/src/clj/youyesyet/routes/home.clj
index 7fbf9f7..90f2f12 100644
--- a/src/clj/youyesyet/routes/home.clj
+++ b/src/clj/youyesyet/routes/home.clj
@@ -1,15 +1,81 @@
(ns youyesyet.routes.home
- (:require [youyesyet.layout :as layout]
+ (:require [clojure.walk :refer [keywordize-keys]]
+ [noir.response :as nresponse]
+ [noir.util.route :as route]
+ [youyesyet.layout :as layout]
[youyesyet.db.core :as db-core]
- [compojure.core :refer [defroutes GET]]
+ [compojure.core :refer [defroutes GET POST]]
[ring.util.http-response :as response]
[clojure.java.io :as io]))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; youyesyet.routes.home: routes and pages for unauthenticated users.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2016 Simon Brooke for Radical Independence Campaign
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn app-page []
+ (layout/render "app.html"))
+
+(defn about-page []
+ (layout/render "about.html"))
+
+(defn call-me-page [request]
+ (if
+ request
+ (do
+ ;; do something to store it in the database
+ (layout/render "call-me-accepted.html" (:params request)))
+ (layout/render "call-me.html"
+ {:title "Please call me!"
+ ;; TODO: Issues need to be fetched from the database
+ :concerns nil})))
+
(defn home-page []
- (layout/render "home.html"))
+ (layout/render "home.html" {:title "You Yes Yet?"}))
+
+(defn login-page
+ "This is very temporary. We're going to do authentication by oauth."
+ [request]
+ (let [params (keywordize-keys (:form-params request))
+ session (:session request)
+ username (:username params)
+ password (:password params)
+ redirect-to (or (:redirect-to params) "app")]
+ (if
+ (and (= username "test") (= password "test"))
+ (do
+ (assoc (response/found redirect-to) :session (assoc session :user username)))
+ (layout/render "login.html" {:title "Please log in" :redirect-to redirect-to}))))
+
(defroutes home-routes
(GET "/" [] (home-page))
- (GET "/docs" [] (-> (response/ok (-> "docs/docs.md" io/resource slurp))
- (response/header "Content-Type" "text/plain; charset=utf-8"))))
-
+ (GET "/home" [] (home-page))
+ (GET "/about" [] (about-page))
+ (GET "/app" [] (route/restricted (app-page)))
+ (GET "/call-me" [] (call-me-page nil))
+ (POST "/call-me" request (call-me-page request))
+ (GET "/auth" request (login-page request))
+ (POST "/auth" request (login-page request))
+ (GET "/notyet" [] (layout/render "notyet.html"
+ {:title "Can we persuade you?"}))
+ (GET "/supporter" [] (layout/render "supporter.html"
+ {:title "Have you signed up as a canvasser yet?"})))
diff --git a/src/cljc/youyesyet/validation.cljc b/src/cljc/youyesyet/validation.cljc
index fd01d8f..7c293dd 100644
--- a/src/cljc/youyesyet/validation.cljc
+++ b/src/cljc/youyesyet/validation.cljc
@@ -1,3 +1,26 @@
(ns youyesyet.validation
(:require [bouncer.core :as b]
[bouncer.validators :as v]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; youyesyet.validation:
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2016 Simon Brooke for Radical Independence Campaign
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/src/cljs/youyesyet/ajax.cljs b/src/cljs/youyesyet/ajax.cljs
index 07cf00d..ef3a3cb 100644
--- a/src/cljs/youyesyet/ajax.cljs
+++ b/src/cljs/youyesyet/ajax.cljs
@@ -1,6 +1,30 @@
(ns youyesyet.ajax
(:require [ajax.core :as ajax]))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; youyesyet.ajax: transciever for ajax packets.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2016 Simon Brooke for Radical Independence Campaign
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
(defn local-uri? [{:keys [uri]}]
(not (re-find #"^\w+?://" uri)))
From 19e7b2493353ebf0eed6f682f4dc29f02566acd5 Mon Sep 17 00:00:00 2001
From: simon
Date: Tue, 4 Apr 2017 09:33:24 +0100
Subject: [PATCH 02/20] Added lots of queries (not yet complete).
---
resources/sql/queries.sql | 221 +++++++++++++++++++++++++++++++++++---
1 file changed, 206 insertions(+), 15 deletions(-)
diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql
index ab15d8e..6dbcae4 100644
--- a/resources/sql/queries.sql
+++ b/resources/sql/queries.sql
@@ -1,22 +1,213 @@
--- :name create-user! :! :n
--- :doc creates a new user record
-INSERT INTO users
-(id, first_name, last_name, email, pass)
-VALUES (:id, :first_name, :last_name, :email, :pass)
+-- :name create-address! :! :n
+-- :doc creates a new address record
+INSERT INTO addresses
+(address, postcode, district_id, latitude, longitude)
+VALUES (:address, :postcode, :district, :latitude, :longitude)
--- :name update-user! :! :n
--- :doc update an existing user record
-UPDATE users
-SET first_name = :first_name, last_name = :last_name, email = :email
+-- :name update-address! :! :n
+-- :doc update an existing address record
+UPDATE addresses
+SET address = :address, postcode = :postcode, latitude = :latitude, longitude = :longitude
WHERE id = :id
--- :name get-user :? :1
--- :doc retrieve a user given the id.
-SELECT * FROM users
+-- :name get-address :? :1
+-- :doc retrieve a address given the id.
+SELECT * FROM addresses
WHERE id = :id
--- :name delete-user! :! :n
--- :doc delete a user given the id
-DELETE FROM users
+-- :name delete-address! :! :n
+-- :doc delete a address given the id
+DELETE FROM addresses
WHERE id = :id
+
+-- :name create-authority! :! :n
+-- :doc creates a new authority record
+INSERT INTO authorities
+(id)
+VALUES (:id)
+
+-- :name update-authority! :! :n
+-- :doc update an existing authority record
+UPDATE authorities
+SET id = :id
+WHERE id = :id
+
+-- :name get-authority :? :1
+-- :doc retrieve a authority given the id.
+SELECT * FROM authorities
+WHERE id = :id
+
+-- :name delete-authority! :! :n
+-- :doc delete a authority given the id
+DELETE FROM authorities
+WHERE id = :id
+
+
+-- :name create-canvasser! :! :n
+-- :doc creates a new canvasser record
+INSERT INTO canvassers
+(username, fullname, elector_id, address_id, phone, email, authority_id, authorised)
+VALUES (:username, :fullname, :elector_id, :address_id, :phone, :email, :authority_id, :authorised)
+
+-- :name update-canvasser! :! :n
+-- :doc update an existing canvasser record
+UPDATE canvassers
+SET username = :username, fullname = :fullname, elector_id = :elector_id, address_id = :address_id, phone = :phone, email = :email, authority_id = :authority_id, authorised = :authorised
+WHERE id = :id
+
+-- :name get-canvasser :? :1
+-- :doc retrieve a canvasser given the id.
+SELECT * FROM canvassers
+WHERE id = :id
+
+-- :name delete-canvasser! :! :n
+-- :doc delete a canvasser given the id
+DELETE FROM canvassers
+WHERE id = :id
+
+
+-- :name create-district! :! :n
+-- :doc creates a new district record
+INSERT INTO districts
+(id, name)
+VALUES (:id, :name)
+
+-- :name update-district! :! :n
+-- :doc update an existing district record
+UPDATE districts
+SET name = :name
+WHERE id = :id
+
+-- :name get-district :? :1
+-- :doc retrieve a district given the id.
+SELECT * FROM districts
+WHERE id = :id
+
+-- :name delete-district! :! :n
+-- :doc delete a district given the id
+DELETE FROM districts
+WHERE id = :id
+
+
+-- :name create-elector! :! :n
+-- :doc creates a new elector record
+INSERT INTO electors
+(name, address_id, phone, email)
+VALUES (:name, :address_id, :phone, :email)
+
+-- :name update-elector! :! :n
+-- :doc update an existing elector record
+UPDATE electors
+SET name = :name, address_id = :address_id, phone = :phone, email = :email
+WHERE id = :id
+
+-- :name get-elector :? :1
+-- :doc retrieve a elector given the id.
+SELECT * FROM electors
+WHERE id = :id
+
+-- :name delete-elector! :! :n
+-- :doc delete a elector given the id
+DELETE FROM electors
+WHERE id = :id
+
+
+-- :name create-followupaction! :! :n
+-- :doc creates a new followupaction record
+INSERT INTO followupactions
+(request_id, actor, date, notes, closed)
+VALUES (:request_id, :actor, :date, :notes, :closed)
+
+-- We don't update followup actions. They're permanent record.
+
+-- :name get-followupaction :? :1
+-- :doc retrieve a followupaction given the id.
+SELECT * FROM followupactions
+WHERE id = :id
+
+-- We don't delete followup actions. They're permanent record.
+
+
+-- followup methods are reference data, do not need to be programmatically maintained.
+
+
+-- :name create-followuprequest! :! :n
+-- :doc creates a new followupaction record
+INSERT INTO followuprequests
+(elector_id, visit_id, issue_id, method_id)
+VALUES (:elector_id, :visit_id, :issue_id, :method_id)
+
+-- We don't update followup requests. They're permanent record.
+
+-- :name get-followuprequest :? :1
+-- :doc retrieve a followupaction given the id.
+SELECT * FROM followuprequests
+WHERE id = :id
+
+-- We don't delete followup requests. They're permanent record.
+
+
+-- :name create-issueexpertise! :! :n
+-- :doc creates a new issueexpertise record
+INSERT INTO issueexpertise
+(canvasser_id, issue_id, method_id)
+VALUES (:canvasser_id, :issue_id, :method_id)
+
+-- :name update-issueexpertise! :! :n
+-- :doc update an existing issueexpertise record
+UPDATE issueexpertise
+SET canvasser_id = :canvasser_id, issue_id = :issue_id, method_id = :method_id
+WHERE id = :id
+
+-- :name get-issueexpertise :? :1
+-- :doc retrieve a issueexpertise given the canvasser_id -
+-- getting it by its own id is unlikely to be interesting or useful.
+SELECT * FROM issueexpertise
+WHERE canvasser_id = :canvasser_id
+
+-- :name delete-issueexpertise! :! :n
+-- :doc delete a issueexpertise given the id
+DELETE FROM issueexpertise
+WHERE id = :id
+
+
+-- :name create-issue! :! :n
+-- :doc creates a new issue record
+INSERT INTO issues
+(id, url, content, current)
+VALUES (:id, :url, :content, :current)
+
+-- :name update-issue! :! :n
+-- :doc update an existing issue record
+UPDATE issues
+SET url = :url, content = :content, current = :current
+WHERE id = :id
+
+-- :name get-issue :? :1
+-- :doc retrieve a issue given the id -
+SELECT * FROM issues
+WHERE id = :id
+
+-- :name delete-issue! :! :n
+-- :doc delete a issue given the id
+DELETE FROM issues
+WHERE id = :id
+
+
+-- options is virtually reference data; it's not urgent to create a programmatic means of editing
+
+-- :name create-visit! :! :n
+-- :doc creates a new visit record
+INSERT INTO visits
+(address_id, canvasser_id)
+VALUES (:address_id, :canvasser_id)
+
+-- visits is audit data; we don't update it.
+
+-- :name get-visit :? :1
+-- :doc retrieve a visit given the id.
+SELECT * FROM visits
+WHERE id = :id
+
+-- visits is audit data; we don't delete it.
From 95507002c7fb5e824e0446e0dadef02a59a78da3 Mon Sep 17 00:00:00 2001
From: simon
Date: Wed, 5 Apr 2017 09:56:27 +0100
Subject: [PATCH 03/20] Very rough beginning of making the database stuff work.
---
resources/sql/queries.sql | 28 ++++++++++++++++++++++
src/clj/youyesyet/routes/authenticated.clj | 23 ++++++++++++------
2 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql
index 6dbcae4..29a9d67 100644
--- a/resources/sql/queries.sql
+++ b/resources/sql/queries.sql
@@ -1,3 +1,31 @@
+------------------------------------------------------------------------------;
+----
+---- youyesyet.routes.authenticated: routes and pages for authenticated users.
+----
+---- This program is free software; you can redistribute it and/or
+---- modify it under the terms of the GNU General Public License
+---- as published by the Free Software Foundation; either version 2
+---- of the License, or (at your option) any later version.
+----
+---- This program is distributed in the hope that it will be useful,
+---- but WITHOUT ANY WARRANTY; without even the implied warranty of
+---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+---- GNU General Public License for more details.
+----
+---- You should have received a copy of the GNU General Public License
+---- along with this program; if not, write to the Free Software
+---- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+---- USA.
+----
+---- Copyright (C) 2016 Simon Brooke for Radical Independence Campaign
+----
+------------------------------------------------------------------------------;
+
+-- This file gets slurped in and converted into simple functions by the line
+-- in youyesyet.db.core.clj:
+-- (conman/bind-connection *db* "sql/queries.sql")
+-- the functions then appeare in the youyesyet.db.core namespace.
+
-- :name create-address! :! :n
-- :doc creates a new address record
INSERT INTO addresses
diff --git a/src/clj/youyesyet/routes/authenticated.clj b/src/clj/youyesyet/routes/authenticated.clj
index b5c2644..7e38955 100644
--- a/src/clj/youyesyet/routes/authenticated.clj
+++ b/src/clj/youyesyet/routes/authenticated.clj
@@ -1,12 +1,12 @@
(ns youyesyet.routes.authenticated
- (:require [clojure.walk :refer [keywordize-keys]]
+ (:require [clojure.java.io :as io]
+ [clojure.walk :refer [keywordize-keys]]
+ [compojure.core :refer [defroutes GET POST]]
[noir.response :as nresponse]
[noir.util.route :as route]
- [youyesyet.layout :as layout]
- [youyesyet.db.core :as db-core]
- [compojure.core :refer [defroutes GET POST]]
[ring.util.http-response :as response]
- [clojure.java.io :as io]))
+ [youyesyet.layout :as layout]
+ [youyesyet.db.core :as db]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
@@ -31,5 +31,14 @@
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; (defn roles-page [request]
-;; (if
+;;; This code adapted from http://www.luminusweb.net/docs#accessing_the_database
+
+(defn canvassers-page
+ [request]
+ (if
+ (:params request)
+ (let [params (:params request)]
+ (if (:id params)
+ (db/update-canvasser! params)
+ (db/create-canvasser! params)))))
+
From d534302fd862417732c7dbae0d5b6751ba9b80eb Mon Sep 17 00:00:00 2001
From: simon
Date: Sat, 15 Apr 2017 11:57:17 +0100
Subject: [PATCH 04/20] #5: Progress, but nothing working yet
---
.../20161014170335-basic-setup.up.sql | 21 ++++---
...170401115900-basic-reference-data-down.sql | 0
...170401115900-basic-reference-data.down.sql | 17 ++++++
...0170401115900-basic-reference-data.up.sql} | 2 +-
.../20170415102900-core-views.down.sql | 11 ++++
.../20170415102900-core-views.up.sql | 59 +++++++++++++++++++
resources/sql/queries.sql | 34 +++++++++++
src/clj/youyesyet/handler.clj | 2 +
src/clj/youyesyet/routes/authenticated.clj | 14 ++++-
9 files changed, 148 insertions(+), 12 deletions(-)
delete mode 100644 resources/migrations/20170401115900-basic-reference-data-down.sql
create mode 100644 resources/migrations/20170401115900-basic-reference-data.down.sql
rename resources/migrations/{20170401115900-basic-reference-data-up.sql => 20170401115900-basic-reference-data.up.sql} (97%)
create mode 100644 resources/migrations/20170415102900-core-views.down.sql
create mode 100644 resources/migrations/20170415102900-core-views.up.sql
diff --git a/resources/migrations/20161014170335-basic-setup.up.sql b/resources/migrations/20161014170335-basic-setup.up.sql
index 0719e57..b7b3277 100644
--- a/resources/migrations/20161014170335-basic-setup.up.sql
+++ b/resources/migrations/20161014170335-basic-setup.up.sql
@@ -118,15 +118,16 @@ ALTER TABLE public.authorities OWNER TO youyesyet;
--
CREATE TABLE IF NOT EXISTS canvassers (
- id serial,
- username character varying(32) NOT NULL,
- fullname character varying(64) NOT NULL,
- elector_id integer,
- address_id integer NOT NULL,
- phone character varying(16),
- email character varying(128),
- authority_id character varying(32) NOT NULL,
- authorised boolean
+ id serial,
+ username character varying(32) NOT NULL,
+ fullname character varying(64) NOT NULL,
+ elector_id integer,
+ address_id integer NOT NULL,
+ phone character varying(16),
+ email character varying(128),
+ authority_id character varying(32) NOT NULL,
+ introduced_by int references canvassers(id),
+ authorised boolean
);
--;;
@@ -534,6 +535,8 @@ ALTER TABLE ONLY canvassers
ADD CONSTRAINT canvassers_elector_id_fkey FOREIGN KEY (elector_id) REFERENCES electors(id);
--;;
+create unique index canvassers_username_ix on canvassers (username);
+create unique index canvassers_email_ix on canvassers(email);
--
-- Name: electors_address_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: youyesyet
diff --git a/resources/migrations/20170401115900-basic-reference-data-down.sql b/resources/migrations/20170401115900-basic-reference-data-down.sql
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/migrations/20170401115900-basic-reference-data.down.sql b/resources/migrations/20170401115900-basic-reference-data.down.sql
new file mode 100644
index 0000000..a0b3aa1
--- /dev/null
+++ b/resources/migrations/20170401115900-basic-reference-data.down.sql
@@ -0,0 +1,17 @@
+-- this is just a teardown of everything set up in the corresponding .up.sql file
+
+delete from roles where name = 'Expert';
+delete from roles where name = 'Administrator';
+delete from roles where name = 'Recruiter';
+delete from roles where name = 'Organiser';
+delete from roles where name = 'Editor';
+
+alter table issues drop column content;
+alter table issues drop column current;
+
+delete from issues where id = 'Currency';
+delete from issues where id = 'Monarchy';
+delete from issues where id = 'Defence';
+
+delete from options where id = 'Yes';
+delete from options where id = 'No';
diff --git a/resources/migrations/20170401115900-basic-reference-data-up.sql b/resources/migrations/20170401115900-basic-reference-data.up.sql
similarity index 97%
rename from resources/migrations/20170401115900-basic-reference-data-up.sql
rename to resources/migrations/20170401115900-basic-reference-data.up.sql
index 6ca3028..26d3bf1 100644
--- a/resources/migrations/20170401115900-basic-reference-data-up.sql
+++ b/resources/migrations/20170401115900-basic-reference-data.up.sql
@@ -37,7 +37,7 @@ alter table issues add column content varchar(1024);
-- from the system but kept because it may become current again later. Only
-- current issues are shown in the app. Typically not fewer than three and not
-- more than about seven issues should be current at any time.
-alter table issues add column current default false;
+alter table issues add column current boolean default false;
insert into issues (id, content, current) values ('Currency',
'Scotland could keep the Pound, or use the Euro. But we could also set up a new currency of our own.',
diff --git a/resources/migrations/20170415102900-core-views.down.sql b/resources/migrations/20170415102900-core-views.down.sql
new file mode 100644
index 0000000..c576947
--- /dev/null
+++ b/resources/migrations/20170415102900-core-views.down.sql
@@ -0,0 +1,11 @@
+drop view if exists roles_by_canvasser;
+
+drop view if exists teams_by_canvasser;
+
+drop view if exists canvassers_by_team;
+
+drop view if exists canvassers_by_introducer;
+
+drop view if exists teams_by_organiser;
+
+drop view if exists organisers_by_team;
diff --git a/resources/migrations/20170415102900-core-views.up.sql b/resources/migrations/20170415102900-core-views.up.sql
new file mode 100644
index 0000000..53346a6
--- /dev/null
+++ b/resources/migrations/20170415102900-core-views.up.sql
@@ -0,0 +1,59 @@
+
+create view roles_by_canvasser as
+ select canvassers.id as canvasser, roles.name
+ from roles, rolememberships, canvassers
+ where roles.id = rolememberships.role_id
+ and canvassers.id = rolememberships.canvasser_id
+ and canvassers.authorised = true;
+
+create view teams_by_canvasser as
+ select canvassers.id as canvasser, teams.id, teams.name, teams.latitude, teams.longitude
+ from teams, teammemberships, canvassers
+ where teams.id = teammemberships.team_id
+ and canvassers.id = teammemberships.canvasser_id;
+
+create view canvassers_by_team as
+ select teams.id as team,
+ canvassers.id,
+ canvassers.username,
+ canvassers.fullname,
+ canvassers.email,
+ canvassers.phone
+ from teams, teammemberships, canvassers
+ where teams.id = teammemberships.team_id
+ and canvassers.id = teammemberships.canvasser_id
+ and canvassers.authorised = true;
+
+create view canvassers_by_introducer as
+ select introducers.id as introducer,
+ canvassers.id as canvasser,
+ canvassers.username,
+ canvassers.fullname,
+ canvassers.email,
+ canvassers.phone,
+ canvassers.authorised
+ from canvassers, canvassers as introducers
+ where introducers.id = canvassers.introduced_by;
+
+create view teams_by_organiser as
+ select canvassers.id as organiser,
+ teams.id,
+ teams.name,
+ teams.latitude,
+ teams.longitude
+ from teams, teamorganiserships, canvassers
+ where teams.id = teamorganiserships.team_id
+ and canvassers.id = teamorganiserships.canvasser_id
+ and canvassers.authorised = true;
+
+create view organisers_by_team as
+ select teams.id as team,
+ canvassers.id,
+ canvassers.username,
+ canvassers.fullname,
+ canvassers.email,
+ canvassers.phone
+ from teams, teamorganiserships, canvassers
+ where teams.id = teamorganiserships.team_id
+ and canvassers.id = teamorganiserships.canvasser_id
+ and canvassers.authorised = true;
diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql
index 29a9d67..0689475 100644
--- a/resources/sql/queries.sql
+++ b/resources/sql/queries.sql
@@ -239,3 +239,37 @@ SELECT * FROM visits
WHERE id = :id
-- visits is audit data; we don't delete it.
+
+
+-- views are select only
+
+-- :name get-roles-by-canvasser :? :*
+-- :doc Get the role names for the canvasser with the specified id
+select name from roles_by_canvasser
+ where canvasser = :canvasser
+
+-- :name get-teams-by-canvasser :? :*
+-- :doc Get details of the teams which the canvasser with the specified id is member of.
+select * from teams_by_canvasser
+ where canvasser = :canvasser_id
+
+-- :name get-canvassers-by-team :? :*
+-- :doc Get details of all canvassers who are members of the team with the specified id
+select * from canvassers_by_team
+ where team = :team_id
+
+-- :name get-canvassers-by-team :? :*
+-- :doc Get details of all authorised canvassers who are members of this team.
+select * from canvassers_by_introducer
+ where introducer = :introducer_id
+
+-- :name get-teams_by_organiser :? :*
+-- :doc Get details of all the teams organised by the canvasser with the specified id
+select * from teams_by_organiser
+ where organiser = :organiser_id
+
+-- :name get-organisers-by-team :? :*
+-- :doc Get details of all organisers of the team with the specified id
+select * from organisers_by_team
+ where team = :team_id
+
diff --git a/src/clj/youyesyet/handler.clj b/src/clj/youyesyet/handler.clj
index ad5462d..e25b53c 100644
--- a/src/clj/youyesyet/handler.clj
+++ b/src/clj/youyesyet/handler.clj
@@ -1,6 +1,7 @@
(ns youyesyet.handler
(:require [compojure.core :refer [routes wrap-routes]]
[youyesyet.layout :refer [error-page]]
+ [youyesyet.routes.authenticated :refer [authenticated-routes]]
[youyesyet.routes.home :refer [home-routes]]
[youyesyet.routes.oauth :refer [oauth-routes]]
[compojure.route :as route]
@@ -61,6 +62,7 @@
(wrap-routes middleware/wrap-csrf)
(wrap-routes middleware/wrap-formats))
#'oauth-routes
+ #'authenticated-routes
(route/not-found
(:body
(error-page {:status 404
diff --git a/src/clj/youyesyet/routes/authenticated.clj b/src/clj/youyesyet/routes/authenticated.clj
index 7e38955..d0f4d3f 100644
--- a/src/clj/youyesyet/routes/authenticated.clj
+++ b/src/clj/youyesyet/routes/authenticated.clj
@@ -33,12 +33,22 @@
;;; This code adapted from http://www.luminusweb.net/docs#accessing_the_database
-(defn canvassers-page
+(defn canvasser-page
[request]
(if
(:params request)
(let [params (:params request)]
(if (:id params)
(db/update-canvasser! params)
- (db/create-canvasser! params)))))
+ (db/create-canvasser! params))
+ )))
+(defn routing-page
+ "Render the routing page, which offers routes according to the user's roles"
+ []
+ (layout/render "routing.html"))
+
+(defroutes authenticated-routes
+ (GET "/edit-canvasser" request (canvasser-page request))
+ (POST "/edit-canvasser" request (canvasser-page request))
+ (GET "/routing" [] (routing-page)))
From be324e9d064ad273b0be84b8f74a5ac34435d884 Mon Sep 17 00:00:00 2001
From: simon
Date: Sat, 15 Jul 2017 17:49:32 +0100
Subject: [PATCH 05/20] Beginnings of a working role-routing page
(also the first actual database reads)
---
resources/sql/queries.sql | 14 +++++
resources/templates/canvasser.html | 60 ++++++++++++++++++++++
src/clj/youyesyet/routes/authenticated.clj | 29 +++++++++--
src/clj/youyesyet/routes/home.clj | 35 ++++++++++---
4 files changed, 127 insertions(+), 11 deletions(-)
create mode 100644 resources/templates/canvasser.html
diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql
index 0689475..e708a7b 100644
--- a/resources/sql/queries.sql
+++ b/resources/sql/queries.sql
@@ -66,6 +66,10 @@ WHERE id = :id
SELECT * FROM authorities
WHERE id = :id
+-- :name get-authorities :? :0
+-- :doc retrieve all authorities
+SELECT id FROM authorities
+
-- :name delete-authority! :! :n
-- :doc delete a authority given the id
DELETE FROM authorities
@@ -89,6 +93,16 @@ WHERE id = :id
SELECT * FROM canvassers
WHERE id = :id
+-- :name get-canvasser-by-username :? :1
+-- :doc rerieve a canvasser given the username.
+SELECT * FROM canvassers
+WHERE username = :username
+
+-- :name get-canvasser-by-email :? :1
+-- :doc rerieve a canvasser given the email address.
+SELECT * FROM canvassers
+WHERE email = :email
+
-- :name delete-canvasser! :! :n
-- :doc delete a canvasser given the id
DELETE FROM canvassers
diff --git a/resources/templates/canvasser.html b/resources/templates/canvasser.html
new file mode 100644
index 0000000..b223313
--- /dev/null
+++ b/resources/templates/canvasser.html
@@ -0,0 +1,60 @@
+{% extends "base-authenticated.html" %}
+{% block title %}
+{% endblock %}
+{% block content %}
+
+ id serial,
+ username character varying(32) NOT NULL,
+ fullname character varying(64) NOT NULL,
+ elector_id integer,
+ address_id integer NOT NULL,
+ phone character varying(16),
+ email character varying(128),
+ authority_id character varying(32) NOT NULL,
+ introduced_by int references canvassers(id),
+ authorised boolean
+
+
+
+{% endblock %}
diff --git a/src/clj/youyesyet/routes/authenticated.clj b/src/clj/youyesyet/routes/authenticated.clj
index d0f4d3f..e8b1b7b 100644
--- a/src/clj/youyesyet/routes/authenticated.clj
+++ b/src/clj/youyesyet/routes/authenticated.clj
@@ -33,15 +33,34 @@
;;; This code adapted from http://www.luminusweb.net/docs#accessing_the_database
-(defn canvasser-page
+(defn post?
+ "Return true if the argument is a ring request which is a post request"
[request]
- (if
+ true)
+
+(defn canvasser-page
+ "Process this canvasser request, and render the canvasser page"
+ [request]
+ (let [canvasser (if
(:params request)
(let [params (:params request)]
(if (:id params)
- (db/update-canvasser! params)
- (db/create-canvasser! params))
- )))
+ (if (post? request)
+ (db/update-canvasser! params)
+ (db/create-canvasser! params))
+ (db/get-canvasser (:id params)))
+ ))]
+ (layout/render
+ "canvasser.html"
+ {:title (if canvasser
+ (str
+ "Edit canvasser "
+ (:fullname canvasser)
+ " "
+ (:email canvasser))
+ "Add new canvasser")
+ :canvasser canvasser
+ :address (if (:address_id canvasser) (db/get-address (:address_id canvasser)))})))
(defn routing-page
"Render the routing page, which offers routes according to the user's roles"
diff --git a/src/clj/youyesyet/routes/home.clj b/src/clj/youyesyet/routes/home.clj
index 90f2f12..77ef2f0 100644
--- a/src/clj/youyesyet/routes/home.clj
+++ b/src/clj/youyesyet/routes/home.clj
@@ -48,28 +48,51 @@
;; TODO: Issues need to be fetched from the database
:concerns nil})))
+
+(defn roles-page [request]
+ (let
+ [session (:session request)
+ username (:user session)
+ user (if username (db-core/get-canvasser-by-username db-core/*db* {:username username}))
+ roles (if user (db-core/get-roles-by-canvasser db-core/*db* {:canvasser (:id user)}))]
+ (cond
+ roles (layout/render "roles.html"
+ {:title (str "Welcome " (:fullname user))
+ :roles roles})
+ true (assoc (response/found "/login") :session (dissoc session :user))
+ )))
+
+
(defn home-page []
(layout/render "home.html" {:title "You Yes Yet?"}))
+
(defn login-page
"This is very temporary. We're going to do authentication by oauth."
[request]
(let [params (keywordize-keys (:form-params request))
session (:session request)
username (:username params)
+ user (if username (db-core/get-canvasser-by-username db-core/*db* {:username username}))
password (:password params)
- redirect-to (or (:redirect-to params) "app")]
- (if
- (and (= username "test") (= password "test"))
- (do
- (assoc (response/found redirect-to) :session (assoc session :user username)))
- (layout/render "login.html" {:title "Please log in" :redirect-to redirect-to}))))
+ redirect-to (or (:redirect-to params) "roles")]
+ (cond
+ ;; this is obviously, ABSURDLY, insecure. I don't want to put just-about-good-enough,
+ ;; it-will-do-for-now security in place; instead, I want this to be test code only
+ ;; until we have o-auth properly working.
+ (and user (= username password))
+ (assoc (response/found redirect-to) :session (assoc session :user username))
+ user
+ (layout/render "login.html" {:title (str "User " username " is unknown") :redirect-to redirect-to})
+ true
+ (layout/render "login.html" {:title "Please log in" :redirect-to redirect-to}))))
(defroutes home-routes
(GET "/" [] (home-page))
(GET "/home" [] (home-page))
(GET "/about" [] (about-page))
+ (GET "/roles" request (route/restricted (roles-page request)))
(GET "/app" [] (route/restricted (app-page)))
(GET "/call-me" [] (call-me-page nil))
(POST "/call-me" request (call-me-page request))
From 4213f6159c5f2b2513300fd791c0fd653081d085 Mon Sep 17 00:00:00 2001
From: simon
Date: Sat, 15 Jul 2017 17:51:28 +0100
Subject: [PATCH 06/20] #28: only the very beginning of the beginning
Don't even know if this is worth doing - this specification language doesn't yet mean much to me.
---
doc/specification/api.v1.raml | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 doc/specification/api.v1.raml
diff --git a/doc/specification/api.v1.raml b/doc/specification/api.v1.raml
new file mode 100644
index 0000000..44bd043
--- /dev/null
+++ b/doc/specification/api.v1.raml
@@ -0,0 +1,23 @@
+#%RAML 0.8
+ ---
+ title: YouYesYet API
+ baseUri: https://api.yyy.scot/{version}
+ version: v1
+
+
+/canvassers:
+ get:
+ put:
+
+/electors:
+ get:
+ /{id}:
+ get:
+ /{address_id}:
+ get:
+
+# Location isn't a real entity in the database, but it is a means of searching for
+# addresses and electors.
+/location:
+ /{lat}/{long}/{radius}:
+ get:
From 2ce44cc0b89bd118d34526271679941b9bc56729 Mon Sep 17 00:00:00 2001
From: simon
Date: Sat, 15 Jul 2017 19:36:37 +0100
Subject: [PATCH 07/20] Progress...
---
resources/public/css/yyy-site.css | 1 +
resources/templates/app.html | 40 ++++++-------------
resources/templates/base-authenticated.html | 44 ++++++++++++++++++---
resources/templates/login.html | 5 ---
resources/templates/roles.html | 5 ++-
src/clj/youyesyet/routes/home.clj | 6 ++-
6 files changed, 61 insertions(+), 40 deletions(-)
diff --git a/resources/public/css/yyy-site.css b/resources/public/css/yyy-site.css
index 5387c7a..6f9b521 100644
--- a/resources/public/css/yyy-site.css
+++ b/resources/public/css/yyy-site.css
@@ -46,6 +46,7 @@
#nav-menu {
margin: 0;
padding: 0;
+ width: 100%;
}
#nav menu li {
diff --git a/resources/templates/app.html b/resources/templates/app.html
index 5214806..024aa39 100644
--- a/resources/templates/app.html
+++ b/resources/templates/app.html
@@ -1,16 +1,5 @@
-
-
-
-
-
-
-
-
-
- You Yes Yet?
-
-
-
+{% extends "base-authenticated.html" %}
+{% block whole-page %}
@@ -33,21 +22,16 @@
You must enable JavaScript to use the You Yes Yet app.