problem with redirect code

32 views
Skip to first unread message

Bill Norman

unread,
Feb 19, 2016, 6:35:41 PM2/19/16
to ChicagoBoss
Hello,

I am currently going through the 'Evening with Chicago Boss tutorial.

I am following instructions for handling user authentication and have implemented this code fragment in the controller/evening_user_controller.erl:

  1. login('POST', []) ->
  2. Name = Req:post_param("name"),
  3. case boss_db:find(ward_boss, [{name, Name}], [{limit,1}]) of
  4. [WardBoss] ->
  5. case WardBoss:check_password(Req:post_param("password")) of
  6. true ->
  7. {redirect, proplists:get_value("redirect",
  8. Req:post_params(), "/"), WardBoss:login_cookies()};
  9. false ->
  10. {ok, [{error, "Bad name/password combination"}]}
  11. end;
  12. [] ->
  13. {ok, [{error, "No Ward Boss named " ++ Name}]}
  14. end.
My issue is that the value of the redirect (lines 7 & 8) calculates to the default value "/" in proplists:get_value/3.

The return value of Req:post_params() is:
[{<<"name">>,<<"Bathhouse John">>}, {<<"password">>,<<"password">>}, {<<"redirect">>,<<"http://localhost:8001/voter/list">>}]

so querying this list with proplists:get_value("redirect", Req:post_params()) returns undefined.

I modified the code to:
binary_to_list(proplists:get_value(list_to_binary("redirect"), Req:post_params()))

This works but it is awfully ugly. 

Is there a helper method in Chicago Boss or a more elegant erlang conversion term  
I could use to handle the binary tuples returned by Req:get_params()?

What has changed since this tutorial was written? Has the output of Req:get_params()
changed?

Thanks

Bill Norman

unread,
Feb 19, 2016, 6:41:46 PM2/19/16
to ChicagoBoss
BTW, I am using the current CB master for OTP 18, and running erlang 18.1.

kotedo

unread,
Feb 19, 2016, 6:50:12 PM2/19/16
to chica...@googlegroups.com
Hi Bill,

First off, yes the code is butt-ugly.

On that note; you can make it nicer:

[_, _, {<<"redirect">>,Location}] = Req:post_params()
{redirect, Location, WardBoss:login_cookies()}

Pardon my horrible copy/paste

—Kai




--
You received this message because you are subscribed to the Google Groups "ChicagoBoss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chicagoboss...@googlegroups.com.
Visit this group at https://groups.google.com/group/chicagoboss.
To view this discussion on the web visit https://groups.google.com/d/msgid/chicagoboss/02f68890-e21f-4ac5-8def-c71af84a81cd%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Graeme Defty

unread,
Feb 19, 2016, 6:52:40 PM2/19/16
to chica...@googlegroups.com
Hi Bill,

Yes, you are quite right. We now have to deal in binaries.

You should just be able to put:

  proplists:get_value(<<"redirect">>, Req:post_params(), "/"),

Regards,

Graeme



--
You received this message because you are subscribed to the Google Groups "ChicagoBoss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chicagoboss...@googlegroups.com.
Visit this group at https://groups.google.com/group/chicagoboss.

rlander

unread,
Feb 19, 2016, 7:02:31 PM2/19/16
to ChicagoBoss
Bill,

I think that tutorial is a bit outdated. This one is more current:


Why not use a binary instead of a string?
proplists:get_value(<<"redirect">>, Req:post_params())

Jesse Gumm

unread,
Feb 19, 2016, 7:02:59 PM2/19/16
to chica...@googlegroups.com
Rather than pulling Req:post_params() then running a
proplist:get_value() against it, you can do:

Req:post_param(redirect) or Req:post_param("redirect") to get the string value.

Or Req:post_param(<<"redirect">>) to get the same value as a binary.

SimpleBridge 2.0 is Type-In-Type-Out in almost all cases, though
Req:params() returns just the full list of internally stored params
(which are stored as binary).

Unless you need the full list of params to work with, It's usually
preferable to just do Req:post_param/1 or Req:query_param/1.

Or alternatively, sbw:post_param(redirect, Req). This method will help
with dialyzer checks.

