App-Dochazka-REST

 view release on metacpan or  search on metacpan

lib/App/Dochazka/REST/Guide.pm  view on Meta::CPAN

If this test fails, a "405 Method Not Allowed" response is sent.

=item * B<Internal and external authentication, session management>

This takes place when L<Web::Machine> calls the C<is_authorized> method,
our implementation of which is in L<App::Dochazka::REST::Auth>.

Though the method is called C<is_authorized>, what it really does is
authenticate the request - i.e., validate the user's credentials to 
determine his or her identity. B<Authorization> - determination whether the
user has sufficient privileges to make the request - takes place one step
further on. (The HTTP standard uses the term "authorized" to mean
"authenticated"; the name of this method is a nod to that usage.)

In C<is_authorized>, the user's credentials are authenticated
against an external database (LDAP), an internal database (PostgreSQL
'employees' table), or both. Session management techniques are utilized
to minimize external authentication queries, which impose latency. The
authentication and session management algorithms are described in
L<"AUTHENTICATION AND SESSION MANAGEMENT">. If authentication fails, a "401
Unauthorized" response is sent. 

Since this is the first time that the PostgreSQL database is needed, this
is also where the L<DBIx::Connector> object is attached to the request
context. (The request context is a hashref that accompanies the request 
as it undergoes processing.) For details, see
L<App::Dochazka::REST::Auth/"is_authorized">.

In a web browser, repeated failed authentication attempts are typically
associated with repeated display of the credentials dialog (and no other
indication of what is wrong, which can be confusing to users but is probably a
good idea, because any error messages could be abused by attackers).

=item * B<Authorization/ACL check>

After the request is authenticated (associated with a known employee), the
server examines the ACL profile of the resource being requested and compares it
with the employee's privilege level. If the privilege level is too low for the
requested operation, a "403 Forbidden" response is sent.

The ACL profile is part of the resource definition. It can be specified either
as a single value for all HTTP methods, or as a hash, e.g.:

    {
        GET => 'passerby',
        PUT => 'admin',
        DELETE => 'admin',
    }

In certain operations (i.e., combinations of HTTP method and resource), the
full range of functionality may be available only to administrators. See These
operations are special cases. Their ACL profile is either 'inactive' or
'active', but a non-administrator employee may still get a 403 Forbidden error
on the operation if they are trying to do something, such as update an interval
belonging to a different employee, that is reserved for administrators.

=item * B<Test for resource existence>

The next test a request undergoes on its quest to become a response is the
test of resource existence. If the request is asking for a non-existent resource,
e.g. L<http://dochazka.site/employee/curent>, it cannot be fulfilled and a "404
Not Found" response will be sent.

For GET requests, this is ordinarily the last cog in the state machine: if the
test passes, a "200 OK" response is typically sent, along with a response body.
(There are exceptions to this rule, however - see L<the AUTHORIZATION
chapter|"AUTHORIZATION">.) Requests using other methods (POST, PUT, DELETE) are
subject to further processing as described below.

=back

=head2 Additional processing (POST and PUT)

Because they are expected to have a request body, incoming POST and PUT
requests are subject to the following additional test:

=over

=item * B<malformed_request>

This test examines the request body. If it is non-existent, the test
passes. If the body exists and is valid JSON, the test passes. Otherwise,
it fails.

=item * B<known_content_type>

Test the request for the 'Content-Type' header. POST and PUT requests
should have a header that says:

    Content-Type: application/json

If this header is not present, a "415 Unsupported Media Type" response is
sent.

=back

=head2 Additional processing (POST)

=over 

#=item * B<post_is_create>
#
#This test examines the POST request and places it into one of two
#categories: (1) generic request for processing, (2) a request that creates
#or otherwise manipulates a resource. 

=back


=head1 DATA MODEL

This section describes the C<App::Dochazka::REST> data model. Conceptually, 
Dochazka data can be seen to exist in the following classes of objects:

=over

##=item * Policy (parameters set when database is first created)
##
=item * Employee (an individual employee)

