Göteborg Bit Factory                                                  June 2013

                        Writing a Client for Taskserver
                                   Version 1


Status of this Memo

   This document provides information for the Internet community.  It does not
   specify an Internet standard of any kind.  Distribution of this document is
   not restricted.


Copyright Notice

   Copyright (C) 2010 - 2014, Göteborg Bit Factory.


Abstract

   A Taskserver client is a todo-list manager.  It may be as simple as a
   program that captures a single task, as complex as Taskwarrior, or anything
   in between.  It can be a mobile client, a web application, or any other type
   of program.

   This document describes how such a client would interact with the server.


Table of Contents

   1      Introduction
   1.1    Requirements
   2      Taskserver Account
   2.1      Credentials
   2.2      Registration
   3      Description of a Taskserver client
   3.1      Encryption
   3.2      Configuration
   3.3      Local Storage
   3.4      Local Changes
   3.5      Remote Changes
   3.6      Sync Key
   3.7      Data Integrity
   6      Synchronizing
   4.1      Establish Encrypted Connection
   4.2      Sync Request
   4.3      Sync Response
   4.4      Server Messages
   5      Server Errors
   6      Example Requests
   6.1      Request: First Sync
   6.2      Request: Sync No Data
   6.3      Request: Sync Data
   6.4      Response: No Data
   6.5      Response: Remote Data
   6.6      Response: Error
   6.7      Response: Relocate
   6.8      Response: Message
   7      Reference Implementation
   8      References
   9      Acknowledgements
   10     Authors' Addresses
   11     Full Copyright Statement


1  Introduction

   A client to the Taskserver is a program that manages a task list, and wishes
   to exchange data with the server so that the task list may be shared.

   In order to do this, a client must store tasks locally, upload local changes,
   download remote changes, and apply remote changes to the local tasks.

   The client must consider that there may be no network connectivity, or no
   desire by the user to synchronize.

   The client will need proper credentials to talk to the server.


1.1  Requirements

   In this document, we adopt the convention discussed in Section 1.3.2 of
   [RFC1122] of using the capitalized words MUST, REQUIRED, SHOULD, RECOMMENDED,
   MAY, and OPTIONAL to define the significance of each particular requirement
   specified in this document.

   In brief: "MUST" (or "REQUIRED") means that the item is an absolute
   requirement of the specification; "SHOULD" (or "RECOMMENDED") means there may
   exist valid reasons for ignoring this item, but the full implications should
   be understood before doing so; and "MAY" (or "OPTIONAL") means that this item
   is optional, and may be omitted without careful consideration.


2  Taskserver Account

   A Taskserver account must be created.  This process creates a storage area,
   and generates the necessary credentials.


2.1  Credentials

   A Taskserver client needs the following credentials in order to communicate
   with a server:

      - Server address and port
      - Organization name
      - User name
      - Password
      - Certificate
      - Key

   The server address and port are the network location of the server.  An
   example of this value is:

      tasktools.org:53589

   In addition to a DNS name, this can be an IPv4 or IPv6 address.

   The organization name is an arbitrary grouping, and is typically 'PUBLIC',
   reflecting the individual nature of server accounts.  Future capabilities
   will provide functionality that support groups of users, called an
   organization.

   The user name is the full name.  This will be the name used to identify other
   users in an organization, in a future release.  Example 'John Doe'.

   The password is a text string generated by the server at account creation
   time.  It should be considered a secret.

   The certificate is an X.509 PEM file generated by the server at account
   creation time.  This is used for authentication.  It should be considered a
   secret.

   The key is an X.509 PEM file generated by the server at account creation
   time.  This is used for encryption.  It should be considered a secret.

   These credentials need to be stored on the client, and used during the sync
   operation.


2.2  Registration

   Registration is the process of creating an account and receiving user
   credentials.  It is a process run once per account.

   -------------

   Note: This section is to be completed when the online registration site is
         operational, and will include examples of how to manually and
         programmatically obtain credentials.

   -------------


