App-Dochazka-CLI

 view release on metacpan or  search on metacpan

lib/App/Dochazka/CLI/Testers.pm  view on Meta::CPAN

repo for your operating system:
L<http://software.opensuse.org/download.html?project=home%3Asmithfarm&package=perl-App-Dochazka-CLI>.


=head2 Prereq 2: Install/configure servers

Before you start, you will need to install and set up PostgreSQL and the
Dochazka REST server. There are two ways to accomplish this:
the Docker way and the "traditional" way.

=over

=item L<"The Docker way">

is arguably simpler, because you don't install as many
packages and there is little or no setup work involved. However, quite a
lot of data (on the order of hundreds of MB) will be downloaded from Docker
Hub. (To handle this, it may be a good idea to put C</var/lib/docker> on a
separate partition.)

=item L<"The traditional way">

is to install and configure PostgreSQL and the
Dochazka REST server in your testing environment. This is somewhat more
complicated and involves installing and operating a PostgreSQL server on
the machine where you will be running the tests.

=back

Both ways are described below, but you only need to do one or the other!

=head3 The Docker way

=over

=item Install Docker

For testing purposes, you can use the Dockerized REST server. For this, you
will need to have Docker installed and running:

    zypper install docker
    systemctl start docker.service

=item Get and run test drive script

The REST server Docker image depends on the official PostgreSQL image and
must be run with certain parameters. A script is provided to make this
easy. Download and run the script:

    wget https://raw.githubusercontent.com/smithfarm/dochazka-rest/master/test-drive.sh
    sh test-drive.sh

If you have never run Docker containers before, you may be surprised that
the script downloads quite a lot of data from Docker Hub. The script should
complete without any error messages.

=item Web browser test

When the C<test-drive.sh> script completes, you should be able to access
the REST server by pointing your browser at L<http://localhost:5000>. At
the login dialog, enter username "demo" and password "demo".

=back


=head3 The traditional way

Alternatively, if you don't like Docker or can't use it for some reason,
you can install and set up PostgreSQL and the Dochazka REST server
yourself.

=over

=item Install server packages

    zypper install postgresql postgresql-server postgresql-contrib 
    zypper install perl-App-Dochazka-REST 

=item PostgreSQL setup

Follow the instructions at
L<https://metacpan.org/pod/App::Dochazka::REST::Guide#PostgreSQL-setup>.

=item Site configuration

Follow the instructions at
L<https://metacpan.org/pod/App::Dochazka::REST::Guide#Site-configuration>.

=item Database initialization

This step is very simple. Just run the C<dochazka-dbinit> command:

    # dochazka-dbinit
    Dochazka database reset to pristine state

=item Start the server

To actually do anything, the server needs to be running:

    # dochazka-rest
    Starting Web::MREST ver. 0.283
    App distro is App-Dochazka-REST
    App module is App::Dochazka::REST::Dispatch
    Distro sharedir is /usr/lib/perl5/site_perl/5.20.1/auto/share/dist/App-Dochazka-REST
    Local site configuration directory is /etc/dochazka-rest
    Loading configuration parameters from /etc/dochazka-rest
    Setting up logging
    Logging to /home/smithfarm/mrest.log
    Calling App::Dochazka::REST::Dispatch::init()
    Starting server
    HTTP::Server::PSGI: Accepting connections at http://0:5000/

=item Web browser test

After completing the above, you should be able to access the REST server by
pointing your browser at L<http://localhost:5000>. At the login dialog,
enter username "demo" and password "demo".

=back


=head2 Prereq 3: Install Dochazka CLI client

Now that the server part is working, install the CLI:

    zypper install perl-App-Dochazka-CLI

You should now be able to start the CLI and login as "demo" with password
"demo":

    $ dochazka-cli -u demo -p demo
    Loading configuration files from
    /usr/lib/perl5/vendor_perl/5.18.2/auto/share/dist/App-Dochazka-CLI
    Cookie jar: /root/.cookies.txt
    URI base http://localhost:5000 set from site configuration
    Authenticating to server at http://localhost:5000 as user root
    Server is alive
    Dochazka(2016-01-12) demo PASSERBY>

Exit the CLI by issuing the C<exit> command:

    Dochazka(2016-01-12) demo PASSERBY> exit
    $

Congratulations! You have passed the first test.


=head1 SESSION 1: CREATE AN EMPLOYEE

Before you do anything, L<make sure the server is running|"Start the server">.


=head2 Try with insufficient privileges

To create an employee, you will need to be logged in as an administrator.
The "demo" employee is not an administrator, but let's try anyway. First,
log in according to L<"Verify success">, above. Then, issue the C<employee
list> command:

    Dochazka(2016-01-12) demo PASSERBY> employee list
    *** Anomaly detected ***
    Status:      403 Forbidden
    Explanation: ACL check failed for resource employee/list/?:priv (ERR)

