App-Dochazka-REST

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


0.421  2015-04-05 13:34 CEST
- REST/Shared.pm: in 'shared_get_privsched', return 404 if no priv/schedule
  assigned (instead of returning 200 OK with a null priv/schedule) 
- t/dispatch/schedule.t: adapt tests

0.422  2015-04-05 20:45 CEST
- dbinit_Config.pm: make schedule_at_timestamp return SID instead of the
  schedule JSON itself
- Model/Shared.pm: schedule_by_eid returns SID
- REST/Shared.pm: shared_get_privsched looks up the SID and returns the
  entire schedule
- t/dispatch/schedule.t: adapt tests affected by the above change
- t/sql/disabled_to_zero.t: clean up after ourselves

0.423  2015-04-06 13:42 CEST
- REST/Shared.pm: make shared_employee_acl_part2 declare 403 status with a
  proper App::CELL::Status instead of a hard-coded string

0.424  2015-04-06 18:59 CEST
- ResourceDefs.pm: allow inactives and actives to view their own privilege

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

    bash# systemctl enable postgresql.service
    bash# systemctl start postgresql.service
    bash# su - postgres
    bash$ psql postgres
    postgres-# ALTER ROLE postgres WITH PASSWORD 'mypass';
    ALTER ROLE

At this point, we exit C<psql> and, still as the user C<postgres>, we 
edit C<pg_hba.conf>. In SUSE distributions, this file is located in
C<data/> under the C<postgres> home directory.  Using our favorite editor,
we change the METHOD entry for C<local> so it looks like this:

    # TYPE  DATABASE   USER   ADDRESS     METHOD
    local   all        all                password

For the audit triggers to work (and the application will not run otherwise), we
must to add the following line to the end of C<postgresql.conf> (also
located in C<data/> in SUSE distros):

    dochazka.eid = -1

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

machine, each "cog" of which is a L<Web::Machine::Resource> method that can
be overridden by a child module. In our case, this module is
L<App::Dochazka::REST::Resource>.

The behavior of the resulting web server can be characterized as follows:

=over

=item * B<Allowed methods test>

One of the first things the server looks at, when it receives a request, is 
the method. Only certain HTTP methods, such as 'GET' and 'POST', are accepted.
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 

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

    my $cdate = shift;  # cdate == Canonicalized Date String YYYY-MM-DD
    my ( $year, $month, $day ) = $cdate =~ m/(\d{4})-(\d{2})-(\d{2})/;
    my ( $tyear, $tmonth, $tday ) = Add_Delta_Days( $year, $month, $day, 1 );
    return "$tyear-" . sprintf( "%02d", $tmonth ) . "-" . sprintf( "%02d", $tday );
}


=head2 holidays_and_weekends

Given a date range (same as in C<holidays_in_daterange>, above), return
a reference to a hash of hashes that looks like this (for sample dates):

    {
        '2015-01-01' => { holiday => 1 },
        '2015-01-02' => {},
        '2015-01-03' => { weekend => 1 },
        '2015-01-04' => { weekend => 1 },
        '2015-01-05' => {},
        '2015-01-06' => {},
    }

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


sub privhistory_at_timestamp {
    my $self = shift;
    my ( $conn, $arg ) = validate_pos( @_, 
        { isa => 'DBIx::Connector' },
        { type => SCALAR },
    );
    $log->debug( "Entering " . __PACKAGE__ . "::privhistory_at_timestamp with argument $arg" );
    $log->debug( "EID is " . $self->eid );

    # if it looks like a tsrange, use tsrange, otherwise use timestamp
    my $sql = ( $arg =~ m/[[(].*,.*[])]/ )
        ? $site->SQL_EMPLOYEE_PRIVHISTORY_AT_TSRANGE
        : $site->SQL_EMPLOYEE_PRIVHISTORY_AT_TIMESTAMP;

    my $status = select_single(
        conn => $conn, 
        sql => $sql,
        keys => [ $self->eid, $arg ], 
    );
    return undef unless $status->ok;

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


sub schedhistory_at_timestamp {
    my $self = shift;
    my ( $conn, $arg ) = validate_pos( @_, 
        { isa => 'DBIx::Connector' },
        { type => SCALAR },
    );
    $log->debug( "Entering " . __PACKAGE__ . "::schedhistory_at_timestamp with argument $arg" );
    $log->debug( "EID is " . $self->eid );

    # if it looks like a tsrange, use tsrange, otherwise use timestamp
    my $sql = ( $arg =~ m/[[(].*,.*[])]/ )
        ? $site->SQL_EMPLOYEE_SCHEDHISTORY_AT_TSRANGE
        : $site->SQL_EMPLOYEE_SCHEDHISTORY_AT_TIMESTAMP;

    my $status = select_single(
        conn => $conn, 
        sql => $sql,
        keys => [ $self->eid, $arg ], 
    );
    return undef unless $status->ok;

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

for multiple employees. (For example, an organization might have hundreds of
employees on a single, unified schedule.) 

      CREATE TABLE IF NOT EXISTS schedules (
        sid        serial PRIMARY KEY,
        schedule   text UNIQUE NOT NULL,
        disabled   boolean,
        remark     text
      );

The value of the 'schedule' field is a JSON array which looks something like this:

    [
        { low_dow:"MON", low_time:"08:00", high_dow:"MON", high_time:"12:00" },  
        { low_dow:"MON", low_time:"12:30", high_dow:"MON", high_time:"16:30" },  
        { low_dow:"TUE", low_time:"08:00", high_dow:"TUE", high_time:"12:00" },  
        { low_dow:"TUE", low_time:"12:30", high_dow:"TUE", high_time:"16:30" },
        ...
    ]   

Or, to give an example of a more convoluted schedule:

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

);




=head1 FUNCTIONS


=head2 hash_the_password

Takes a request entity (hashref) - looks for a 'password' property.  If it
is present, adds a random salt to the request entity and hashes the
password with it.  If there is no password property, the function does
nothing.

=cut

sub hash_the_password {
    my $entity = shift;
    if ( $entity->{'password'} ) {
        my $ppr = Authen::Passphrase::SaltedDigest->new(

t/dispatch/interval_lock.t  view on Meta::CPAN

        ', "intvl" : "[2014-07-31 20:00, 2014-08-01 00:01)" }',
    qr/upper and lower bounds of interval must be evenly divisible by 5 minutes/ );

note( '- interval is locked' );
dbi_err( $test, 500, 'active', 'POST', 'interval/new',
    '{ "aid" : '. $aid_of_work . ', "eid" : ' . $eid_active .
        ', "intvl" : "[2014-07-31 20:00, 2014-08-01 00:05)" }',
    qr/interval is locked/ );

note( 'now let\'s try to attack upper bound of lock' );
note( '- this one looks like it might conflict with the lock\'s upper bound');
note( '  (2014-09-01), but since the upper bound is non-inclusive, the interval will');
note( '  be OK');

$status = req( $test, 201, 'active', 'POST', 'interval/new', <<"EOH" );
{ "aid" : $aid_of_work, "eid" : $eid_active, "intvl" : "[2014-09-01 00:00, 2014-09-01 04:00)" }
EOH
is( $status->level, 'OK' );
is( $status->code, 'DOCHAZKA_CUD_OK' );
$tiid = $status->payload->{'iid'};
$status = req( $test, 200, 'active', 'DELETE', "interval/iid/$tiid" );



( run in 0.791 second using v1.01-cache-2.11-cpan-64827b87656 )