=item * Privhistory (history of changes in an employee's privilege level)

lib/App/Dochazka/REST/Guide.pm  view on Meta::CPAN


After the protocol, the next URI component is the REST server's domain name.
Obviously, this will differ from site to site. It is separated from the next
component (i.e. the resource specification) by a single forward slash.

=item Dochazka resource

As stated above, the domain name is terminated by a single forward slash.
Everything after that is interpreted as a resource specification. 

A single forward slash C<'/'> specifies the root resource.

=back

Of these three components, the first two are site-specific. It is possible, 
for example, to run the Dochazka server without SSL encryption, in which case
the protocol would be C<http://> instead of C<https://>.

Once the application's implementation at a given site has stabilized, these two
URI components will change very seldomly, if at all.

Dochazka resources are much more ephemeral. Different resources present
different ways that users can access and modify the data (in this case,
attendance data) in the underlying database. 

Some resources, such as C<employee/nick/simona>, refer directly to a unit of
information that may or may not exist in the database information. Other
resources, like C<interval/new>, are not linked to a specific database record.

Also, in programming terms the resources are generalized, so we think about,
e.g., C<employee/nick/simona> and C<employee/nick/wanda> as two instances of a
more generalized C<employee/nick/:nick> resource, where C<:nick> is like an
argument to a function call.

And, indeed, internally all resources resolve to function calls. The function
in this case is referred to as the "resource handler".

Some resources accept all four HTTP methods listed above, others accept two or
three, and still others accept only one.

=head3 Headers

HTTP headers are somewhat obscure because they are often hidden by the 
client. Nevertheless, they are an important part of the HTTP protocol. The
Dochazka REST server only accepts certain headers in the request.

#FIXME: describe the more common response headers

=head3 Body

C<PUT> and C<POST> requests may take a request body. If a request body is
expected or accepted, it must be a valid JSON string. (JSON is a simple way of
"stringifying" a data structure.)

=head2 HTTP response

The HTTP response returned by the REST server consists of:

=over

=item * Status code (e.g. 200, 400, 404, etc.)

=item * Headers

=item * Content body (or "response entity")

=back

=head3 Status

The HTTP standard stipulates a number of status codes. The server listens for
incoming requests. Under normal operation, the server processes each request.
The result of such processing is a "response", which is sent back to the client
that originated the request. Each response will contain one and only one status
code. The meanings of the various status codes are explained in the HTTP
standard. Some of the more common ones are as follows:

=over

=item C<200> (OK)

The request was accepted and processed. Refer to the response body for the
result.

=item C<204> ()

This code is returned on C<DELETE> requests when either the record was
successfully deleted or the resource did not exist in the first place.

=item C<404> (Not Found)

The resource specification given in the URI could not be associated with a
known resource.

=item C<405> (Method Not Allowed)

The resource was recognized but it is not defined for this method.

=item C<401> (Not authorized)

A valid method+resource combination was specified, but the user failed to
authenticate herself to the REST server.

=item C<403> (Forbidden)

A valid method+resource combination was specified and the user was successfully
authenticated, but the user is not authorized to perform the operation she is
requesting.

=item C<400> (Malformed)

A valid method+resource combination was specified and the user passed
authentication and authorization. However, the information provided by the user
in the resource specification or in the request body could not be parsed.

=back

=head3 Headers

HTTP responses are always accompanied by headers, which qualify the response in
various ways. For example, the C<Content-Encoding> header indicates how the
bytes in the response body string should be interpreted. In Dochazka's case, the 
response body will always be in JSON, which implies the C<UTF-8> encoding.

#FIXME: describe the more common response headers

=head3 Body

The response body holds the information returned by a "successful" request. Be
aware that "success" in this context only means that, from the perspective of
the REST server, the request was fully processed. It does I<not> means that 
that whatever the user was requesting was actually done. For example, if a
C<GET> request for a resource is sent and the reponse code is 200, the client
programmer can assume that a response body will be present, and that it will
be an L<App::CELL::Status> object, but that is all she can assume.
Particularly, she cannot assume that the payload of that status object 
contains the object requested.

As stated above, the response body will always be a JSON string. This string
can either be displayed to the user as-is, or it can be interpreted and further
processed by the client.

A body may be included in the response, provided the status code is C<200> (OK).
For the client, an HTTP response of 200 is a signal to look into the response
body for further information. For the purposes of Dochazka, a 200 status does
not provide any information beyond this imperative: "look into the response
body". 

Since looking into the response body is fundamental to the operation of
Dochazka clients, the REST server emits response bodies in a strictly defined



( run in 0.859 second using v1.01-cache-2.11-cpan-39bf76dae61 )