This output indicates that the REST server returned a C<403 Forbidden> error,
which is to be expected because the C<demo> employee has insufficient
privileges.

Next, try to create an employee:

    Dochazka(2016-01-12) demo PASSERBY> PUT employee nick george { "fullname" : "King George III" }
    HTTP status: 403 Forbidden
    Non-suppressed headers: {
      'X-Web-Machine-Trace' => 'b13,b12,b11,b10,b9,b8,b7'
    }
    Response:
    {
       "payload" : {
          "http_code" : 403,
          "uri_path" : "employee/nick/george",
          "permanent" : true,
          "found_in" : {
             "file" : "/usr/lib/perl5/vendor_perl/5.22.0/App/Dochazka/REST/Auth.pm",
             "package" : "App::Dochazka::REST::Auth",
             "line" : 431
          },
          "resource_name" : "employee/nick/:nick",
          "http_method" : "PUT"
       },
       "text" : "ACL check failed for resource employee/nick/:nick",
       "level" : "ERR",
       "code" : "DISPATCH_ACL_CHECK_FAILED"
    }

Here, the error is the same C<403 Forbidden> but the output is more detailed.
This is because we used a special type of command that is ordinarily only
used to test the REST API.

=head2 Log in as root

For the rest of this session, we will be logged in as the C<root> employee, 
which has a special status in that it is created when the database is
initialized and it is difficult or impossible to delete. In a freshly
initialized database, the C<root> employee's password is "immutable".

The username and password need not be specified on the command line.
Try it this way:

    $ dochazka-cli
    Loading configuration files from /usr/lib/perl5/vendor_perl/5.18.2/auto/share/dist/App-Dochazka-CLI
    Cookie jar: /root/.cookies.txt
    URI base http://localhost:5000 set from site configuration
    Username: root
    Authenticating to server at http://localhost:5000 as user root
    Password: 
    Server is alive
    Dochazka(2016-01-12) root ADMIN>

=head2 List employees

A list of all employees in the database can be obtained using the C<employee
list> command, which is documented at L<App::Dochazka::CLI::Guide|"Get list of
employees">:

    Dochazka(2016-01-12) root ADMIN> employee list

    List of employees with priv level ->all<-
        demo
        root

Actually, there is no priv level "all" - this just means that all employees are
listed, regardless of their priv level.

You can also try listing employees by priv level as per the documentation.

=head2 Create an employee

At the moment there is no CLI command to create a new employee. Hence we use
the REST API testing command as described in
L<App::Dochazka::CLI::Guide|"Create a new employee">:

    Dochazka(2016-01-12) root ADMIN> PUT employee nick george { "fullname" : "King George III" }
    HTTP status: 200 OK
    Non-suppressed headers: {
      'X-Web-Machine-Trace' => 'b13,b12,b11,b10,b9,b8,b7,b6,b5,b4,b3,c3,c4,d4,e5,f6,g7,g8,h10,i12,l13,m16,n16,o16,o14,p11,o20,o18,o18b'
    }
    Response:
    {
       "code" : "DOCHAZKA_CUD_OK",
       "count" : 1,
       "payload" : {
          "email" : null,
          "remark" : null,
          "eid" : 3,
          "passhash" : null,
          "supervisor" : null,
          "sec_id" : null,
          "salt" : null,
          "nick" : "george",
          "fullname" : "King George III"
       },
       "text" : "DOCHAZKA_CUD_OK",
       "DBI_return_value" : 1,
       "level" : "OK"
    }

lib/App/Dochazka/CLI/Testers.pm  view on Meta::CPAN

=cut


=head1 SESSION 2: EMPLOYEE PRIVILEGES AND PASSWORD

Before you do anything, L<make sure the server is running|"Start the server">.


=head2 Verify state

If you are continuing from Session 1, you can skip this step.

If you are starting over (or from scratch), run the following script to
bring your database into the proper state:

    #!/bin/sh
    cat <<EOF | dochazka-cli -u root -p immutable
    PUT employee nick george { "fullname" : "King George III" }
    EOF


=head2 View employee profile

Let us see the state of a freshly created employee:

    Dochazka(2016-01-27) root ADMIN> emp=george profile

    Full name:    King George III
    Nick:         george
    Email:        (not set)
    Secondary ID: (not set)
    Dochazka EID: 5
    Reports to:   (not set)

This only tells us the state of the employee object. Most objects in the
Dochazka database are associated with an employee via the Dochazka EID
value (5 in this example). We can get the same information by typing:

    Dochazka(2016-01-27) root ADMIN> eid=5 profile

    Full name:    King George III
    Nick:         george
    Email:        (not set)
    Secondary ID: (not set)
    Dochazka EID: 5
    Reports to:   (not set)


