Merge branch 'deny-dupped-relations' into 'master'
Deny dupped relations See merge request ZeusWPI/cat!4
This commit is contained in:
commit
46b5b4df1a
6 changed files with 101 additions and 75 deletions
|
@ -105,7 +105,7 @@
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<header class="card-header">
|
<header class="card-header">
|
||||||
<p class="card-header-title">
|
<p class="card-header-title">
|
||||||
Your cuddles
|
Your hugs
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
@ -114,15 +114,13 @@
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Person 1</th>
|
<th>With</th>
|
||||||
<th>Person 2</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for relation in user-relations %}
|
{% for relation in user-relations %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{relation.name}}</td>
|
<td>{{relation.other_name}}</td>
|
||||||
<td>{{relation.name_2}}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -147,14 +145,14 @@
|
||||||
<div class="select">
|
<div class="select">
|
||||||
<select name="to_id" id="to_id">
|
<select name="to_id" id="to_id">
|
||||||
<option hidden disabled selected value> -- select an option -- </option>
|
<option hidden disabled selected value> -- select an option -- </option>
|
||||||
{% for user in non_requested_users %}
|
{% for user in non_connected_users %}
|
||||||
<option value="{{user.id}}">{{user.name}}</option>
|
<option value="{{user.id}}">{{user.name}}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="button is-link" type="submit" value="Request cuddle!">
|
<input class="button is-link" type="submit" value="Request hug!">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -283,9 +281,9 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<h3 class="title is-3">Cozy cuddles</h3>
|
<h3 class="title is-3">Cozy hugs</h3>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="subtitle is-4">Add cuddle</h3>
|
<h3 class="subtitle is-4">Add hug</h3>
|
||||||
<form action="/relations" method="post">
|
<form action="/relations" method="post">
|
||||||
{% csrf-field %}
|
{% csrf-field %}
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
@ -319,15 +317,15 @@
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Person 1</th>
|
<th>From</th>
|
||||||
<th>Person 2</th>
|
<th>To</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for relation in relations %}
|
{% for relation in relations %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{relation.name}}</td>
|
<td>{{relation.from_name}}</td>
|
||||||
<td>{{relation.name_2}}</td>
|
<td>{{relation.to_name}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -28,6 +28,6 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#view {
|
#view {
|
||||||
height: 600px;
|
height: 550px;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ VALUES (:from_id, :to_id)
|
||||||
|
|
||||||
-- :name get-relations :? :*
|
-- :name get-relations :? :*
|
||||||
-- :doc retrieves all relations
|
-- :doc retrieves all relations
|
||||||
SELECT * FROM relations
|
SELECT u_from.name from_name, u_to.name to_name, from_id, to_id FROM relations
|
||||||
JOIN users u_from on relations.from_id = u_from.id
|
JOIN users u_from on relations.from_id = u_from.id
|
||||||
JOIN users u_to on relations.to_id = u_to.id
|
JOIN users u_to on relations.to_id = u_to.id
|
||||||
|
|
||||||
|
@ -68,6 +68,22 @@ WHERE from_id = :from_id
|
||||||
|
|
||||||
-- :name get-relation-requests-to-user :? :*
|
-- :name get-relation-requests-to-user :? :*
|
||||||
-- :doc retrieves all relations requests send to a user
|
-- :doc retrieves all relations requests send to a user
|
||||||
SELECT rr.id as rr_id, rr.status, u_from.name as from_name FROM relation_requests as rr
|
SELECT rr.id as rr_id, rr.status, u_from.name as from_name, u_from.id as from_id FROM relation_requests as rr
|
||||||
JOIN users u_from on rr.from_id = u_from.id
|
JOIN users u_from on rr.from_id = u_from.id
|
||||||
WHERE to_id = :to_id
|
WHERE to_id = :to_id
|
||||||
|
|
||||||
|
/*
|
||||||
|
COMPLEX QUERIES
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- :name get-connection-existence :? :1
|
||||||
|
-- :doc retrieves all relations-requests or relations between 2 users
|
||||||
|
SELECT count(*) count
|
||||||
|
FROM(
|
||||||
|
SELECT rr.from_id FROM relation_requests rr WHERE rr.from_id = :user_id and rr.to_id = :other_id
|
||||||
|
UNION ALL
|
||||||
|
SELECT rr.to_id FROM relation_requests rr WHERE rr.from_id = :other_id and rr.to_id = :user_id
|
||||||
|
UNION ALL
|
||||||
|
SELECT rel.from_id FROM relations rel WHERE rel.from_id = :user_id and rel.to_id = :other_id
|
||||||
|
UNION ALL
|
||||||
|
SELECT rel.to_id FROM relations rel WHERE rel.from_id = :other_id and rel.to_id = :user_id) x
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
(GET "/relations_zeroed" [] (show-relations)))
|
(GET "/relations_zeroed" [] (show-relations)))
|
||||||
|
|
||||||
(defroutes user-routes
|
(defroutes user-routes
|
||||||
(POST "/relation_request/:id/status" [id & body] (update-relationrequest-status id body)) ; STATUS ENUM: (open, accepted, rejected)
|
(POST "/relation_request/:id/status" [id & body :as req] (update-relationrequest-status id body req)) ; STATUS ENUM: (open, accepted, rejected)
|
||||||
(POST "/request_relation" req (create-relation-request req)))
|
(POST "/request_relation" req (create-relation-request req)))
|
||||||
|
|
||||||
(defroutes oauth-routes
|
(defroutes oauth-routes
|
||||||
|
|
|
@ -15,11 +15,6 @@
|
||||||
(defn- home-page [params]
|
(defn- home-page [params]
|
||||||
(layout/render "home.html" params))
|
(layout/render "home.html" params))
|
||||||
|
|
||||||
(defn- get-relations []
|
|
||||||
(map
|
|
||||||
(fn [relation] (select-keys relation [:name :name_2]))
|
|
||||||
(db/get-relations)))
|
|
||||||
|
|
||||||
(defn- get-users []
|
(defn- get-users []
|
||||||
(db/get-users))
|
(db/get-users))
|
||||||
|
|
||||||
|
@ -30,33 +25,43 @@
|
||||||
|
|
||||||
(defn show-home [req]
|
(defn show-home [req]
|
||||||
(let [users (get-users)
|
(let [users (get-users)
|
||||||
relations (get-relations)
|
relations (db/get-relations)
|
||||||
user (-> (get-in req [:session :user]))
|
user (get-in req [:session :user])
|
||||||
user-relations (when user
|
user-relations (when user
|
||||||
(seq (filter (fn [rel]
|
;; This can probably be compacted to one reduce operation
|
||||||
|
;; -> filter for only our relations, remove our name
|
||||||
|
(->> relations
|
||||||
|
(filter (fn [rel]
|
||||||
(or
|
(or
|
||||||
(= (:name rel) (:name user))
|
(= (:from_name rel) (:name user))
|
||||||
(= (:name_2 rel) (:name user))))
|
(= (:to_name rel) (:name user)))))
|
||||||
relations)))
|
(map (fn [rel] (if (= (:from_name rel) (:name user))
|
||||||
|
(-> rel
|
||||||
|
(assoc :other_name (:to_name rel))
|
||||||
|
(assoc :other_id (:to_id rel)))
|
||||||
|
(-> rel
|
||||||
|
(assoc :other_name (:from_name rel))
|
||||||
|
(assoc :other_id (:from_id rel))))))))
|
||||||
other_users (when user
|
other_users (when user
|
||||||
(seq (filter (fn [usr] (not (= (:id usr) (:id user))))
|
(filter (fn [usr] (not (= (:id usr) (:id user))))
|
||||||
users)))
|
users))
|
||||||
rel-requests-out (seq (db/get-relation-requests-from-user {:from_id (:id user)}))
|
rel-requests-out (db/get-relation-requests-from-user {:from_id (:id user)})
|
||||||
rel-requests-in (seq (db/get-relation-requests-to-user {:to_id (:id user)}))
|
rel-requests-in (db/get-relation-requests-to-user {:to_id (:id user)})
|
||||||
non_requested_users (seq (filter (fn [other-user] (not (some (partial = (:id other-user)) (map :to_id rel-requests-out)))) other_users))]
|
;; This can be done in one SQL query but since we already have the data for the other operations...
|
||||||
|
non_connected_users (filter (fn [other_user] (not (some (partial = (:id other_user))
|
||||||
|
(concat
|
||||||
|
(map :from_id rel-requests-in)
|
||||||
|
(map :to_id rel-requests-out)
|
||||||
|
(map :other_id user-relations)))))
|
||||||
|
other_users)]
|
||||||
(log/debug (str "Session: " (:session req)))
|
(log/debug (str "Session: " (:session req)))
|
||||||
;(log/info (str "Relation requests: \n OUTGOING: " rel-requests-out "\n INCOMING: " rel-requests-in))
|
|
||||||
;(log/info (str "User relations: " user-relations))
|
|
||||||
;(log/info (str "Other Users: " other_users))
|
|
||||||
;(log/info (str "rel reqs out: " rel-requests-out))
|
|
||||||
;(log/info (str "rel reqs out id: " (seq (map :to_id rel-requests-out))))
|
|
||||||
(home-page {:relations relations
|
(home-page {:relations relations
|
||||||
:users users
|
:users users
|
||||||
:user user
|
:user user
|
||||||
:user-relations user-relations
|
:user-relations user-relations
|
||||||
:rel-requests-out rel-requests-out
|
:rel-requests-out rel-requests-out
|
||||||
:rel-requests-in rel-requests-in
|
:rel-requests-in rel-requests-in
|
||||||
:non_requested_users non_requested_users
|
:non_connected_users non_connected_users
|
||||||
:flash (:flash req)})))
|
:flash (:flash req)})))
|
||||||
|
|
||||||
(defn show-relations
|
(defn show-relations
|
||||||
|
@ -85,38 +90,46 @@
|
||||||
:links rels-indexed})))
|
:links rels-indexed})))
|
||||||
|
|
||||||
(defn update-relationrequest-status
|
(defn update-relationrequest-status
|
||||||
[id body]
|
"Updates the status of a relationship request"
|
||||||
(let [rr_id_map {:id id}
|
[id body {:keys [:session]}]
|
||||||
success (cond
|
(let [rr (db/get-relation-request {:id id})]
|
||||||
|
; Check that you are authorized to change this request
|
||||||
|
(if-not (= (:to_id rr) (get-in session [:user :id]))
|
||||||
|
(response/unauthorized "You can only update requests send to you")
|
||||||
|
(if-not (= "open" (:status rr))
|
||||||
|
(response/gone "Request is not open anymore")
|
||||||
|
(let [correct-params?
|
||||||
|
(cond
|
||||||
(contains? body :accept)
|
(contains? body :accept)
|
||||||
(do
|
(do
|
||||||
(let [rr (db/get-relation-request rr_id_map)]
|
(db/create-relation! (select-keys rr [:from_id :to_id]))
|
||||||
(db/create-relation! {:from_id (:from_id rr) :to_id (:to_id rr)}))
|
(db/update-relation-request-status! {:id id :status "accepted"}))
|
||||||
(db/update-relation-request-status! (assoc rr_id_map :status "accepted")))
|
|
||||||
(contains? body :decline)
|
(contains? body :decline)
|
||||||
(db/update-relation-request-status! (assoc rr_id_map :status "declined"))
|
(db/update-relation-request-status! {:id id :status "declined"})
|
||||||
:else false)]
|
:else false)]
|
||||||
(if success
|
(if correct-params?
|
||||||
(response/found "/")
|
(response/found "/")
|
||||||
(response-wrong-parameters))))
|
(response-wrong-parameters)))))))
|
||||||
|
|
||||||
(defn create-relation-request
|
(defn create-relation-request
|
||||||
[req]
|
"Creates a new request, as requests are unidirectional,
|
||||||
(let [data (:params req)
|
this gets denied if there is a request pending or a relation already established"
|
||||||
[err result] (st/validate data request_relation-schema)
|
[{:keys [:params :session :uri]}]
|
||||||
from-id (get-in req [:session :user :id])]
|
(let [[err result] (st/validate params request_relation-schema)
|
||||||
(if (nil? from-id) (response/found (error-page
|
from_id (get-in session [:user :id])
|
||||||
{:status 400
|
to_id (:to_id result)]
|
||||||
:title "No user id found in session"})))
|
(if (= from_id to_id)
|
||||||
(log/debug "Post to " (:uri req) "\n with data " result)
|
(response/unprocessable-entity "Sadly enough, you can't hug yourself :'(")
|
||||||
(if (nil? err)
|
(if-not (nil? err)
|
||||||
|
(response/unprocessable-entity "Incorrect input")
|
||||||
|
(let [count (db/get-connection-existence {:user_id from_id :other_id to_id})]
|
||||||
|
(if-not (= 0 (:count count))
|
||||||
|
(do
|
||||||
|
(log/info "Existing connections found, aborting.")
|
||||||
|
(response/conflict "There is already a request or relation between you and the other user"))
|
||||||
(do
|
(do
|
||||||
(log/debug "Create relation request")
|
(log/debug "Create relation request")
|
||||||
(db/create-relation-request! {:from_id from-id
|
(db/create-relation-request! {:from_id from_id
|
||||||
:to_id (:to_id result)
|
:to_id to_id
|
||||||
:status "open"})
|
:status "open"})
|
||||||
(response/found "/"))
|
(response/found "/"))))))))
|
||||||
(do
|
|
||||||
(log/debug "Relation request failed")
|
|
||||||
(log/debug err)
|
|
||||||
(response/unprocessable-entity "Incorrect input")))))
|
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
(cond-> (some (partial = (select-keys user [:zeusid :name])) admins)
|
(cond-> (some (partial = (select-keys user [:zeusid :name])) admins)
|
||||||
(->
|
(->
|
||||||
(assoc-in [:user :admin] {:enabled false})
|
(assoc-in [:user :admin] {:enabled false})
|
||||||
(assoc-in [:user :roles] #{:admin})
|
(assoc-in [:user :roles] #{:admin}))))]
|
||||||
(assoc :identity "foo"))))]
|
|
||||||
(-> (found redirect-url)
|
(-> (found redirect-url)
|
||||||
(assoc :session new-session))))
|
(assoc :session new-session))))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue