Examples of aget (multi-dimensional) and make-array

2014-05-17 Thread Colin Kahn
Interested in seeing an example of how to use aget on a multi-dimensional 
array, and how to use make-array. So far I've had no luck getting either to 
work.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Looking for help with a Stack Overflow error

2014-05-17 Thread Karsten Schmidt
Hi Brad, I can't help you with your solution, but just wanted to mention
that the core.logic library might be a great tool for this kind of problem
(plus I'd be v.interested in seeing a solution using this myself... :)

K.
On 16 May 2014 22:15, "Brad Kurtz"  wrote:

> I have since fixed the original stack overflow error I was getting, it was
> a result of not using "recur". However, I'm still trying to find the best
> way to actually iterate through the permutations to find the result...
>
> On Friday, May 16, 2014 2:31:26 PM UTC-5, Brad Kurtz wrote:
>>
>> I'm pretty new to Clojure so I'm trying out simple examples to see if I
>> can get myself in the functional programming/Lisp mindset. My team lead
>> sends out puzzles from his Mensa calendar, and every once in a while I find
>> one that seems fun to solve as a Clojure program.
>>
>> With this particular puzzle, I've tried a couple of different ways of
>> "solving" the puzzle, and I decided to try a recursive function. I'm fairly
>> certain that what I've done here is not anywhere near ideal, and I'm
>> looking for insight into how to better write this solution.
>>
>> Also, with my latest attempt I seem to be getting a stack overflow error,
>> and I'm not quite sure why. I'm pretty sure it has to do with the
>> permutation sequence (it's basically 10 factorial, or around 3 million
>> sequences), but I don't really know how to better represent this problem in
>> Clojure. Can anyone help? Thanks!
>>
>> https://github.com/bradkurtz/clojure-puzzles/tree/master/billiards
>>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Examples of aget (multi-dimensional) and make-array

2014-05-17 Thread Frank Castellucci
As per the 
documentation http://clojuredocs.org/clojure_core/clojure.core/make-array 
you use this to collect Java Class types into an array.

Remember that a make-array return is a mutable type.

For example,  a string in clojure is backed by java's String class. If you 
want to make a 3 member array of Strings:

(def _ma (make-array String 3))

=> (aset _ma 0 "Foo")

"Foo"

=> _ma

#

=> (aget _ma 0)

"Foo"


However, in your case of wanting to use a multi-dimensional you could use 
"to-array-2d" http://clojuredocs.org/clojure_core/clojure.core/to-array-2d 
which
has examples.



On Saturday, May 17, 2014 4:03:03 AM UTC-4, Colin Kahn wrote:
>
> Interested in seeing an example of how to use aget on a multi-dimensional 
> array, and how to use make-array. So far I've had no luck getting either to 
> work.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Looking for help with a Stack Overflow error

2014-05-17 Thread Rob Day

A better approach might be to break it down into three groups:

* The first three numbers (rows 1 and 2), constrained by rule D
* The middle three numbers (row 3), constrained by rule A
* The last four numbers (row 4), constrained by rule E

There are only 10!/7! or 10!/6! initial possibilities for each group, so 
it's much quicker to apply the constraints, and the constraints reduce 
the problem space significantly - only 53 of the original 720 
possibilities satisfy rule D, 4 of the original 720 satisfy rule A, and 
~3000 of the initial 5040 satisfy rule E. At this point, you've run less 
than 7000 checks, but you've reduced your pool of possible solutions 
from 10! (~3,600,000) to ~600,000.


You can then combine those three groups together (to get the possible 
arrangements of all 10 balls), and run a filter to verify that no 
numbers are repeated (e.g. that you aren't combining a solution to the 
first three balls that uses 1 with a solution to the last four balls 
that uses 1 - this step takes it down to about 900 possible answers). 
Then just filter on rules B and C to get the answer. I've got this 
running in about 160ms (though admittedly in Haskell).


There's probably a name for this technique - constraint propagation? - 
but I'll leave it to the formally trained to comment. The slowest step 
is almost certainly discarding repeated solutions - that runs over 
600,000 possible permutations and discards 599,000 of them - so if 
anyone has ideas on how to not generate so many duplicate numbers, that 
would be great.


On 17/05/14 00:15, Brad Kurtz wrote:
I have since fixed the original stack overflow error I was getting, it 
was a result of not using "recur". However, I'm still trying to find 
the best way to actually iterate through the permutations to find the 
result...


On Friday, May 16, 2014 2:31:26 PM UTC-5, Brad Kurtz wrote:

I'm pretty new to Clojure so I'm trying out simple examples to see
if I can get myself in the functional programming/Lisp mindset. My
team lead sends out puzzles from his Mensa calendar, and every
once in a while I find one that seems fun to solve as a Clojure
program.

With this particular puzzle, I've tried a couple of different ways
of "solving" the puzzle, and I decided to try a recursive
function. I'm fairly certain that what I've done here is not
anywhere near ideal, and I'm looking for insight into how to
better write this solution.

Also, with my latest attempt I seem to be getting a stack overflow
error, and I'm not quite sure why. I'm pretty sure it has to do
with the permutation sequence (it's basically 10 factorial, or
around 3 million sequences), but I don't really know how to better
represent this problem in Clojure. Can anyone help? Thanks!

https://github.com/bradkurtz/clojure-puzzles/tree/master/billiards


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google 
Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to clojure+unsubscr...@googlegroups.com 
.

For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups "Clojure" group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Advice on data structure communication and awareness

2014-05-17 Thread Mike Fikes
I've never used a dynamically-typed language and an issue I've encountered 
with Clojure is a difficulty with readily "seeing" the data structures 
being consumed or returned by functions I'm writing, especially when I come 
back to them several days later and if those structures get to be somewhat 
nested or otherwise complex.

As a small concrete example, lets say that I currently have a function that 
accepts data that looks like {:a "A" :b "B"} and, at some point I change 
the internals of the function to instead operate on data that looks like 
[[:a "A"] [:b "B"]].

I could see the docstring communicating that the initial implementation of 
the function accepts a map, and then perhaps it boils down to finding 
suitable language to describe the structure in the revised implementation 
("sequence of pairs", "relation", or some other language suitable to the 
abstraction).

I suppose this is no different than the "documentation" aspect that 
generics provided in Java when we went from raw types like List to 
List, but, of course, generics can get unwieldy rather quickly with 
things like List>>.

Does there exist idiomatic language that developers employ in their 
docstrings to quickly convey this kind of info? I see that the docstrings 
for clojure.core are fairly readable, but they tend to operate on very 
simple data structures.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[ANN] ring-auth middleware for protecting sessions

2014-05-17 Thread Brendan Younger
Hi all,

In light of Aaron Bedra's 
talkat
 Clojure/West this past March on the (lack of) security in Clojure 
webapps, I've written a small, easy-to-understand middleware for keeping 
your authenticated session secure.  

Ring-auth aims to implement all the recommendations from OWASP about secure 
session storage while at the same time not putting undue constraints on how 
you architect your app.  Just place authentication information in an 
:auth-session key in your ring responses and you're all set.

Check it out at: https://github.com/brendanyounger/ring-auth

Brendan Younger


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Looking for help with a Stack Overflow error

2014-05-17 Thread Gary Verhaegen
I'd suggest taking a look at the following blog post:
http://programming-puzzler.blogspot.be/2013/03/logic-programming-is-overrated.html

(The ensuing discussion between David and Mark is also worth reading.)

On 17 May 2014 14:49, Rob Day  wrote:
> A better approach might be to break it down into three groups:
>
> * The first three numbers (rows 1 and 2), constrained by rule D
> * The middle three numbers (row 3), constrained by rule A
> * The last four numbers (row 4), constrained by rule E
>
> There are only 10!/7! or 10!/6! initial possibilities for each group, so
> it's much quicker to apply the constraints, and the constraints reduce the
> problem space significantly - only 53 of the original 720 possibilities
> satisfy rule D, 4 of the original 720 satisfy rule A, and ~3000 of the
> initial 5040 satisfy rule E. At this point, you've run less than 7000
> checks, but you've reduced your pool of possible solutions from 10!
> (~3,600,000) to ~600,000.
>
> You can then combine those three groups together (to get the possible
> arrangements of all 10 balls), and run a filter to verify that no numbers
> are repeated (e.g. that you aren't combining a solution to the first three
> balls that uses 1 with a solution to the last four balls that uses 1 - this
> step takes it down to about 900 possible answers). Then just filter on rules
> B and C to get the answer. I've got this running in about 160ms (though
> admittedly in Haskell).
>
> There's probably a name for this technique - constraint propagation? - but
> I'll leave it to the formally trained to comment. The slowest step is almost
> certainly discarding repeated solutions - that runs over 600,000 possible
> permutations and discards 599,000 of them - so if anyone has ideas on how to
> not generate so many duplicate numbers, that would be great.
>
> On 17/05/14 00:15, Brad Kurtz wrote:
>
> I have since fixed the original stack overflow error I was getting, it was a
> result of not using "recur". However, I'm still trying to find the best way
> to actually iterate through the permutations to find the result...
>
> On Friday, May 16, 2014 2:31:26 PM UTC-5, Brad Kurtz wrote:
>>
>> I'm pretty new to Clojure so I'm trying out simple examples to see if I
>> can get myself in the functional programming/Lisp mindset. My team lead
>> sends out puzzles from his Mensa calendar, and every once in a while I find
>> one that seems fun to solve as a Clojure program.
>>
>> With this particular puzzle, I've tried a couple of different ways of
>> "solving" the puzzle, and I decided to try a recursive function. I'm fairly
>> certain that what I've done here is not anywhere near ideal, and I'm looking
>> for insight into how to better write this solution.
>>
>> Also, with my latest attempt I seem to be getting a stack overflow error,
>> and I'm not quite sure why. I'm pretty sure it has to do with the
>> permutation sequence (it's basically 10 factorial, or around 3 million
>> sequences), but I don't really know how to better represent this problem in
>> Clojure. Can anyone help? Thanks!
>>
>> https://github.com/bradkurtz/clojure-puzzles/tree/master/billiards
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojur

Re: [ANN] ring-auth middleware for protecting sessions

2014-05-17 Thread James Reeves
Hi Brendan,

This sort of work is very much appreciated, but since this involves
security, I hope you won't mind if I make a few criticisms.

When dealing with security, it's extremely important that you don't
re-implement existing functionality without good reason. A large part of
avoiding security flaws is minimising the surface area of code exposed to
attackers.

In your library, you re-implement a lot of the functionality that already
exists in the standard Ring session middleware. There's no reason for this.
You could implement all the functionality in :auth-session as middleware
that sits on top of the standard Ring middleware.

You have a :csrf-token option for wrap-auth-session, but you do nothing
with it. Hopefully you won't implement your own anti-CSRF middleware, but
instead use the standard ring-anti-forgery library.

A lot of the functionality of your code could be boiled down to:

(defn wrap-secure-sessions [handler]
  (fn [request]
(if (and (:session request) (insecure-session? request))
  (-> request request-url redirect (assoc :session nil))
  (handler response


Where the "insecure-session?" function makes a decision as to whether the
session is too old, or has been accessed over HTTP rather than HTTPS.

However, all this is a moot point, as there are better ways of achieving
the same functionality.

The session store itself should be expiring sessions, rather than the
session middleware, as the middleware can only expire sessions it's
currently being accessed by. If you rely on middleware to expire sessions
as they come in, you'll build up a backlog of sessions from visitors who
will never return to your site.

For HTTPS sessions, the "Secure" flag should be set on the session cookies,
which means that the browser will never send the cookie over HTTP,
therefore making it unnecessary to delete sessions over insecure
connections. Ideally you want both :secure and :http-only to ensure that
the cookie is only delivered to your server over a secure connection.

- James


On 17 May 2014 17:18, Brendan Younger  wrote:

> Hi all,
>
> In light of Aaron Bedra's 
> talkat
>  Clojure/West this past March on the (lack of) security in Clojure
> webapps, I've written a small, easy-to-understand middleware for keeping
> your authenticated session secure.
>
> Ring-auth aims to implement all the recommendations from OWASP about
> secure session storage while at the same time not putting undue constraints
> on how you architect your app.  Just place authentication information in an
> :auth-session key in your ring responses and you're all set.
>
> Check it out at: https://github.com/brendanyounger/ring-auth
>
> Brendan Younger
>
>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Advice on data structure communication and awareness

2014-05-17 Thread Jace Bennett
There were a number of talks at the Conj that spoke directly to this
challenge. One of the approaches I liked was Prismatic's schema.

https://github.com/Prismatic/schema

And here's Aria's talk on it, since he can explain it better than I.

https://www.youtube.com/watch?v=o_jtwIs2Ot8



On Sat, May 17, 2014 at 10:22 AM, Mike Fikes  wrote:

> I've never used a dynamically-typed language and an issue I've encountered
> with Clojure is a difficulty with readily "seeing" the data structures
> being consumed or returned by functions I'm writing, especially when I come
> back to them several days later and if those structures get to be somewhat
> nested or otherwise complex.
>
> As a small concrete example, lets say that I currently have a function
> that accepts data that looks like {:a "A" :b "B"} and, at some point I
> change the internals of the function to instead operate on data that looks
> like [[:a "A"] [:b "B"]].
>
> I could see the docstring communicating that the initial implementation of
> the function accepts a map, and then perhaps it boils down to finding
> suitable language to describe the structure in the revised implementation
> ("sequence of pairs", "relation", or some other language suitable to the
> abstraction).
>
> I suppose this is no different than the "documentation" aspect that
> generics provided in Java when we went from raw types like List to
> List, but, of course, generics can get unwieldy rather quickly with
> things like List>>.
>
> Does there exist idiomatic language that developers employ in their
> docstrings to quickly convey this kind of info? I see that the docstrings
> for clojure.core are fairly readable, but they tend to operate on very
> simple data structures.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Examples of aget (multi-dimensional) and make-array

2014-05-17 Thread Colin Kahn
Thanks for the answer Frank. Actually this was my mistake, I was looking 
for how to do this using Clojurescript thinking this was the Clojurescript 
group.

On Saturday, May 17, 2014 2:30:09 AM UTC-7, Frank Castellucci wrote:
>
> As per the documentation 
> http://clojuredocs.org/clojure_core/clojure.core/make-array you use this 
> to collect Java Class types into an array.
>
> Remember that a make-array return is a mutable type.
>
> For example,  a string in clojure is backed by java's String class. If you 
> want to make a 3 member array of Strings:
>
> (def _ma (make-array String 3))
>
> => (aset _ma 0 "Foo")
>
> "Foo"
>
> => _ma
>
> #
>
> => (aget _ma 0)
>
> "Foo"
>
>
> However, in your case of wanting to use a multi-dimensional you could use 
> "to-array-2d" 
> http://clojuredocs.org/clojure_core/clojure.core/to-array-2dwhich
> has examples.
>
>
>
> On Saturday, May 17, 2014 4:03:03 AM UTC-4, Colin Kahn wrote:
>>
>> Interested in seeing an example of how to use aget on a multi-dimensional 
>> array, and how to use make-array. So far I've had no luck getting either to 
>> work.
>>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Advice on data structure communication and awareness

2014-05-17 Thread James Reeves
I've been toying around with the idea of type signatures that exist
specifically for documentation purposes, loosely inspired by the stack
effect declarations in Factor.

For example, in your case we might start with something like:

(defn count-items
  {:doc/type '([{Keyword String} -> Integer])}
  [m])

And then change it to:

(defn count-items
  {:doc/type '([[& [Keyword String]] -> Integer])}
  [m])

This might produce docs like:

  (count-items {Keyword String}) → Integer

  (count-items [& [Keyword String]]) → Integer

Or for more standard functions:

  (assoc {k v} k v) → {k v}

  (get {k v} k) → v

As you can probably tell, these type definitions wouldn't be sufficient for
core.typed or even Prismatic's schema. Their purpose would be purely to
give end users an approximate understanding of the function at a glance.

I've yet to completely sell myself on this idea, however.

- James


On 17 May 2014 15:22, Mike Fikes  wrote:

> I've never used a dynamically-typed language and an issue I've encountered
> with Clojure is a difficulty with readily "seeing" the data structures
> being consumed or returned by functions I'm writing, especially when I come
> back to them several days later and if those structures get to be somewhat
> nested or otherwise complex.
>
> As a small concrete example, lets say that I currently have a function
> that accepts data that looks like {:a "A" :b "B"} and, at some point I
> change the internals of the function to instead operate on data that looks
> like [[:a "A"] [:b "B"]].
>
> I could see the docstring communicating that the initial implementation of
> the function accepts a map, and then perhaps it boils down to finding
> suitable language to describe the structure in the revised implementation
> ("sequence of pairs", "relation", or some other language suitable to the
> abstraction).
>
> I suppose this is no different than the "documentation" aspect that
> generics provided in Java when we went from raw types like List to
> List, but, of course, generics can get unwieldy rather quickly with
> things like List>>.
>
> Does there exist idiomatic language that developers employ in their
> docstrings to quickly convey this kind of info? I see that the docstrings
> for clojure.core are fairly readable, but they tend to operate on very
> simple data structures.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [ANN] clojure.test.check 0.5.8

2014-05-17 Thread Reid Draper

On May 15, 2014, at 2:08 PM, Steve Miner  wrote:

> I'm generating generators from schemas [1].  I have generators for all my 
> simple schemas -- "int" corresponds to gen/int, etc.  The tougher case is 
> when I have to convert a conjunction of schema expressions into a generator. 
> For example, a schema (and int pos) specifies a positive integer, essentially 
> like testing (fn [x] (and (integer? x) (pos? x)).  
> 
> My current implementation finds some element of the AND that I can map to a 
> generator and uses such-that to filter against a predicate created from the 
> rest of the AND elements.
> 
> A simple example does something like this...
> 
> (make-generator '(and int pos odd))
> --->  (gen/such-that (make-predicate '(and pos odd)) (make-generator 'int))
> --->  (gen/such-that (fn [x] (and (pos? x) (odd? x))) gen/int)
> 
> Of course, it would be better to use gen/s-pos-int.  I'm thinking that I need 
> to look for a few common combinations of simple schemas, especially if 
> there's already a good generator for those cases.
> 
> However, I still need to try to handle the general case, and it looks like 
> the such-that approach will have to be my fallback position.  I'll probably 
> give the user the option of adding custom generators to match more 
> complicated schema expressions.

Yes, I think you're thinking about this correctly. And in some cases, you may 
be better off just wasting some CPU cycles and using such-that, just like you 
are. It really depends on how complex you want your library to be.

> 
> Now, if you could provide an efficient AND generator combinator, that would 
> solve all my problems.  :-)

I'll give this some thought :)

> 
> It occurs to me that automatically deriving generators is something like 
> running a predicate backwards so maybe there's a way to do it with 
> core.logic, but I haven't tried to do that yet.

Let me know how this goes.

Reid

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Advice on data structure communication and awareness

2014-05-17 Thread Sam Ritchie

Check out Prismatic's schema:

https://github.com/Prismatic/schema

With validation turned off that's exactly what the library provides.


James Reeves 
May 17, 2014 11:42 AM
I've been toying around with the idea of type signatures that exist 
specifically for documentation purposes, loosely inspired by the stack 
effect declarations in Factor.


For example, in your case we might start with something like:

(defn count-items
  {:doc/type '([{Keyword String} -> Integer])}
  [m])

And then change it to:

(defn count-items
  {:doc/type '([[& [Keyword String]] -> Integer])}
  [m])

This might produce docs like:

  (count-items {Keyword String}) → Integer

  (count-items [& [Keyword String]]) → Integer

Or for more standard functions:

  (assoc {k v} k v) → {k v}

  (get {k v} k) → v

As you can probably tell, these type definitions wouldn't be 
sufficient for core.typed or even Prismatic's schema. Their purpose 
would be purely to give end users an approximate understanding of the 
function at a glance.


I've yet to completely sell myself on this idea, however.

- James



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google 
Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to clojure+unsubscr...@googlegroups.com 
.

For more options, visit https://groups.google.com/d/optout.
Mike Fikes 
May 17, 2014 8:22 AM
I've never used a dynamically-typed language and an issue I've 
encountered with Clojure is a difficulty with readily "seeing" the 
data structures being consumed or returned by functions I'm writing, 
especially when I come back to them several days later and if those 
structures get to be somewhat nested or otherwise complex.


As a small concrete example, lets say that I currently have a function 
that accepts data that looks like {:a "A" :b "B"} and, at some point I 
change the internals of the function to instead operate on data that 
looks like [[:a "A"] [:b "B"]].


I could see the docstring communicating that the initial 
implementation of the function accepts a map, and then perhaps it 
boils down to finding suitable language to describe the structure in 
the revised implementation ("sequence of pairs", "relation", or some 
other language suitable to the abstraction).


I suppose this is no different than the "documentation" aspect that 
generics provided in Java when we went from raw types like List to 
List, but, of course, generics can get unwieldy rather quickly 
with things like List>>.


Does there exist idiomatic language that developers employ in their 
docstrings to quickly convey this kind of info? I see that the 
docstrings for clojure.core are fairly readable, but they tend to 
operate on very simple data structures.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google 
Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to clojure+unsubscr...@googlegroups.com 
.

For more options, visit https://groups.google.com/d/optout.


--
Sam Ritchie (@sritchie)
Paddleguru Co-Founder
703.863.8561
www.paddleguru.com 
Twitter // Facebook 



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups "Clojure" group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Advice on data structure communication and awareness

2014-05-17 Thread Sam Ritchie

Ah, sorry, didn't see your reference at the bottom :)

Schema does augment the docs to some degree:

paddleguru.models.transfer/payout!
([regatta balance our-fee their-fee])
  Inputs: [regatta :- regatta/Regatta balance :- graph/Balance our-fee 
:- s/Num their-fee :- s/Num]

  Returns: {:success s/Bool, :message s/Str}

  Performs a payout for the supplied regatta. If either of the
  supplied balances can't be satisfied by current available funds,
  this method returns success false and a message explaining what
  happened. Else, it'll create all transfers and return success and a
  nice note.


James Reeves 
May 17, 2014 11:42 AM
I've been toying around with the idea of type signatures that exist 
specifically for documentation purposes, loosely inspired by the stack 
effect declarations in Factor.


For example, in your case we might start with something like:

(defn count-items
  {:doc/type '([{Keyword String} -> Integer])}
  [m])

And then change it to:

(defn count-items
  {:doc/type '([[& [Keyword String]] -> Integer])}
  [m])

This might produce docs like:

  (count-items {Keyword String}) → Integer

  (count-items [& [Keyword String]]) → Integer

Or for more standard functions:

  (assoc {k v} k v) → {k v}

  (get {k v} k) → v

As you can probably tell, these type definitions wouldn't be 
sufficient for core.typed or even Prismatic's schema. Their purpose 
would be purely to give end users an approximate understanding of the 
function at a glance.


I've yet to completely sell myself on this idea, however.

- James



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google 
Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to clojure+unsubscr...@googlegroups.com 
.

For more options, visit https://groups.google.com/d/optout.
Mike Fikes 
May 17, 2014 8:22 AM
I've never used a dynamically-typed language and an issue I've 
encountered with Clojure is a difficulty with readily "seeing" the 
data structures being consumed or returned by functions I'm writing, 
especially when I come back to them several days later and if those 
structures get to be somewhat nested or otherwise complex.


As a small concrete example, lets say that I currently have a function 
that accepts data that looks like {:a "A" :b "B"} and, at some point I 
change the internals of the function to instead operate on data that 
looks like [[:a "A"] [:b "B"]].


I could see the docstring communicating that the initial 
implementation of the function accepts a map, and then perhaps it 
boils down to finding suitable language to describe the structure in 
the revised implementation ("sequence of pairs", "relation", or some 
other language suitable to the abstraction).


I suppose this is no different than the "documentation" aspect that 
generics provided in Java when we went from raw types like List to 
List, but, of course, generics can get unwieldy rather quickly 
with things like List>>.


Does there exist idiomatic language that developers employ in their 
docstrings to quickly convey this kind of info? I see that the 
docstrings for clojure.core are fairly readable, but they tend to 
operate on very simple data structures.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google 
Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to clojure+unsubscr...@googlegroups.com 
.

For more options, visit https://groups.google.com/d/optout.


--
Sam Ritchie (@sritchie)
Paddleguru Co-Founder
703.863.8561
www.paddleguru.com 
Twitter // Facebook 



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegr

Re: I'm reading the book "Web Development with Clojure...". On page 4 I entered the command 'leon ring server' and it returns an error message: 'ring' is not a task. See 'lein help'.

2014-05-17 Thread Alejandro Ciniglio
http://www.meetup.com/Clojure-NYC/ 

On Friday, May 16, 2014 6:56:01 PM UTC-6, patrick lynch wrote:
>
> ...solved it - if anyone is reading this book - you're going to have to 
> change your $PATH in order to get this to work. 
> ...hope to see you all in the future - if anyone can recommend a Clojure 
> User Group in NY/NJ area please let me know.
> thanks again
>
> On Friday, May 16, 2014 8:09:30 PM UTC-4, Gary Trakhman wrote:
>>
>> you have to be inside the guestbook dir.
>>
>>
>> On Fri, May 16, 2014 at 7:50 PM, patrick lynch wrote:
>>
>>> I'm going thru the book   "Web Development with Clojure...". 
>>> I entered the following commands:
>>>
>>> lein new compojure-app guestbook
>>>
>>> It ran ok.
>>>
>>> I then ran:
>>>
>>> > lein ring server
>>>
>>> It returned the error message:
>>>
>>> 'ring' is not a task. See 'lein help'.
>>>
>>>
>>> Did you mean this?
>>>
>>>  run
>>>
>>> I'd appreciate any help.
>>> Thank you
>>>  
>>> -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> --- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to clojure+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [ANN] ring-auth middleware for protecting sessions

2014-05-17 Thread Brendan Younger
Hi James,

The general point about not unduly duplicating functionality is well taken, 
however, here are the reasons for the choices I made.

Having the ability to keep one insecure session (for anonymous users) and 
one secure, authenticated session is very helpful.  With the standard 
ring.middleware.session, you are restricted to setting the HttpOnly and 
Secure flags on the cookie all the time or never.  This is why I added a 
second :auth-session key.

The :csrf-token is there on purpose since setting it on an insecure 
session, as ring-anti-forgery does, doesn't prevent CSRF attacks since the 
session identifier can still be fixed.  In ring-auth, it's up to the 
application to provide and check the :csrf-token on requests and responses, 
which is not that hard to do.

Sessions can still be expired via the session store, but not all stores 
make it easy to auto-expire them.  Keeping invalidation code in the 
middleware just provides some more defense in-depth.

There are other niceties in ring-auth which are easy to elide when focusing 
on your application logic.  

For instance, the session identifier for the :auth-session is always a 
random UUID rather than allowing the session store to decide what it is. 
 This guards against session stores that might simply auto-increment the 
session identifier and thus be easily guessable.  

Every time the contents of :auth-session are altered, a new session 
identifier is created.  This guards against privilege escalation whereby 
moving from "regular user" -> "admin" would allow a third party with access 
to the "regular user" session identifier to now act as an "admin".

Finally, the logging was placed there for specific reasons.  If you see a 
lot "Unknown auth-id" messages, it's likely that someone is trying to guess 
the session identifiers.  Likewise, seeing "Refusing to set auth session on 
insecure request" means that your code is allowing HTTP on a route that 
should probably be HTTPS-only and you should look into your routing logic. 
 I think it's helpful to have predictable mistakes called out like this.

I do, of course, owe a great debt to yourself and other who have provided 
so much of the plumbing in Ring and the associated libraries.  However, 
right now it's too hard to implement all the OWASP best practices for 
session storage and CSRF protection and be sure that you didn't miss 
something or misconfigure one of the middleware libraries.  Ring-auth is 
meant to eliminate the worry of inadequate configuration.

Brendan

On Saturday, May 17, 2014 1:04:09 PM UTC-4, James Reeves wrote:
>
> Hi Brendan,
>
> This sort of work is very much appreciated, but since this involves 
> security, I hope you won't mind if I make a few criticisms.
>
> When dealing with security, it's extremely important that you don't 
> re-implement existing functionality without good reason. A large part of 
> avoiding security flaws is minimising the surface area of code exposed to 
> attackers.
>
> In your library, you re-implement a lot of the functionality that already 
> exists in the standard Ring session middleware. There's no reason for this. 
> You could implement all the functionality in :auth-session as middleware 
> that sits on top of the standard Ring middleware.
>
> You have a :csrf-token option for wrap-auth-session, but you do nothing 
> with it. Hopefully you won't implement your own anti-CSRF middleware, but 
> instead use the standard ring-anti-forgery library.
>
> A lot of the functionality of your code could be boiled down to:
>
> (defn wrap-secure-sessions [handler]
>   (fn [request]
> (if (and (:session request) (insecure-session? request))
>   (-> request request-url redirect (assoc :session nil))
>   (handler response
>
>
> Where the "insecure-session?" function makes a decision as to whether the 
> session is too old, or has been accessed over HTTP rather than HTTPS.
>
> However, all this is a moot point, as there are better ways of achieving 
> the same functionality.
>
> The session store itself should be expiring sessions, rather than the 
> session middleware, as the middleware can only expire sessions it's 
> currently being accessed by. If you rely on middleware to expire sessions 
> as they come in, you'll build up a backlog of sessions from visitors who 
> will never return to your site.
>
> For HTTPS sessions, the "Secure" flag should be set on the session 
> cookies, which means that the browser will never send the cookie over HTTP, 
> therefore making it unnecessary to delete sessions over insecure 
> connections. Ideally you want both :secure and :http-only to ensure that 
> the cookie is only delivered to your server over a secure connection.
>
> - James
>
>
> On 17 May 2014 17:18, Brendan Younger  >wrote:
>
>> Hi all,
>>
>> In light of Aaron Bedra's 
>> talkat
>>  Clojure/West this past March on the (lack of) security in Cl

Re: [ANN] ring-auth middleware for protecting sessions

2014-05-17 Thread James Reeves
On 17 May 2014 20:04, Brendan Younger  wrote:

>
> Having the ability to keep one insecure session (for anonymous users) and
> one secure, authenticated session is very helpful.  With the standard
> ring.middleware.session, you are restricted to setting the HttpOnly and
> Secure flags on the cookie all the time or never.  This is why I added a
> second :auth-session key.
>

You could just choose different wrap-session options depending on whether
the user is authenticated or not. Middleware options don't need to be fixed
at compile-time.


> The :csrf-token is there on purpose since setting it on an insecure
> session, as ring-anti-forgery does, doesn't prevent CSRF attacks since the
> session identifier can still be fixed.  In ring-auth, it's up to the
> application to provide and check the :csrf-token on requests and responses,
> which is not that hard to do.
>

I'm not sure I follow. Even over HTTP, it shouldn't be possible for an
attacker to read anything in the session itself. Only the server can read
session information.


> Sessions can still be expired via the session store, but not all stores
> make it easy to auto-expire them.  Keeping invalidation code in the
> middleware just provides some more defense in-depth.
>

If the session store doesn't have expiry mechanisms, then the session store
is broken.


> There are other niceties in ring-auth which are easy to elide when
> focusing on your application logic.
>
> For instance, the session identifier for the :auth-session is always a
> random UUID rather than allowing the session store to decide what it is.
>  This guards against session stores that might simply auto-increment the
> session identifier and thus be easily guessable.
>

If the session key is easily guessable, then the session store is
completely broken and needs to be immediately replaced.

The problem is that you're adding code that only has benefit if another
part of the system is broken in some major way. If the session store is not
broken, all your code is doing is adding complexity for no benefit.

Rather than use wrap-auth-session, it seems like a better idea just to
check that the session store you're using is in working order.

Every time the contents of :auth-session are altered, a new session
> identifier is created.  This guards against privilege escalation whereby
> moving from "regular user" -> "admin" would allow a third party with access
> to the "regular user" session identifier to now act as an "admin".
>

Middleware that clears the session if on changing privileges might be
useful, but I'd suggest this be separate middleware.


> Finally, the logging was placed there for specific reasons.  If you see a
> lot "Unknown auth-id" messages, it's likely that someone is trying to guess
> the session identifiers.  Likewise, seeing "Refusing to set auth session on
> insecure request" means that your code is allowing HTTP on a route that
> should probably be HTTPS-only and you should look into your routing logic.
>  I think it's helpful to have predictable mistakes called out like this.
>

Middleware that passively looks for signs of attack could be useful. Again,
this seems more useful as separate middleware.


> I do, of course, owe a great debt to yourself and other who have provided
> so much of the plumbing in Ring and the associated libraries.  However,
> right now it's too hard to implement all the OWASP best practices for
> session storage and CSRF protection and be sure that you didn't miss
> something or misconfigure one of the middleware libraries.  Ring-auth is
> meant to eliminate the worry of inadequate configuration.
>

It's a laudable goal, but I really don't think your current middleware
design achieves that. I'm usually not this critical, but when it comes to
security it's important to get things right.

Ring best practice for sessions is as follows:

   - Sessions over HTTPS should be flagged as Secure
   - If you really must have sessions over HTTP and HTTPS, they should be
   in different cookies
   - The session store should use unpredictable identifiers for keys
   - The session store should handle expiry of old sessions

I'd welcome middleware that lints the session, i.e. makes sure your cookies
are right.

I'd also welcome more session stores that follow proper security.

Middleware that passively looks for signs of brute force attacks and
delivers warnings would be useful.

But I don't think the ring-auth middleware takes the right approach. It's
*maybe* better than nothing, but it doesn't follow best practice, and isn't
something I could recommend using in its current state. There are some good
ideas in there, but it's mixed in with functionality that has better
existing solutions.

- James

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe 

Re: [ANN] ring-auth middleware for protecting sessions

2014-05-17 Thread Brendan Younger
For anyone else following along at home, I'll just re-iterate the benefits 
of using ring-auth versus trying to write your routes *just right* to avoid 
the myriad security issues listed at OWASP.

- If you initiate a session with a user over HTTP and later on that user 
logs in over HTTPS but you don't change the session id in the cookie, then 
everyone at the coffee shop has access to the authenticated session. 
 Ring-auth protects you from this.

- If you use a CSRF middleware, but at any time leak the session id cookie 
over HTTP, then your CSRF protection is broken.  Ring-auth protects you 
from this.

- If you ever send your CSRF token over HTTP, then the entire coffee shop 
can entice the user to "Click here now!" and send money to their off-shore 
account.  Ring-auth helps you avoid sending the CSRF token in the clear.

- If you get a request over HTTP which should have gone over HTTPS and 
respond with an error, but don't immediately delete the session, then 
everyone at the coffee shop has seen the authenticated session id (assuming 
you forgot to set Secure).  Ring-auth protects you from this.

- If a user closes their browser on a public computer but forgets to sign 
off, the next user can go back to the site, and hopefully the browser has 
cached the cookie giving them access to the first user's account. 
 Ring-auth will help prevent this as soon as the "Cache-Control" header is 
set.

- Not to mention the helpful errors that try to help you develop secure 
routes with warnings when you're doing something obviously insecure.

None of these things come out-of-the-box with Ring's wrap-session, even 
with {:secure true} set.

Read it, it's only a few dozen lines of code, and please let me know if you 
put it into use and need more features.

Brendan

On Saturday, May 17, 2014 4:22:34 PM UTC-4, James Reeves wrote:
>
> On 17 May 2014 20:04, Brendan Younger  >wrote:
>
>>
>> Having the ability to keep one insecure session (for anonymous users) and 
>> one secure, authenticated session is very helpful.  With the standard 
>> ring.middleware.session, you are restricted to setting the HttpOnly and 
>> Secure flags on the cookie all the time or never.  This is why I added a 
>> second :auth-session key.
>>
>
> You could just choose different wrap-session options depending on whether 
> the user is authenticated or not. Middleware options don't need to be fixed 
> at compile-time.
>  
>
>> The :csrf-token is there on purpose since setting it on an insecure 
>> session, as ring-anti-forgery does, doesn't prevent CSRF attacks since the 
>> session identifier can still be fixed.  In ring-auth, it's up to the 
>> application to provide and check the :csrf-token on requests and responses, 
>> which is not that hard to do.
>>
>
> I'm not sure I follow. Even over HTTP, it shouldn't be possible for an 
> attacker to read anything in the session itself. Only the server can read 
> session information.
>  
>
>> Sessions can still be expired via the session store, but not all stores 
>> make it easy to auto-expire them.  Keeping invalidation code in the 
>> middleware just provides some more defense in-depth.
>>
>
> If the session store doesn't have expiry mechanisms, then the session 
> store is broken. 
>  
>
>> There are other niceties in ring-auth which are easy to elide when 
>> focusing on your application logic.  
>>
>> For instance, the session identifier for the :auth-session is always a 
>> random UUID rather than allowing the session store to decide what it is. 
>>  This guards against session stores that might simply auto-increment the 
>> session identifier and thus be easily guessable.
>>
>
> If the session key is easily guessable, then the session store is 
> completely broken and needs to be immediately replaced.
>
> The problem is that you're adding code that only has benefit if another 
> part of the system is broken in some major way. If the session store is not 
> broken, all your code is doing is adding complexity for no benefit.
>
> Rather than use wrap-auth-session, it seems like a better idea just to 
> check that the session store you're using is in working order.
>
> Every time the contents of :auth-session are altered, a new session 
>> identifier is created.  This guards against privilege escalation whereby 
>> moving from "regular user" -> "admin" would allow a third party with access 
>> to the "regular user" session identifier to now act as an "admin".
>>
>
> Middleware that clears the session if on changing privileges might be 
> useful, but I'd suggest this be separate middleware. 
>  
>
>> Finally, the logging was placed there for specific reasons.  If you see a 
>> lot "Unknown auth-id" messages, it's likely that someone is trying to guess 
>> the session identifiers.  Likewise, seeing "Refusing to set auth session on 
>> insecure request" means that your code is allowing HTTP on a route that 
>> should probably be HTTPS-only and you should look into your routing logic. 
>>  I thin

Re: [ANN] ring-auth middleware for protecting sessions

2014-05-17 Thread James Reeves
On 18 May 2014 00:09, Brendan Younger  wrote:

> For anyone else following along at home, I'll just re-iterate the benefits
> of using ring-auth versus trying to write your routes *just right* to
> avoid the myriad security issues listed at OWASP.
>
> - If you initiate a session with a user over HTTP and later on that user
> logs in over HTTPS but you don't change the session id in the cookie, then
> everyone at the coffee shop has access to the authenticated session.
>  Ring-auth protects you from this.
>

This is true, but I don't think we should be aiming to protect people from
doing the wrong thing, so much as stop them from doing it in the first
place.

You seem to be aiming this middleware at people concerned about security,
but not so concerned as to follow best practice. I'm a little baffled by
this use-case.


> - If you use a CSRF middleware, but at any time leak the session id cookie
> over HTTP, then your CSRF protection is broken.  Ring-auth protects you
> from this.
>

CSRF protection doesn't matter if your session is compromised. CSRF is a
mechanism for sending a HTTP POST with the user's session ID. If you
already have the session ID, there's very few reasons why you'd bother with
CSRF.


> - If you ever send your CSRF token over HTTP, then the entire coffee shop
> can entice the user to "Click here now!" and send money to their off-shore
> account.  Ring-auth helps you avoid sending the CSRF token in the clear.
>

Hm? How? There doesn't appear to be anything in your code that looks for
the CSRF token embedded in the response body.


> - If you get a request over HTTP which should have gone over HTTPS and
> respond with an error, but don't immediately delete the session, then
> everyone at the coffee shop has seen the authenticated session id (assuming
> you forgot to set Secure).  Ring-auth protects you from this.
>

Again, I don't understand the use-case for this. Setting the secure flag on
the session cookie is the clearly the better option. I'm having trouble
seeing how you'd present this in your project's README.


> - If a user closes their browser on a public computer but forgets to sign
> off, the next user can go back to the site, and hopefully the browser has
> cached the cookie giving them access to the first user's account.
>  Ring-auth will help prevent this as soon as the "Cache-Control" header is
> set.
>

A session idle-timeout isn't necessarily a bad idea, though again this
could be implemented as middleware on top of the existing session
middleware.

I'm not sure what bearing the Cache-Control header has in this case.


> - Not to mention the helpful errors that try to help you develop secure
> routes with warnings when you're doing something obviously insecure.
>

This isn't a bad idea.


> None of these things come out-of-the-box with Ring's wrap-session, even
> with {:secure true} set.
>

No, and I agree that there are definitely pieces of middleware that could
help, but I disagree on how ring-auth currently goes about it.

Improving Ring's security is a laudable goal, but it's also something you
need to be very careful with. Rather than building on existing
infrastructure, such as the secure cookie flag or the existing wrap-session
middleware, you're building your own ad-hoc systems. This is not a good way
to build secure software.

You have a lot of sound ideas, but any library that purports to improve
security needs to be very carefully considered, and should be held to a far
higher standard.

- James

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: clojurescript, sourcemaps, and debugging info

2014-05-17 Thread t x
flat namespace is ugly. Someone please please tell me there is a
better solution. :-) Is there no 10-line chrome-plugin which solves
this?

On Fri, May 16, 2014 at 7:35 AM, t x  wrote:
> Bah, I've reverted to a flat namespace, i.e. foo_internal.cljs,
> foo_public.cljs, bar_internal.cljs, bar_public.cljs ... :-)
>
> On Fri, May 16, 2014 at 6:24 AM, Tim Visher  wrote:
>> Seems worth a bug report/feature request to the Chrome Dev Tools team.
>>
>> On Thu, May 15, 2014 at 11:45 PM, t x  wrote:
>>> Hi,
>>>
>>> * background:
>>>
>>>   * I have clojurescript + lein cljsbuild auto working perfectly fine.
>>>
>>>   * I have source maps working (when I click on a file in Chrome, it
>>> jumps me to the corresponding *.cljs file)
>>>
>>>
>>> * problem I am facing:
>>>
>>>   * I like to name my modules:
>>>
>>> foo/public.cljs
>>> foo/other-stuff.cljs
>>>
>>> bar/public.cljs
>>> bar/other-stuff.cljs
>>>
>>>   Now, Chrome + clojurescript (not sure who is at fault) appears to
>>> display not the _full name_, but only the _last part of the pathname_,
>>> so I get a bunch of lines saying things like:
>>>
>>>public.cljs:23
>>>public.cljs:68
>>>
>>>   and I have no idea whether it's foo/public.cljs or bar/public.cljs
>>> without clicking on it.
>>>
>>>
>>> * question:
>>>
>>>   Is there anyway to get Chrome / clojurescript to display the full
>>> name of the *.cljs file rather than just the last part?
>>>
>>> Thanks!
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscr...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google Groups 
>>> "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with your 
>> first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.