Trying to understand ordering of routes

77 views
Skip to first unread message

Oliver Mooney

unread,
Aug 21, 2014, 12:43:33 PM8/21/14
to comp...@googlegroups.com
Hi, 

I'm integrating Friend with a set of routes. One route seems to consume the Friend login options even though it's not a Friend route. In detail, the following ordering results in a parameters map of {:user "" :password ""} being supplied to the Friend authentication function, though from the browser's perspective they're being POSTed with the correct values:

(compojure.core/defroutes user-routes
                          (http/GET "/account" req (resp/response (str "Account!..." req)))
                          (http/GET "/summary" req (resp/response (str "Summary!..." req))))

(compojure.core/defroutes ring-app
           ;; user routes
           (compojure.core/context "/user" req (friend/wrap-authorize user-routes #{::user}))

           ;; admin routes
           (http/GET "/admin" req (friend/authorize #{::admin}
                                                    "This page is only visible to administrators..."
                                                    (resp/response (str "Administrate!"))))

           ;; open access routes
           (http/GET "/" {params :params} (resp/response (str params)))
           (http/GET "/login" req (h/html5 pretty-head (pretty-body login-form)))
           (friend/logout (http/ANY "/logout" request (resp/redirect "/")))
           (route/not-found "Unpopulated link."))


(def secured-app
  (compojure.handler/site
    (friend/authenticate ring-app {:credential-fn #(do
                                                    (println (str "Testing user credentials..." %))
                                                    (creds/bcrypt-credential-fn users %))
                                   :workflows     [(workflows/interactive-form)]}))
  )

I've included compojure.core under 'http'. Somewhere along the way the populated parameters list is being cleared from the login form (the auth function receives a map with the right keys and empty values, not an empty map).


Re-arranging the ring-app section of the routes to read

(compojure.core/defroutes ring-app
                          ;; user routes
                          (compojure.core/context "/user" req (friend/wrap-authorize user-routes #{::user}))

                          ;; admin routes
                          (http/GET "/admin" req (friend/authorize #{::admin}
                                                                   "This page is only visible to administrators..."
                                                                   (resp/response (str "Administrate!"))))

                          ;; open access routes
                          (http/GET "/login" req (h/html5 pretty-head (pretty-body login-form)))
                          (friend/logout (http/ANY "/logout" request (resp/redirect "/")))
                          (http/GET "/" {params :params} (resp/response (str params)))
                          (route/not-found "Unpopulated link."))

resolves the issue. The only change is to move the GET "/" handler that just responds with supplied parameters in the body to the second-to-last position.

I understand that each route is tried in turn until one returns non-nil, but I thought that a route of "/" would only match that route. Is it that it matches all routes as the simplest route possible, and ignores subsequent URL segments? E.g. that most general matches should come last?

Thanks,
Oliver.

James Reeves

unread,
Aug 21, 2014, 4:24:27 PM8/21/14
to Compojure
There's nothing obviously wrong that I can see with your code. The position of the "GET /" shouldn't matter.

Could you possibly provide a more complete example in a gist or repo that replicates this issue?

- James



--
You received this message because you are subscribed to the Google Groups "Compojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to compojure+...@googlegroups.com.
To post to this group, send email to comp...@googlegroups.com.
Visit this group at http://groups.google.com/group/compojure.
For more options, visit https://groups.google.com/d/optout.

Oliver Mooney

unread,
Aug 22, 2014, 6:38:10 AM8/22/14
to comp...@googlegroups.com, ja...@booleanknot.com
It's on Github here:

There's not to much more to it, just some additional HTML rendering for the login form using Hiccup. The only namespace with any real content besides  project.clj is friendtest.core, which I've also made a gist of here: 

James Reeves

unread,
Aug 24, 2014, 9:40:21 AM8/24/14
to Compojure
I'm afraid I can't reproduce the behaviour you see, even when I use your friendtest project. Placing the "/" route before "/login" works exactly the same as the other way around.

Perhaps try a "lein clean"? Or even a "git clean"? There may be something in your project directory that's affecting the result. You might also want to check the content of $HOME/.lein/profiles.clj.

- James 

Oliver Mooney

unread,
Aug 27, 2014, 7:41:24 AM8/27/14
to comp...@googlegroups.com, ja...@booleanknot.com
Thanks James, lein clean resolved it. I'm newish to Clojure but presumably that cleans up artifacts from previous builds? I'm not sure what would have been held over given that there was only one .clj file but I can re-arrange the routes without issue now. Thanks for all your work on compojure!

Oliver.

James Reeves

unread,
Aug 27, 2014, 6:30:12 PM8/27/14
to Compojure
Yes, it cleans artifacts from previous builds, including class files in the target directory. Clojure prioritises class files over source files, and under some circumstances this can lead to unintuitive behaviour and strange bugs. If something's happening that you don't think should be able to happen, try a "lein clean" or manually remove the target directory.

- James


On 27 August 2014 12:41, Oliver Mooney <oliver...@gmail.com> wrote:
Thanks James, lein clean resolved it. I'm newish to Clojure but presumably that cleans up artifacts from previous builds? I'm not sure what would have been held over given that there was only one .clj file but I can re-arrange the routes without issue now. Thanks for all your work on compojure!

Oliver.

--
You received this message because you are subscribed to the Google Groups "Compojure" group.
Reply all
Reply to author
Forward
0 new messages