=head2 Log in as george

Now, exit the CLI and run it again as C<george>, our new employee.

    $ dochazka-cli 
    ...
    Username: george
    Authenticating to server at http://localhost:5000 as user george
    Password: 
    MREST_CLI_UNAUTHORIZED (ERR) MREST_CLI_UNAUTHORIZED
    Response: '401 Unauthorized'

This happens because there is no password set for C<george>.


=head2 Assign george a password

Fortunately, Dochazka admins can assign any password to any user. This
capability may or may not be useful, depending on whether LDAP
authentication is active at the site. In our current testing scenario, LDAP
authentication is disabled, so the password is taken from the Dochazka
database. So, let's give george a password:

    $ dochazka-cli -u root -p immutable
    ...
    Dochazka(2016-01-27) root ADMIN> emp=george password
    It is important that the new password really be what you intended.
    Therefore, we are going to ask you to enter the desired password
    twice, so you have a chance to double-check. 

    New password      : <type george>
    New password again: <type george again>
    Password changed

Now you can log in with credentials C<george/george>:

    $ dochazka-cli -u george -p george
    ...
    Authenticating to server at http://localhost:5000 as user george
    Server is alive
    Dochazka(2016-01-27) george PASSERBY>




=head1 SESSION 3: EMPLOYEE PRIVILEGE HISTORY

Before you do anything, L<make sure the server is running|"Start the server">.


=head2 Verify state

If you are continuing from Session 2, you can skip this step.