3  Description of a Taskserver client

   This section describes how a client might behave in order to facilitate
   integration with the Taskserver.


3.1  Encryption

   The Taskserver only communicates using encryption.  Therefore all user data
   is encrypted while in transit.  The Taskserver currently uses GnuTLS
   [GnuTLS] to support this encryption, and therefore supports the following
   protocols:

      SSL 3.0
      TLS 1.0
      TLS 1.1
      TLS 1.2

   The client may use any library that supports the above.


3.2  Configuration

   The client needs to store configuration, which matches the credentials needed
   for Taskserver communication.  See section 2.1 "Credentials".

   The credentials may not be modified by the user without losing server access.

   The server:port data may need to be changed automatically following a
   redirect response from the server.  See section 5 "Server Errors".


3.3  Local Storage

   The client needs to store task data locally.  The client will need to be able
   to find tasks by their UUID and overwrite them.  Uploaded and downloaded task
   changes will use the Taskwarrior Data Interchange Format [Task JSON].


3.4  Local Changes

   Whenever local data is modified, that change MUST be synced with the server.
   But this does not have to occur immediately, in fact the client SHOULD NOT
   assume connectivity at any time.

   A client SHOULD NOT also assume that the server is available.  If the server
   is not available, the local changes should be retained, and the sync
   operation repeated later.

   Ideally the client will give the user full control over sync operations.
   Automatically syncing after all local modifications is not recommended.  If a
   client performs too many sync operations, the server MAY revoke the
   certificate.

   Effectively, the client should maintain a separate list of tasks changed
   since the last successful sync operation.

   Note that tasks have a "modification" attribute, which should be updated
   whenever a change is made.  This attribute contributes to conflict
   resolution on the server.


