]po[ REST Interface

The ]po[ "intranet-rest" package implements a Web-Service that exposes most of the ]project-open[ system to external applications that need to read and write ]po[ objects.

REST Interface Overview

The ]po[ “intranet-rest” package allows 3rd party applications to integrate conveniently with a ]project-open[ backend application. External applications are allowed to Create, Read, Update and List important ]po[ objects.



HTTP “GET” HTTP “POST”
Object Type
Resource
“L=Lists”:
Lists all object
of that object type.
“C=Create”:
Creates a new instance
of the object type.
Individual Object
Resource
“R=Read”:
Retrieves all fields
of the specified object
“U=Update”:
Updates the specified
object.

“D=Delete”: Delete ("nuke") operations are not supported with this REST interface for the same reasons deleting is not supported via the Web GUI.

REST Java Client Reference Application

Please visit PO Time Sheet  @ SourceForge  to get an idea about what is possible using the ]po[ REST interface.

"]po[ Time Sheet" is a Java client application for Windows, Linux and Mac OSX that allows a user to log hours against a project hierarchy. It is also capable to browse a great part of the ]po[ object types and shows objects in a table view.

The application has been written as a reference application. Users can obtain the source code for Eclipse easily via a CVS checkout.


(A screen shot of the time sheet logging screen)


Download and Installation

The ]po[ "intranet-rest" package is part of the ]po[ V4.0 release, so that you don't need to download the package. Please note that the REST interface for ]po[ V3.5 was experimental and has several known issues, so that we strongly suggest to develop with ]po[ V4.0.

FAQs

Application Scenarios

The following application scenarios are supported by the ]po[ REST interface:

  • Project Reporting:
    An external applications report into ]project-open[ the creation of new projects, their financial status, and their completion degree.

  • Time Sheet Reporting:
    An external application captures employee’s timesheet hours and reports them to ]project-open[.
    Please see PO-Timesheet  @ SourceForge  for reference.

  • AJAX Task Management GUI:
    An AJAX GUI allows users to keep track of tasks (project, milestones, timesheet tasks, translation tasks, forum tasks) assigned to the user and to mark tasks as done.

Design Goals

The REST Web-service was designed to fulfill the following goals:

  • Completeness:
    Expose all ]po[ objects as a Web service, not just a few. Provide the means for external applications to actually replace ]po[.
  • REST standards:
    Follow the best practices or REST interfaces as defined by Roy Fielding implemented by important examples of REST interfaces.

  • Open for unprivileged Users:
    Use tight permissions to allow all users (including unprivileged profiles like customers or freelancers) to use the REST interface, not just for system administrators. Show restricted users only the appropriate objects and restrict the update operations to objects where the user have write permissions.

 

REST Version

The ]po[ REST protocol (the names and structure of the tags sent and received) is released in versions. Version numbers consist of two digits (for example: "1.0"):

  • The first digit represents the "major" version number (for example: "1").
    Changes in this first digit indicate incompatibility with all previous versions.
  • The second digit represents the "minor" version number (for example: "0").
    Changes in the second digit indicate upward compatibility (increased functionality, while not affecting existing functionality).

To get the server version number please visit the URL http://<your_server>/intranet-rest/version.

Please see the |REST version history

REST V1.0 Interface Details

L=List Operation

  • Objective:
    Retrieve a list of objects that match certain criteria.
  • Implementation:
    A HTTP GET operation on object type resource page returns an XML structure with a list of references to object resource pages.
  • Request example:
    http://localhost/intranet-rest/im_project?format=xml&query=project_status_id=76
  • Result example:
    <?xml version='1.0'?>
    <object_list>
    <object_id href="http://localhost/intranet-rest/im_project/13074">13074</object_id>
    ...
    </object_list>
  • URL format:
    http://localhost/intranet-rest/<object_type>
    where object_type is one of the supported REST object types.
    • format={xml|html}: Determines output format (see below)
    • limit=<integer>: Limits the number of returned objects
    • query=<SQL where clause>: Limits objects listed. The SQL where clause allows AND and OR conditions with the operators “=“, “<“, “>”, “<=“, “>=“, “like” and “in”.

R=Read Operation

  • Objective:
    Retrieve all information about one specific object.
  • Implementation:
    A HTTP GET operation on an object’s resource page returns an XML structure with a list of the object’s attributes.
  • Request example:
    http://localhost/intranet-rest/im_project/12345?format=xml
  • Result example:
    <?xml version='1.0'?>
    <im_project>
    <project_id>12345</
    project_id>
    <project_name>System Specification</project_name>
    <project_nr>2005_0027</project_nr>
    <company_id href="http://localhost/intranet-rest/im_company/8720">8720</company_id>
    ...(a list of ~60 attributes from the im_projects table)
    </im_project>
  • URL format:
    http://localhost/intranet-rest/<object_type>/<object_id> where
    object_type is one of the supported REST object types and
    object_id is a ]po[ object of type object_type.
    • format={xml | html}: Determines output format (see below).
  • Result format:
    • The result document consists of a single XML tag named “object_type” containing all attributes from the object’s SQL tables”. For example, the result for the object type “im_timesheet_task” will return all columns from the table acs_objects, im_projects and im_timesheet_tasks, because im_timesheet_task is a sub-type of im_project, which in turn is a sub-type of acs_object.
    • The result attributes includes DynField dynamic fields and manually added database columns.
    • Every attribute will be returned in the format: <attribute_name>attribute_value</attribute_name> where “attribute_name” is the column in the object’s table and “attribute_value” is the value of the attribute as returned by the underlying PostgreSQL database and its default formatting.
    • Certain XML attributes representing references to other ]po[ objects will include an additional “href” XML attribute: href="http://192.168.140.128::8000/intranet-rest/im_company/8720"
    • In case an attribute name exists as a column in more then one object’s table, an undefined value is returned. Therefore, please do not create DynField or other columns with ambiguous names.

U=Update Operation

  • Objective:
    Update one or more attributes of an object.
  • Implementation:
    A HTTP POST operation on the object resource page updates the attributes included in the POST operation’s content XML structure.
  • Request example:
    http://localhost/intranet-rest/im_project/12345
    The following POST content will update the project’s “budget_hours” field:
    <?xml version='1.0'?>
    <im_project>
    <budget_hours>10000</budget_hours>
    </im_project>
  • Result example:
    The call will return a HTTP 200 code on success, or an error code plus an error message otherwise. The database may reject update operations because of referential integrity constraints, unique indices and other constraints. In such a case, the REST interface will return an error.
  • URL format:
    http://localhost/intranet-rest/<object_type>/<object_id> where
    • object_id is a valid object of the supported REST object_type.
    • The POST content may contain any of the object’s attributes, surrounded by an XML tag with the name of the object_type. In particular, the POST content may include the XML document returned by a previous R=Read operation on the object.
    • Certain attributes in the POST content are ignored during the update process, because they refer to ]po[ internal management mechanisms. Ignored attributes include:
      • “Index columns” (primary keys of an object’s tables)
      • Any attributes related to acs_object (creation_user, creation_date, 
)
      • Attributes related to tree managemet (“tree_sortkey” and “max_child_sortkey”)
      • Attributes ending with “_cache” (representing im_project’s cached financial information)

C=Create

Please note that not all ]po[ objects support a C=Create operation. This is because create operations need to be coded manually, as opposed to the automatic processing of RUL operations via the ]po[ DynField SQL metadata system.

  • Objective:
    Create a new object of a specified object type
  • Implementation:
    A HTTP POST operation on the object resource page creates a new object.
  • Request example:
    http://localhost/intranet-rest/im_project
    The following POST content will create a new project. For the meaning of project_type_id and project_status_id please see the data model documentation:
    <?xml version='1.0'?>
    <im_project>
    <project_name>Test Project 001</project_name>
    <project_nr>2009_1234</project_nr>
    <project_path>2009_1234</project_path>
    <company_id>8773</company_id>
    <parent_id></parent_id>
    <project_type_id>2501</project_type_id>
    <project_status_id>76</project_status_id>
    </im_project>
  • Result example:
    The call will return an XML document with a 200 code on success:
    <?xml version='1.0'?> <object_id>$rest_oid</object_id>
    or an HTTP error code and an error message otherwise. Please note that the creation of objects are constraint by PostgreSQL database referential integrity, unique and other constraints, which are outside of the scope of this document.
  • URL format:
    http://localhost/intranet-rest/<object_type> where
    • object_type is a supported ]po[ REST object type.
  • The HTTP POST XML structure behaves the same as with the U=Update command.
  • Currently (2010-02-17) only im_project, [im_trans_task], im_invoice and im_invoice_item support C=Creation operations. Other objects types will follow soon.
  • Please see the REST Object Creation documentation on the details of creating objects.

REST Authentication

Authentication of the REST API is managed per user. Users are granted the same access right as with the Web GUI. This mechanism includes the case of external users including customers and providers.  

The REST WS provides a choice of three different authentication mechanisms:

  • REST Basic HTTP Authentication:
    ]po[ accepts standard username/password combinations via HTTP “Basic” authentication”. You can find out about a user's username either in the user's home page or in the cc_users.username field. You need to set the parameter EnableUsersUsernameP to 1 in order to tell the ]po[ GUI to show the username as part of the normal UserViewPage.

  • OpenACS Cookie Authentication:
    The standard OpenACS authentication allows you to explore the REST API interactively in HTML format. The fact that you see this page right now is due to cookie authentication. However, cookie authentication is not very useful for machine-machine communication...
  • REST Auto-Login Token:
    An auto-login token is a hashed password. To determine a user's auto-login token please visit the URL /intranet-rest/auto-login. This page will return an auto-login token for a user who has authenticated via Cookie or Basic Auth.

Basic HTTP Authentication

BASIC HTTP Authentication is defined in RFC 2617 (http://www.ietf.org/rfc/rfc2617.txt) and explained in http://en.wikipedia.org/wiki/Basic_access_authentication. ]po[ accepts standard username/password or email/password combinations.

The following example assumes that the user “Ben Bigboss” has username=bbigboss and password=ben. Getting the list of all projects accessible for Ben Bigboss using the “wget” command line utility (available on Linux and CygWin for Windows):

wget -O - --user=bbigboss --password=ben http://192.168.140.128:8000/intranet-rest/im_project 

Depending on your version of "wget" , you may have add the option "--auth-no-challenge" to your wget command.
Use "--no-check-certificate" if you use a self-signed certificate.

The output will look like:

<?xml version='1.0'?>
<object_list>
<object_id href="http://192.168.140.128::8000/intranet-rest/im_project/13074">13074</object_id>
. . .
</object_list>

OpenACS Cookie Authentication

“OpenACS Cookie Authentication” represents the standard OpenACS authentication. You are automatically authenticated when you have entered your email/password at the ]po[ application. Then please enter to the local URL /intranet-rest/ in your local server.

As a result, you will see a HTML view to the REST interface, allowing you to browse the data in HTML mode.

Auto-Login Token Authentication

An "auto-login token" is a hashed password. The auto-login authentication mechanism allows to authenticate a user with URL parameters, making it the ideal mechanism for AJAX interfaces etc.

To determine your user's auto-login token please enter the URL: /intranet-rest/auto-login. This page will return an auto-login token for your user like this one:

  • User ID: 624
  • Name: System Administrator
  • Username: sysadmin
  • Auto-Login Token: 41909DE9FEB3B556C6C7266F246E03A43403E852

The /intranet-rest/auto-login?format=xml will return the auto_login token in XML format.

Now you can get the list of all projects accessible for Ben Bigboss using the “wget” command line utility by passing the user_id and the auto_login token as part of the URL:

wget -O - "http://192.168.140.128:8000/intranet-rest/im_project?user_id=8864&auto_login=6AD9391BE60089BBD551AE9535775EFE78A9AB5C"

Please observe the double quotes (“”) round the URL, because the “&” has a special meaning as part of a Linux command line.

REST Permissions

The REST interface allows to set permissions per object type and user group, effectively allowing users to use client-side applications, widgets etc. using the REST interface, instead of the normal Web GUI.

The screenshot below shows the REST permission administration screen. In this screen you can set R=Read and W=Write permissions per object type and user profile.

Special permissions apply to the following object types:

  • im_company
  • im_cost
  • im_expense
  • im_invoice
  • im_project

These object types feature per-user permission in addition to the per-user-profile permission set in the administration screen below.

In the same way as project and the other objects can be limited to individual users being a "member" of a project in the Web GUI, these permissions apply in the REST interface. So a user effectively needs two permissions to R=Read a project:

  • A general R=Read in the permission administration screen below and
  • The general permission to read the project (i.e. the user needs to be a member of the project or be in a profile with the privilege "view_projects_all").

Rest Admin Panel

Encoding and Formatting

  • URL variables are supposed to be encoded using “%” URL encoding according to RFC 1738 (http://www.ietf.org/rfc/rfc1738.txt)

  • All documents returned by the REST interface are available in the formats “xml” and “html”.
    The URL parameter format={xml|html} determines output format.
    “Html” is default for cookie authentication (using the REST via a browser). “Xml” is the default otherwise.

  • All XML documents sent and received are encoded in UTF-8 format.

  • HTML documents are only designed to be human readable, no specific encoding is defined.

Error Messages and Error Return Codes

The REST interface returns standard HTTP error codes:

  • 200 OK: Success!
  • 304 Not Modified: There was no new data to return.
  • 400 Bad Request: The request was invalid. An accompanying error message will explain why.
  • 401 Not Authorized: Authentication credentials were missing or incorrect.
  • 403 Forbidden: The request is understood, but it has been refused.  An accompanying error message will explain why.
  • 404 Not Found: The URI requested is invalid or the resource requested, for example a non-existing project.
  • 406 Not Acceptable: Returned by the Search API when an invalid format is specified in the request.
  • 500 Internal Server Error: Something is broken.  Please post to the ]po[ “Open Discussions” forum.
  • 502 Bad Gateway: ]project-open[ is probably down.
  • 503 Service Unavailable: ]project-open[ is up, but overloaded with requests. Try again later.

In case of an error, there will be an explicit error message:

<?xml version='1.0' encoding='UTF-8'?>
<error>
    <http_status>403</http_status>
    <http_status_message>
        Forbidden: The request is understood, but it has been refused.
    </http_status_message>
    <request>
        /intranet-rest/im_project?query=project%5fstatuss%5fid+in+%2876%2c71%29
    </request>
    <message>
        The specified query is not a valid SQL where clause: 'project_status_id = (76,71)‘
    </message>
</error>

Supported ]po[ Object Types

Not all ]po[ object types are supported by the REST interface, and not all object types currently support all CRUL operations. The following table specifies the current status of the interface:

  • RUL - group
  • RUL - im_biz_object_member
  • CRUL - im_company
  • CRUL - im_company_employee_rel
  • RUL - im_conf_item
  • RUL - im_conf_item_project_rel
  • RUL - im_cost_center
  • RUL - im_expense
  • RUL - im_expense_bundle
  • RUL - im_forum_topic
  • RUL - im_fs_file
  • RUL - im_invoice(please see Howto Create Financial Documents)
  • CRUL - im_key_account_rel
  • RUL - im_material
  • RUL - im_office
  • RUL - im_profile
  • CRUL - im_project
  • RUL - im_release_item
  • RUL - im_rest_object_type
  • CRUL - im_ticket
  • RUL - im_ticket_queue
  • CRUL - im_ticket_ticket_rel
  • RUL - im_timesheet_invoice
  • CRUL - im_timesheet_task
  • CRUL - im_trans_invoice
  • RUL - im_trans_task
  • CRUL - im_user_absence
  • CRUL - membership_rel
  • RUL - party
  • RUL - person
  • RUL - relationship
  • CRUL - user

ToDo

  • Perform a complete white box security check
  • Implement a HTML GUI for creating and updating object interactively

References

Package Documentation

Procedure Files

tcl/intranet-rest-authentication-procs.tcl       REST Web Service Component Library - Authentication 
tcl/intranet-rest-create-procs.tcl       REST Web Service Component Library 
tcl/intranet-rest-data-source-procs.tcl       REST Web Service Component Library 
tcl/intranet-rest-get-procs.tcl       REST Web Service Component Library 
tcl/intranet-rest-post-procs.tcl       REST Web Service Component Library 
tcl/intranet-rest-procs.tcl       REST Web Service Component Library 
tcl/intranet-rest-sql-parser-procs.tcl       REST Web Service Library Utility functions 
tcl/intranet-rest-util-procs.tcl       REST Web Service Library Utility functions 
tcl/intranet-rest-validator-procs.tcl       REST Web Service Validator 

Procedures

im_quotejson       Quote a JSON string. 
im_rest_authenticate       Determine the authenticated user 
im_rest_call       Handler for all REST calls 
im_rest_call_delete       Handler for DELETE rest calls 
im_rest_call_get       Handler for GET rest calls 
im_rest_call_post       Handler for GET rest calls 
im_rest_call_put       Handler for PUT rest calls 
im_rest_cookie_auth_user_id       Determine the user_id even if ns_conn doesn't work in a HTTP PUT call 
im_rest_debug_headers       Show REST call headers 
im_rest_delete_object       Handler for DELETE rest calls to an individual object: Update the specific object using a generic update procedure 
im_rest_deref_plpgsql_functions       Returns a key-value list of dereference functions per table-column. 
im_rest_doc_return       This is a replacement for doc_return that values if the gzip_p URL parameters has been set. 
im_rest_error       Returns a suitable REST error message 
im_rest_get_content       This is a hack to get the content of the REST request. 
im_rest_get_im_categories       Handler for GET rest calls on invoice items. 
im_rest_get_im_dynfield_attributes       Handler for GET rest calls on dynfield attributes 
im_rest_get_im_hour_intervals       Handler for GET rest calls on timesheet hour intervals 
im_rest_get_im_hours       Handler for GET rest calls on timesheet hours 
im_rest_get_im_indicator_result_interval       Handler for GET rest calls on indicator results 
im_rest_get_im_invoice_items       Handler for GET rest calls on invoice items. 
im_rest_get_im_timesheet_task_dependencies       Handler for GET rest calls on task dependencies 
im_rest_get_object_type       Handler for GET rest calls on a whole object type - mapped to queries on the specified object type 
im_rest_get_rest_columns       Reads the "columns" URL variable and returns the list of selected REST columns or an empty list if the variable was not specified. 
im_rest_hard_coded_deref_plpgsql_functions       Returns a key-value list of hard coded attribues per object type. 
im_rest_header_extra_stuff       Returns a number of HTML header code in order to make the REST interface create reasonable HTML pages. 
im_rest_normalize_timestamp       Reformat JS date/timestamp format to suit PostgreSQL 8.4/9.x 
im_rest_object_type_columns       Returns a list of all columns for a given object type. 
im_rest_object_type_index_columns       Returns a list of all "index columns" for a given object type. 
im_rest_object_type_order_sql       returns an "ORDER BY" statement for the *_get_object_type SQL. 
im_rest_object_type_pagination_sql       Appends pagination information to a SQL statement depending on URL parameters: "LIMIT $limit OFFSET $start". 
im_rest_object_type_select_sql       Calculates the SQL statement to extract the value for an object of the given rest_otype. 
im_rest_object_type_subtypes       Returns a list of all object types equal or below rest_otype (including rest_otype). 
im_rest_object_type_update_sql       Updates all the object's tables with the information from the hash array. 
im_rest_page       The user has requested /intranet-rest/index or /intranet-rest/data-source/* 
im_rest_parse_json_content       Parse the JSON content of a POST request with the values of the object to create or update. 
im_rest_post_object       Handler for POST rest calls to an individual object: Update the specific object using a generic update procedure 
im_rest_post_object_im_hour       Handler for POST calls on particular im_hour objects. 
im_rest_post_object_im_hour_interval       Handler for POST calls on particular im_hour_interval objects. 
im_rest_post_object_type       Handler for POST rest calls to an object type - create a new object. 
im_rest_post_object_type_im_biz_object_member       Create a new object and return the object_id. 
im_rest_post_object_type_im_company       Create a new Company and return the company_id. 
im_rest_post_object_type_im_company_employee_rel       Create a new object and return the object_id. 
im_rest_post_object_type_im_hour       Create a new Timesheet Hour line and return the item_id. 
im_rest_post_object_type_im_hour_interval       Create a new Timesheet Hour line and return the item_id. 
im_rest_post_object_type_im_invoice       Create a new Financial Document and return the task_id. 
im_rest_post_object_type_im_invoice_item       Create a new Financial Document line and return the item_id. 
im_rest_post_object_type_im_key_account_rel       Create a new object and return the object_id. 
im_rest_post_object_type_im_note       Handler for POST calls on particular im_note objects. 
im_rest_post_object_type_im_project       Create a new object and return the object_id. 
im_rest_post_object_type_im_sencha_column_config       Handler for POST calls on particular im_sencha_column_config objects. 
im_rest_post_object_type_im_sencha_preference       Handler for POST calls on particular im_sencha_preference objects. 
im_rest_post_object_type_im_ticket       Create a new object and return its object_id 
im_rest_post_object_type_im_ticket_ticket_rel       Create a new object and return the object_id. 
im_rest_post_object_type_im_timesheet_task       Create a new object and return its object_id 
im_rest_post_object_type_im_timesheet_task_dependency       Create a new task dependency and return the id. 
im_rest_post_object_type_im_trans_invoice       Create a new object and return the object_id 
im_rest_post_object_type_im_trans_task       Create a new object and return the object_id. 
im_rest_post_object_type_im_user_absence       Create a new User Absence and return the company_id. 
im_rest_post_object_type_membership_rel       Create a new object and return the object_id. 
im_rest_post_object_type_user       Create a new User object return the user_id. 
im_rest_project_task_tree_action       Create, Update or Delete a task coming from TreeStore 
im_rest_project_task_tree_assignees       Update the resource assignees to the task 
im_rest_project_task_tree_create       Create a new task coming from TreeStore 
im_rest_project_task_tree_delete       Delete a task coming from TreeStore 
im_rest_project_task_tree_predecessors       Update the resource predecessors to the task 
im_rest_project_task_tree_update       Update a task coming from TreeStore 
im_rest_system_url       Returns a the system's "official" URL without trailing slash suitable to prefix all hrefs used for the JSON format. 
im_rest_valid_sql       Returns 1 if "where_clause" is a valid where_clause or 0 otherwise. 
im_rest_validate_call       Performs a REST call and returns the results. 
im_rest_validate_list       Checks permissions to "list" on all object types 
im_rest_validate_projects       Checks permissions on ]po[ projects 
im_rest_version       Returns the current server version of the REST interface. 
sql_assert       Checks that the string str is of sql type "type". 
sql_between        
sql_compare        
sql_containing        
sql_exact        
sql_from_table_reference        
sql_function        
sql_function_count        
sql_in        
sql_integer        
sql_keyword        
sql_like        
sql_name        
sql_non_assert       Checks that the string str is NOT of sql type "type". 
sql_operator        
sql_procedure_end        
sql_search_condition        
sql_search_value        
sql_select        
sql_starting        
sql_test       Executes a number of checks 
sql_value_litteral        

SQL Files

sql/postgresql/intranet-rest-create.sql        
sql/postgresql/intranet-rest-drop.sql        

Content Pages

www/
      auto-login.adp
      auto-login.tcl Home page for REST service, when accessing from the browser.
     data-source/
           auto-login-token.tcl Provide the user with cookies and a login token
           domain-proxy.adp
           domain-proxy.tcl Fetches a page from www.project-open.net
           next-object-id.adp
           project-task-tree-action.adp
           project-task-tree-action.tcl
           project-task-tree.json.adp
           project-task-tree.json.tcl Returns a JSON tree structure suitable for batch-loading a project TreeStore
           success.adp
      dynfield-widget-values.adp
      dynfield-widget-values.tcl
      index.adp
      index.tcl
      version.adp
      version.tcl
 

 

  Contact Us
  Project Open Business Solutions S.L.

Calle Aprestadora 19, 12o-2a

08902 Hospitalet de Llobregat (Barcelona)

Spain

 Tel Europe: +34 609 953 751
 Tel US: +1 415 200 2465
 Mail: info@project-open.com