Let's take a look at merlyn's analysis of CGI programming:

The core of every CGI application seems to be roughly the same:

  1. Analyze the incoming parameters, cookies, and URLs to determine the state of the application (let's call this ``dispatch'').
  2. Based on the current state, analyze the incoming parameters to respond to any form submitted (``respond'').
  3. From there, decide what response page should be generated, and produce it (``render'').

This post aims to expand and clarify step #2 above with a newly discovered issue.

When a user submits a form, your response may entail several different actions:
validation
was the submitted form data intelligible?
authentication
was the submitted form data/cookie something that allows you to figure out who this person is?
authorization
was the person who submitted form data/cookie somethone that has a right to request this page?
execution
Perform the actions requested by hitting the submit button. E.g. update user info.

So now that you understand these steps, let's see why I am bothering posting all this. Let's assume you have presented a user with an information update screen. The user enters some (possibly invalid) data and hits submit. The following then occurs in CGI::Prototype::activate

  1. the dispatch routine is called. This routine will determine that a user has submitted user update information. Now it is up to a package, say, MyApp::Update::Validate to determine the response. Here is pseudocode for that:
    package MyApp::Update::Validate; sub response { my $response; if (not validated) { $response = 'Redo'; } elsif (not authenticated) { $response = 'NotAuthenticated' } elsif (not authorized) { $response = 'NotAuthorized'; } else { $response = 'HandleUpdate' # model action: update user info } $response = "MyApp::Login::$response"; return $response; }

But the question becomes where do model actions occur and how do we change pages based on this?

Replies are listed 'Best First'.
Re: CGI::Prototype - let me clarify the response phase for you
by Anonymous Monk on Feb 05, 2005 at 17:40 UTC
    you have authorize and authenticate backwards.

    authenticate -- establish identity

    authorize -- does identity have sufficient rights for requested action.

Re: CGI::Prototype - let me clarify the response phase for you
by cbrandtbuffalo (Deacon) on Feb 07, 2005 at 17:29 UTC

    This is how we handle those phases within CGIP:

    authenticate: the server does this for us, and gives us the userid;

    authorize: create an authorize method that lets them through or doesn't and put it in app_enter since this is 'front door':

    sub app_enter { my $self = shift; # Check auth at the app-level. If they don't pass, they don't # get in. if ( not $self->authorize() ){ die [user_error => "Not authorized."]; } }

    We have a die handler that will catch that error and put up a nice page. The die handler always calls the same default 'info_page' and displays the message you send. You may need something fancier, but this has served us so far.

    As I mentioned in a post to your other topic, we put our validate hook in respond_per_app so we can allow CGIP handle the page dispatch.

    So if we make it to respond_per_page, we know we're good and we can to the 'execute' part. For us, this usually means putting some data in the database. The last part of this method is to return the page object that you want to user to go to next. CGIP will then go to that page and try to render (and render_enter_per_page). So if you finish respond_per_page with something like:

    return $self->name_to_page('next_page_name');

    CGIP will try to render that page next.

Re: CGI::Prototype - let me clarify the response phase for you
by metaperl (Curate) on Feb 04, 2005 at 23:27 UTC
    But the question becomes where do model actions occur and how do we change pages based on this?
    You are thinking about the problem incorrectly. There should *not* be a  MyApp::Update::Validate package. There should be a MyApp::Update::HandleUpdate page which has the logic above and then executes the model actions before returning a response so that the responses can come from subclasses of HandleUpdate... here's the code:

    package MyApp::Update::HandleUpdate; # <-- note new package name sub model_actions { } sub response { my $self = shift; my $response; if (not validated) { $response = 'Redo'; } elsif (not authorized) { $response = 'NotAuthorized' } elsif (not authenticated) { $response = 'NotAuthenticated'; } else { # just render here. # if we felt like it, we could have __PACKAGE::success # and __PACKAGE::failure $response='HandleUpdate'; } $response = "MyApp::Login::$response"; return $response; }
      Why are you arguing with yourself in public? That looks somewhat schizophrenic ...

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        I, too, have been confused about this. I assume two people used a single account or something strange like that, but I'd be interested in knowing as well.