-Jesse
> https://groups.google.com/d/msgid/chicagoboss/CAKF5fiB4TzJSyqg%3DyL%2BSO9RTg_i8hONJN4QHkSQJeKwH%2Bxu8YA%40mail.gmail.com.
>
> For more options, visit https://groups.google.com/d/optout.



--
Jesse Gumm
Owner, Sigma Star Systems
414.940.4866 || sigma-star.com || @jessegumm

rlander

unread,
Feb 19, 2016, 7:06:44 PM2/19/16
to ChicagoBoss
Or this. Pattern matching is way faster than propiststs:get_value/2 AFAIK.

rland...@gmail.com

unread,
Feb 19, 2016, 7:30:59 PM2/19/16
to chica...@googlegroups.com
On Fri, Feb 19, 2016 at 10:02 PM, Jesse Gumm <gu...@sigma-star.com> wrote:


Or alternatively, sbw:post_param(redirect, Req). This method will help
with dialyzer checks.

Going off on a tangent, sbw is new to me. Are you planning on killing pmod support? Should I be using this in order to future-proof my apps?


Jesse Gumm

unread,
Feb 19, 2016, 7:54:58 PM2/19/16
to chica...@googlegroups.com
No, I definitely will not be killing the pmod syntax for simple_bridge.

Even though simple_bridge doesn't use pmods any longer, it retains the
tuple-module syntax, and I did this specifically to avoid breaking
every app that depends on SB.

That said, I added sbw because the pmod syntax is absolutely *loathed*
by many in the Erlang world, so giving a version that works without
pmods was the goal. Further, as I said, dialyzer can't analyze through
the pmod syntax, so if you want your apps dialyzable, the standard
Erlang syntax is the way to do it.

But the pmod approach will not be dropped or abandoned unless Erlang
explicitly drops tuple-module syntax, in which case, even then a parse
transform will almost certainly be made available.

For a bit of history and more explanation:

sbw = "simple bridge wrapper"

In SB 1.x, the request and response were separate objects, and were
handled using the explicit pmod syntax with the parse transform. At
that time, the modules that handled all calls were
simple_bridge_request_wrapper and simple_bridge_response_wrapper
(https://github.com/nitrogen/simple_bridge/blob/da17a0fe8da2a3d1d6e5feaf195d415d6504fdce/src/simple_bridge_request_wrapper.erl)
-- long names that no one ever would want to type in their code with
the frequency necessary when working with the modules.

With 2.0, I unified the two into a single "Bridge" object (though CB's
code still refers to it as Req, and that's perfectly okay), and
introduced an internal record called #sbw
(https://github.com/nitrogen/simple_bridge/blob/master/include/simple_bridge.hrl#L14),
which wraps the information previously tracked using pmods.
Conveniently, if you have a record, and that record is used as the
last argument in a function call, you can also use the tuple-module
syntax in the same way. So even though simple_bridge doesn't
explicitly use pmods any longer, it does have both an #sbw record and
an sbw module. Which allows you to interchangeably use:

Bridge:post_params("header")
or
sbw:post_params("header", Bridge)

They are effectively the same call, though in the first case (the pmod
syntax), the `sbw` module is determined at runtime, rather than
compile time, which is why it can't dialyze.

Anyway, that was a much longer explanation than necessary, but I guess
I'm feeling a little verbose this evening.

Also, relevant to the conversation, the binary issue is documented
here: https://github.com/nitrogen/simple_bridge#return-type-changes-to-look-out-for-in-20
.While most of it has already been mentioned, it's documented at that
part in the Readme.

-Jesse
> --
> You received this message because you are subscribed to the Google Groups
> "ChicagoBoss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to chicagoboss...@googlegroups.com.
> Visit this group at https://groups.google.com/group/chicagoboss.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/chicagoboss/CAF788usuZnjc2nmnTNvqam4oinTgfHbPfG97E0UvSLjjuJvUfw%40mail.gmail.com.

rlander

unread,
Feb 20, 2016, 12:03:16 AM2/20/16
to ChicagoBoss
Jesse,

thanks for the clear explanation.

Bill Norman

unread,
Feb 20, 2016, 9:26:51 AM2/20/16
to ChicagoBoss

Thank you for all the help. I now have a functioning authentication system that I can use in my own project.
Reply all
Reply to author
Forward
0 new messages