3.5  Remote Changes

   When a server sends remote changes to a client, in the response to a sync
   request, the changes have already been merged by the server, and therefore
   the client should simply store them intact.

   Based on the UUID in the task, the client can determine whether a task is
   new (and should be added to the local list of tasks), or whether it
   represents a modification (and should overwrite it's existing entry).

   The client MUST NOT perform any merges.


3.6  Sync Key

   Whenever a sync is performed, the server responds by sending a sync key and
   any remote changes.  The sync key is important, and should be included in the
   next sync request.  The client is REQUIRED to store the sync key in every
   server response message.

   If a client omits the sync key in a sync message, the response will be a
   complete set of all tasks and modifications.


3.7  Data Integrity

   Although a task is guaranteed to contain at least 'entry', 'description' and
   'uuid' attributes, it may also contain other known fields, and unknown
   user-defined fields.  An example might be an attribute named 'estimate'.

   If a task is received via sync that contains an attribute named 'estimate',
   then a client has the responsibility of preserving the attribute intact.  If
   that data is shown, then it is assumed to be of type 'string', which is the
   format used by JSON for all values.

   Conversely, if a client wishes to add a custom attribute, it is guaranteed
   that the server and other clients will preserve that attribute.

   Using this rule, two clients of differing capabilities can exchange data and
   still maintain custom attributes.

   This is a requirement.  Any client that does not obey this requirement is
   broken.


4  Synchronizing

   Synchronizing with the Taskserver consists of a single transaction.  Once an
   encrypted connection is made with the server, the client MUST compose a
   sync request message (See [Message]).  This message includes credentials and
   local changes.  The response message contains status and remote changes,
   which MUST be stored locally.


4.1  Establish Encrypted Connection

   All communication with the Taskserver is encrypted using the certificate
   and key provided to each user.  Using the 'server' configuration setting,
   establish a connection.


4.2  Sync Request

   For message format details, see [Message].  A sync request MUST contain a
   sync key if one was provided by a previous sync.  A sync request MUST contain
   a list of modified tasks, in JSON format (see [Task JSON]), if local
   modifications have been made.


4.3  Sync Response

   A sync response WILL contain a 'code' and 'status' header variable, WILL
   contain a sync key in the payload, and MAY contain a list of tasks from the
   server in JSON format (see [Task JSON]).


4.4  Server Messages

   There are cases when the server needs to inform the user of some condition.
   This may be anticipated server downtime, for example.  The response message
   is typically not present, but may be present in the header, containing a
   string:

      ...
      message: Scheduled maintenance 2013-07-14 08:00UTC for 10 minutes.
      ...

   If such a message is returned by the server, it SHOULD be made available to
   the user.  This is a recommendation, not a requirement.


5  Server Errors

   The server may generate many errors (See [Protocol]), but the following is a
   list of the ones most in need of special handling:

      200 Success
      201 No change
      301 Redirect
      430 Access denied
      431 Account suspended
      432 Account terminated
      5xx Error

   The 200 indicates success, and that a change was recorded.  The 201 indicates
   success but no changes were necessary.  The 301 is a redirect message
   indicating that the client MUST re-request from a new server.  The 43x series
   messages are account-related.  Any 5xx series code is a server error of some
   kind.  All errors consist of a code and a status message:

      code: 200
      status: Success


6  Examples

   Here are examples of properly formatted request and response messages.  Note
   that the messages are indented for clarity in this document, but is not the
   case in a properly formatted message.  Also note that newline characters
   U+000D are not shown, but are implied by the separate lines.  Because some
   messages have trailing newline characters, the text is delimited by the 'cut'
   markers:

      ----8<----
      foo

      ----8<----

   The example above illustrates text consisting of:

      U+0066   f
      U+006F   o
      U+006F   o
      U+000D   newline
      U+000D   newline

   Note that these values are left unspecified, but should be clear from the
   context, and the [Message] format spec:

      <size>
      <organization>
      <user>
      <password>


6.1  Request: First Sync

   The first time a client syncs, there is (perhaps) no data to upload, and no
   sync key from a previous sync.

      ----8<----
      <size>type: sync
      org: <organization>
      user: <user>
      key: <password>
      client: task 2.3.0
      protocol: v1

      ----8<----

   Note the double newline character separating header from payload, with an
   empty payload.


6.2  Request: Sync No Data

   Ordinarily when a client syncs, there is a sync key from the previous sync
   response to send.  This example shows a sync with no local changes, but a
   sync key from a previous sync.

      ----8<----
      <size>type: sync
      org: <organization>
      user: <user>
      key: <password>
      client: task 2.3.0
      protocol: v1

      2e4685f8-34bc-4f9b-b7ed-399388e182e1
      ----8<----


6.3  Request: Sync Data

   This sync request shows a sync key from the previous sync, and a locally
   modified task.

      ----8<----
      <size>type: sync
      org: <organization>
      user: <user>
      key: <password>
      client: task 2.3.0
      protocol: v1

      2e4685f8-34bc-4f9b-b7ed-399388e182e1
      {"description":"An example","uuid":"8ad2e3db-914d-4832-b0e6-72fa04f6e331",...}
      ----8<----


6.4  Response: No Data

   If a sync results in no downloads to the client, the response will look like
   this.

      ----8<----
      <size>type: response
      client: taskd 1.0.0
      protocol: v1
      code: 200
      status: Ok

      45da7110-1bcc-4318-d33e-12267a774e0f
      ----8<----

   Note that there is a sync key which must be stored and used in the next sync
   request, but there are no remote changes to store.


6.5  Response: Remote Data

  This shows a sync response providing a new sync key, and a remote change to
  two tasks.

      ----8<----
      <size>type: response
      client: taskd 1.0.0
      protocol: v1
      code: 200
      status: Ok

      45da7110-1bcc-4318-d33e-12267a774e0f
      {"description":"Test data","uuid":"8ad2e3db-914d-4832-b0e6-72fa04f6e331",...}
      {"description":"Test data2","uuid":"3b6218f9-726a-44fc-aa63-889ff52be442",...}
      ----8<----

   Note that the sync key must be stored for the next sync request.

   Note that the two changed tasks must be stored locally, and if the UUID in
   the tasks matches local tasks, then the local tasks must be overwritten.


6.6  Response: Error

      ----8<----
      <size>type: response
      client: taskd 1.0.0
      protocol: v1
      code: 431
      status: Account suspended

      ----8<----

   Note the double newline character separating header from payload, with an
   empty payload.


6.7  Response: Relocate

      ----8<----
      <size>type: response
      client: taskd 1.0.0
      protocol: v1
      code: 301
      status: Redirect
      info: <new-server>

      ----8<----

   Note the 'info' field will contain a '<server>:<port>' string that should be
   used for all future sync requests.  This indicates that a user account was
   moved to another server.

   Note the double newline character separating header from payload, with an
   empty payload.


6.8  Response: Message

   Occasionally the server will need to convey a message, and will include an
   additional header variable containing that message.

   The server [Protocol] states that the message SHOULD be shown to the user.
   This message will be used for system event messages, used rarely, and never
   used for advertising or promotion.

      ----8<----
      <size>type: response
      client: taskd 1.0.0
      protocol: v1
      code: 200
      status: Ok
      message: Scheduled maintenance 2013-07-14 08:00UTC for 10 minutes.

      45da7110-1bcc-4318-d33e-12267a774e0f
      ----8<----

   Note that the same message will likely be included in consecutive responses.


7  Reference Implementation

   The Taskserver codebase contains a reference implementation of an SSL/TLS
   client and server program, which communicate text strings.

      taskd.git/src/tls/Makefile             # To build the example
      taskd.git/src/tls/README               # How to run the example
      taskd.git/src/tls/TLSClient.cpp        # TLS client code
      taskd.git/src/tls/TLSClient.h
      taskd.git/src/tls/TLSServer.cpp        # TLS Server code
      taskd.git/src/tls/TLSServer.h
      taskd.git/src/tls/c.cpp                # Client program
      taskd.git/src/tls/s.cpp                # Server program

   The Taskwarrior codebase, version 2.3.0+, is the reference implementation.

      task.git/src/TLSClient.cpp             # TLS client code
      task.git/src/TLSClient.h
      task.git/src/commands/CmdSync.cpp      # Sync implementation
      task.git/src/commands/CmdSync.h


8  References

   [RFC640] Postel, J., "Revised FTP Reply Codes", RFC 640, June,
        1975.

   [RFC1122] IETF, "Requirements for Internet Hosts - Communication
        Layers", October 1989.

   [GnuTLS] http://www.gnutls.org/manual/gnutls.html

   [Task JSON] "Taskwarrior Data Interchange Format", taskd.git/doc/task.txt

   [Message] "Taskserver Message Format", taskd.git/doc/request.txt

   [Protocol] "Taskserver Protocol", taskd.git/doc/protocol.txt


9  Acknowledgements

   Thanks to ... for testing and feedback.

   Thanks to ... whose comments helped improve this document.


10  Authors' Addresses

   Federico Hernandez
   Email: fredde@taskwarrior.org

   Paul Beckingham
   Email: paul@taskwarrior.org


11  Full Copyright Statement

   Copyright 2010 - 2014, Göteborg Bit Factory.
   All rights reserved.

   This document and translations of it may be copied and furnished to others,
   and derivative works that comment on or otherwise explain it or assist in its
   implementation may be prepared, copied, published and distributed, in whole
   or in part, without restriction of any kind, provided that the above
   copyright notice and this paragraph are included on all such copies and
   derivative works.  However, this document itself may not be modified in any
   way, such as by removing the copyright notice or by omission of certain
   sections.

   The limited permissions granted above are perpetual and will not be revoked
   by the authors or their successors or assigns.

   This document and the information contained herein is provided on an "AS IS"
   basis and the authors disclaim all warranties, express or implied, including
   but not limited to any warranty that the use of the information herein will
   not infringe any rights or any implied warranties of merchantability or
   fitness for a particular purpose.

---