If you are starting over (or from scratch), run the following script to
bring your database into the proper state:

    #!/bin/sh
    cat <<EOF | dochazka-cli -u root -p immutable
    PUT employee nick george { "fullname" : "King George III", "salt" : "a054d158a23c3a07ad0163107ad72a8649597d71", "passhash" : "5cf2c3a23de9db43d2d846172966150e9197717ecd0304bafef3f23fc159df942021dd3aec7b4dbcde87d8a44c1bd905bbba3862989065d012bb46a1...
    EOF


=head2 Log in as the test employee

This just demonstrates that the test employee can log in.

    $ dochazka-cli -u george -p george
    ...
    Authenticating to server at http://localhost:5000 as user george
    Server is alive
    Dochazka(2016-01-27) george PASSERBY>


=head2 Concepts (Dochazka prompt, employee priv levels)

Let's review the information presented in the prompt:

=over

=item Prompt date in parentheses (defaults to current date)

=item Logged-in employee (george)

=item Privilege level of logged-in employee (passerby)

=back

The privilege level deserves closer attention. Dochazka has four privilege
levels:

=over

=item passerby

=item inactive

=item active

=item admin

=back


=head2 George the passerby

The current privilege level is determined by consulting the employee's
privilege history, which is a database table containing records for each
change in the employee's status. Employee status changes, for example, when
the employee is hired, leaves the company, goes on parental leave, etc.

Now, our test employee "george" has a password and can log in. However, he
has no privilege history so his priv level defaults to "passerby" - the
lowest possible level.

In this section, we see that passers-by cannot do much at all in Dochazka:

    $ dochazka-cli -u george -p george
    Dochazka(2016-01-29) george PASSERBY> emp=root profile
    *** REST ERROR ***

    Error encountered on attempted operation "Employee lookup"
    REST operation: GET employee/nick/root/minimal
    HTTP status: 403 Forbidden
    Explanation: DISPATCH_KEEP_TO_YOURSELF: Detected attempt by
    insufficiently privileged user to meddle in another user's affairs
    Permanent? YES

    Dochazka(2016-01-29) george PASSERBY> interval
    *** REST ERROR ***

    Error encountered on attempted operation "Get intervals for employee
    george (EID 3) in range [ 2016-01-29 00:00, 2016-01-29 24:00 )"
    REST operation: GET interval/eid/3/[ 2016-01-29 00:00, 2016-01-29 24:00
    )
    HTTP status: 403 Forbidden
    Explanation: DISPATCH_ACL_CHECK_FAILED: ACL check failed for resource
    interval/eid/:eid/:tsrange
    Permanent? YES

    Dochazka(2016-01-29) george PASSERBY> priv history
    *** Anomaly detected ***
    Status:      403 Forbidden
    Explanation: ACL check failed for resource priv/history/eid/:eid (ERR)

There are some things passers-by can do, but it is quite limited.


=head2 Make george an employee

Employees can be either "active" or "inactive". An employee is considered
inactive, for example, when she is on parental leave. The typical employee
in Dochazka will have priv level "active", so let's give george this level
of privilege.

Log in as root:

    $ dochazka-cli -u root -p immutable

Confirm the current priv level using the C<EMP=george PRIV> command:

    Dochazka(2016-01-27) root ADMIN> emp=george priv
    Privilege level of george (EID 5) as of now: passerby

Display george's priv history (which is still empty at this point):

    Dochazka(2016-01-27) root ADMIN> emp=george priv history
    *** Anomaly detected ***
    Status:      404 Not Found
    Explanation: No history for EID 5  (ERR)

Add a priv history record:

lib/App/Dochazka/CLI/Testers.pm  view on Meta::CPAN



=head1 SESSION 5: SCHEDULE HISTORY

Before you do anything, L<make sure the server is running|"Start the server">.


=head2 Verify state

If you are continuing from Session 4, you can skip this step.

If you are starting over (or from scratch), run the following script to
bring your database into the proper state:

    #!/bin/sh
    cat <<EOF | dochazka-cli -u root -p immutable
    PUT employee nick george { "fullname" : "King George III", "salt" :
    "a054d158a23c3a07ad0163107ad72a8649597d71", "passhash" :
    "5cf2c3a23de9db43d2d846172966150e9197717ecd0304bafef3f23fc159df942021dd3aec7b4dbcde87d8a44c1bd905bbba3862989065d012bb46a1e2b9ac5c"
    }
    emp=george active 2015-01-02
    schedule mon 8:00-12:00
    schedule tue 13:00-17:00
    schedule wed 8:00-12:00
    schedule wed 13:00-17:00
    schedule thu 7:00-10:00
    schedule scode VPP-1
    schedule new
    EOF


=head2 List schedules as active employee

The C<SCHEDULE FETCH ALL> generates a C<GET schedule/all> REST request to
list all schedules in the database:

    Dochazka(2016-01-30) george ACTIVE> schedule fetch all
    Schedule ID (SID): 1
    Schedule code (scode): VPP-1
    [ MON 08:00, MON 12:00 )
    [ TUE 13:00, TUE 17:00 )
    [ WED 08:00, WED 12:00 )
    [ WED 13:00, WED 17:00 )
    [ THU 07:00, THU 10:00 )

At a real Dochazka site, this might produce a lot of output. If you know
the SID or scode of a particular schedule, you can fetch just a single
schedule. Either of the following commands should produce the same output
as the one above:

    Dochazka(2016-01-30) george ACTIVE> scode=VPP-1 fetch
    ...
    Dochazka(2016-01-30) george ACTIVE> sid=1 fetch
    ...


=head2 List schedules as passerby

These commands use C<GET schedule/...> REST operations whose ACL profile is
"inactive". This can be verified by logging in as the employee C<demo>
(password C<demo>):

    $ dochazka-cli -u demo -p demo
    Dochazka(2016-01-30) demo PASSERBY> schedule fetch all
    *** Anomaly detected ***
    Status:      403 Forbidden
    Explanation: ACL check failed for resource schedule/all (ERR)

    Dochazka(2016-01-30) demo PASSERBY> scode=VPP-1 fetch
    *** Anomaly detected ***
    Status:      403 Forbidden
    Explanation: ACL check failed for resource schedule/scode/:scode (ERR)

    Dochazka(2016-01-30) demo PASSERBY> sid=1 fetch
    *** Anomaly detected ***
    Status:      403 Forbidden
    Explanation: ACL check failed for resource schedule/sid/:sid (ERR)


=head2 View schedule history as passerby

If we ask to see the schedule history of employee george, we get a slightly
different error:

    Dochazka(2016-01-30) demo PASSERBY> emp=george schedule history
    *** REST ERROR ***

    Error encountered on attempted operation "Employee lookup"
    REST operation: GET employee/nick/george
    HTTP status: 403 Forbidden
    Explanation: DISPATCH_KEEP_TO_YOURSELF: Detected attempt by
    insufficiently privileged user to meddle in another user's affairs
    Permanent? YES

Though the HTTP status is the same as before, the format of the error
message indicates that processing got a little further - this is because
the ACL profile of the C<GET employee/nick/:nick> operation is "passerby".

But this is not a discussion of Dochazka internals - let's get on to
inserting a schedule history record for george. 


=head2 Create schedule history record

Log in as root:

    $ dochazka-cli -u root -p immutable
    Dochazka(2016-01-30) root ADMIN> emp=george schedule history
    *** Anomaly detected ***
    Status:      404 Not Found
    Explanation: No history for EID 3  (ERR)

Schedule histories work analogously to privilege histories:

    Dochazka(2016-01-30) root ADMIN> emp=george scode=VPP-1 2015-01-02
    Schedule history record (SHID 1) added
    Dochazka(2016-01-30) root ADMIN> emp=george schedule history
    Schedule history of george (EID 3):

    SHID Effective date SID scode Remark
    1    2015-01-02     1   VPP-1       



( run in 1.083 second using v1.01-cache-2.11-cpan-ceb78f64989 )