       (assoc :session {})))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Authentication                                   ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(def authdata
+  "Global var that stores valid users with their
+   respective passwords."
+  {:admin "secret"
+   :test "secret"})
+
+;; Authentication Handler
+;; Used to respond to POST requests to /login.
+
+(defn login-authenticate
+  "Check request username and password against authdata username and passwords.
+  On successful authentication, set appropriate user into the session and
+  redirect to the value of (:query-params (:next request)).
+  On failed authentication, renders the login page."
+  [request]
+  (let [username (get-in request [:form-params "username"])
+        password (get-in request [:form-params "password"])
+        session (:session request)
+        found-password (get authdata (keyword username))]
+    (if (= found-password password)
+      (let [next-url (get-in request [:query-params :next] "/")
+            updated-session (assoc session :identity (keyword username))]
+        (-> (redirect next-url)
+            (assoc :session updated-session)))
+      (render (slurp (io/resource "login.html")) request))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Routes and Middlewares                           ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 ;; User defined application routes using compojure routing library.
-;; Note: no any middleware for authorization, all authorization system
-;; is totally decoupled from main routes.
+;; Note: We do not use middleware for authorization, all of the authorization
+;; system is decoupled from main routes.
 
 (defroutes app
   (GET "/" [] home)

    (authenticated? request)
    (-> (render (slurp (io/resource "error.html")) request)
        (assoc :status 403))

    ;; In other cases, redirect it user to login.
    :else
    (let [current-url (:uri request)]
      (redirect (format "/login?next=%s" current-url)))))


;; Create an instance of auth backend.


    (throw-unauthorized)
    (response (slurp (io/resource "index.html")))))

;; Login page controller
;; It returns a login page on get requests.

