diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/api.md | 161 | ||||
-rw-r--r-- | doc/api/file.md | 307 | ||||
-rw-r--r-- | doc/api/user.md | 123 | ||||
-rw-r--r-- | doc/setup.md | 28 |
4 files changed, 619 insertions, 0 deletions
diff --git a/doc/api.md b/doc/api.md new file mode 100644 index 000000000..3484acd2b --- /dev/null +++ b/doc/api.md @@ -0,0 +1,161 @@ +# API + +**Table of Contents** + +- [General notes](#general-notes) + - [URLs](#urls) + - [Compatibility](#compatibility) + - [Unless stated otherwise ...](#unless-stated-otherwise-) + - [Access levels](#access-levels) +- [Endpoints](#endpoints) + - [Examples](#examples) +- [Error handling](#error-handling) + - [General errors](#general-errors) +- [Overview over API versions](#overview-over-api-versions) + +The API provides programmatic access to upload, delete files, view the +currently uploaded ones and combine them to multipastes, as well as functions +to manage api keys. Responses are available in JSON. + +## General notes + +### URLs + +The URLs for API endpoints start with the base URL followed by `/api/`, the +version supported by the client and the endpoint. For example: +`https://paste.xinu.at/api/v1.0.0/some/endpoint`. + +The version number follows the [semantic versioning guidelines](http://semver.org/). +The requested version number must be of the format `vX[.X[.X]]` with X being +a positive number. `v1` and `v1.0` will both be treated as `v1.0.0`. + +The most recent API version is `v2.1.1`. + +### Compatibility + +The API will evolve by adding and removing endpoints, parameters and keywords. +Unknown keywords should be treated gracefully by your application. + +Behavior not documented here should not be expected to be available and may be +changed without notice. + +### Unless stated otherwise ... + + +* ... requests should be sent via POST. +* ... endpoints expect an apikey with access level `apikey` to be sent with the request. +* ... requests should not be assumed to be atomic (i.e. data may be changed on the server despite an error being returned). + + +* ... timestamps are returned as UNIX timestamps (seconds). +* ... sizes are returned in bytes. +* ... values are specific to the user owning the apikey (e.g. the `total_size` field of file/history). + + +* ... errors will generate a response with `status=error`. +* ... error messages may differ from those listed in the tables. +* ... errors listed are only the most common ones (i.e. the lists are non-exhaustive). + +### Access levels + +An api key can have one of the following access levels. Levels further down in +the table include those above themselves. + +| access-level | Comment | +| ------------ | ------- | +| basic | Allows only uploading of files | +| apikey | Allows to delete uploads and view the history | +| full | Allows everything | + +## Endpoints + +Documentation for specific endpoints can be found in `./doc/api/`: + +* [Documentation for the /file/ endpoints](api/file.md) +* [Documentation for the /user/ endpoints](api/user.md) + +Responses will always contain a `status` field which can contain the following +values: `success`, `error`. If the response does not contain the status field +it should be regarded as invalid. + +If `status=success` the response will contain a `data` field which contains +function specific data. + + +```javascript +// General definitions + +// Listed above +access-level: String; + +// An api key +apikey: String; + +// An ID that can be used to display a multipaste or a single file +upload-id: String; + + +// General success response +responseSuccess = { + "status": "success", + "data": object or array, // Differs per endpoint. Refer to the specific endpoint documentation. +} +``` + +### Examples + +For the examples given in the endpoint documentation, set the following +variables in your shell. Please note that they and their values will show up in +your shell history and in top/ps if used. Be careful on untrusted systems. + +```bash +apikey="anApiKey" +base="https://paste.xinu.at/api/v2.0.0" +``` + +## Error handling + +If `status=error` the response will be of the following format: + +```javascript +// Error response format +responseError = { + "status": "error", + "message": "A message that can be displayed to the user", + "error_id": "program/useable/error/id", + "data": object or array, // optional, only used if mentioned +} +``` + + +### General errors + +These are the most common errors that can be returned by any API call. + +| error_id | Message | Note | +| -------- | ------- | ---- | +| api/invalid-version | Invalid API version requested | Failed syntax check | +| api/invalid-endpoint | Invalid endpoint requested | Failed syntax check | +| api/version-not-supported | Requested API version is not supported | | +| api/unknown-endpoint | Unknown endpoint requested | Likely a typo in your URL | +| internal-error | An unhandled internal server error occured | | +| user/api-login-failed | API key login failed | | +| api/insufficient-permissions | Access denied: Access level too low | | +| api/not-authenticated | Not authenticated | Likely no apikey was sent | + +## Overview over API versions + +| Version | Endpoint | Note | +| ------- | -------- | ---- | +| 2.2.0 | file/create_multipaste | Add paramter ''minimum-id-length'' to control the length of generated content id | +| 2.2.0 | file/upload | Add parameter ''minimum-id-length'' to control the length of generated content id | +| 2.1.1 | file/history | Empty objects (values of `items` and `multipaste_items`) are now always returned as {}. Before they were returned as [] | +| 2.1.1 | file/delete | Empty objects (values of `errors` and `deleted`) are now always returned as {}. Before they were returned as [] | +| 2.1.0 | file/history | Add ''item.thumbnail'' | +| 2.0.0 | file/history | Add ''multipaste_item.date'' | +| 2.0.0 | file/history | Remove private fields in response | +| 1.4.0 | file/get_config | Add data.{max_input_vars,request_max_size} | +| 1.3.0 | file/create_multipaste | Allow multipaste creation for basic access level | +| 1.2.0 | user/delete_apikeys | Add this endpoint | +| 1.1.0 | file/create_multipaste | Add url key to response | +| 1.0.0 | * | Initial API version | diff --git a/doc/api/file.md b/doc/api/file.md new file mode 100644 index 000000000..0dcf6a8ad --- /dev/null +++ b/doc/api/file.md @@ -0,0 +1,307 @@ +# /file API endpoints + +**Table of Contents** + +- [file/get_config](#fileget_config) +- [file/upload](#fileupload) +- [file/history](#filehistory) +- [file/delete](#filedelete) +- [file/create_multipaste](#filecreate_multipaste) + +## file/get_config + +Request method: GET +This is a public method and does not require an apikey. + +Return some useful values that may differ between service installations/subsequent requests. + +Success response: +```javascript +// Success response +responseSuccess.data = { + // Maximum size of a single file + "upload_max_size": int, + + // Maximum number of files sent with one request + "max_files_per_request": int, + + // Maximum number of variables sent with one request + // (be sure to account for the api key when using this) + "max_input_vars": int, + + // Maximum size of a complete request + "request_max_size": int, +} +``` + +Example: +``` +> curl -s $base/file/get_config | json_pp +{ + "data" : { + "max_files_per_request" : 20, + "upload_max_size" : 1073741824, + "request_max_size" : 1073741824, + "max_input_vars" : 1000 + }, + "status" : "success" +} +``` + +| Version | Change | +| ------- | ------ | +| 1.4.0 | Add data.{max_input_vars,request_max_size} | + +## file/upload + +Required access level: `basic` + +Upload a new file. + +| POST field | Type | Comment | +| ---------- | ---- | ------- | +| file[`<index>`] | File | Required. Arbitrary index. | +| minimum-id-length | Int | Optional. Values >= 2 only | + +| error_id | Message | Note | +| -------- | ------- | ---- | +| file/no-file | No file was uploaded or unknown error occurred | | +| file/bad-minimum-id-length | Invalid value passsed to bad-minimum-id-length | | +| file/upload-verify | Failed to verify uploaded file(s) | This error provides additional detail | + +```javascript +// Success response +responseSuccess.data = { + "ids": [upload-id, ...], + "urls": [String, ...], +} + +// Error file/upload-verify +responseError.data = { + String-formfield: { + "filename": String, // from the request + "formfield": String-formfield, // from the request, this is the same as the key of this object + "message": String, // can be displayed to the user + }, + ... +} +``` + +Example: +``` +> echo test | curl -s $base/file/upload -F apikey=$apikey -F "file=@-" | json_pp +{ + "status" : "success", + "data" : { + "ids" : [ + "uu28" + ], + "urls" : [ + "http://filebin.localhost/uu28/" + ] + } +} +``` + +| Version | Change | +| ------- | ------ | +| 2.2.0 | Add parameter ''minimum-id-length'' to control the length of generated content id | + +## file/history + +Return the currently available files/multipastes. + +```javascript +// Definitions +item = { + "id": upload-id, + "filename": String, + "mimetype": String, + "date": Timestamp, + "hash": String, + "filesize": int, + "thumbnail": String, // URL. only set when there is a thumbnail available +} + +multipaste_item = { + "url_id": upload-id, + "id": upload-id, // this references item.id described above + "date": Timestamp, +} + +// Success response +responseSuccess.data = { + "items": {item.id: item, ...}, + "multipaste_items": {multipaste_item.url_id: multipaste_item, ...}, + "total_size": int, // total size of all files (excluding duplicates) +} +``` + +Example: +``` +> curl -s $base/file/history -F apikey=$apikey | json_pp +{ + "status" : "success", + "data" : { + "multipaste_items" : { + "m-JcK" : { + "items" : { + "oeL" : { + "id" : "oeL" + }, + "7kn" : { + "id" : "7kn" + } + }, + "url_id" : "m-JcK", + "date" : "1444119317" + } + }, + "total_size" : "164006", + "items" : { + "oeL" : { + "id" : "oeL", + "hash" : "098f6bcd4621d373cade4e832627b4f6", + "date" : "1444119317", + "filename" : "test2", + "filesize" : "4", + "mimetype" : "text/plain" + }, + "7kn" : { + "date" : "1444119317", + "hash" : "6a72c253e8e9e6d01544f1c6b4573e6e", + "id" : "7kn", + "thumbnail" : "http://filebin.localhost/file/thumbnail/7kn", + "mimetype" : "image/jpeg", + "filesize" : "164001", + "filename" : "Relax.jpg" + }, + "l7p" : { + "date" : "1444116077", + "hash" : "cfcd208495d565ef66e7dff9f98764da", + "id" : "l7p", + "mimetype" : "application/octet-stream", + "filesize" : "1", + "filename" : "stdin" + } + } + } +} +``` + +| Version | Change | +| ------- | ------ | +| 2.0.0 | Add ''multipaste_item.date''. Remove ''multipaste_item.{multipaste_id,user_id}''. | +| 2.1.0 | Add ''item.thumbnail'' | +| 2.1.1 | Empty objects (values of `items` and `multipaste_items`) are now always returned as {}. Before they were returned as [] | + +## file/delete + +Delete files or multipastes. Multipastes containing deleted files will also be silently removed. + +Note: This function returns some errors in the success response. + +| POST field | Type | Comment | +| ---------- | ---- | ------- | +| ids[`<index>`] | upload-id | Required. Arbitrary index. | + +| error_id | Message | Note | +| -------- | ------- | ---- | +| file/delete/no-ids | No IDs specified | | + +```javascript +// Success response +responseSuccess.data = { + "errors": { + upload-id: { + "id": upload-id, // this is the same as the key of this object + "reason": String, + }, + ... + }, + "deleted": { + upload-id: { + "id": upload-id, // this is the same as the key of this object + }, + ... + }, + "total_count": int, + "deleted_count": int, +} +``` + + +Example: +``` +> curl -s $base/file/delete -F apikey=$apikey -F "ids[1]=uu28" | json_pp +{ + "data" : { + "errors" : {}, + "total_count" : 1, + "deleted" : { + "uu28" : { + "id" : "uu28" + } + }, + "deleted_count" : 1 + }, + "status" : "success" +} +``` + +| Version | Change | +| ------- | ------ | +| 2.1.1 | Empty objects (values of `errors` and `deleted`) are now always returned as {}. Before they were returned as [] | + +## file/create_multipaste + +Required access level: `basic` + +Create a new multipaste. + +| POST field | Type | Comment | +| ---------- | ---- | ------- | +| ids[`<index>`] | upload-id | Required. Arbitrary index. This only accepts IDs of files, not other multipastes. | +| minimum-id-length | Int | Optional. Values >= 2 only | + +| error_id | Message | Note | +| -------- | ------- | ---- | +| file/bad-minimum-id-length | Invalid value passsed to bad-minimum-id-length | | +| file/create_multipaste/no-ids | No IDs specified | | +| file/create_multipaste/duplicate-id | Duplicate IDs are not supported | | +| file/create_multipaste/verify-failed | Failed to verify ID(s) | This error provides additional detail | + +```javascript +// Success response +responseSuccess.data = { + "url_id": upload-id, + "url": String, // Complete URL to url_id +} + +// Error file/create_multipaste/verify-failed +responseError.data = { + upload-id: { + "id": upload-id, // this is the same as the key of this object + "reason": String, + }, + ... +} +``` + +Example: +``` +> curl -s $base/file/create_multipaste -F apikey=$apikey -F "ids[1]=uu28" | json_pp +{ + "data" : { + "url" : "http://filebin.localhost/m-J250b/", + "url_id" : "m-J25Ob" + }, + "status" : "success" +} +``` + +| Version | Change | +| ------- | ------ | +| 1.1.0 | Add url key to response | +| 1.3.0 | Change required access level from ''apikey'' to ''basic'' | +| 2.2.0 | Add paramter ''minimum-id-length'' to control the length of generated content id | diff --git a/doc/api/user.md b/doc/api/user.md new file mode 100644 index 000000000..33959fcc2 --- /dev/null +++ b/doc/api/user.md @@ -0,0 +1,123 @@ +# /user API endpoints +**Table of Contents** + +- [user/apikeys](#userapikeys) +- [user/create_apikey](#usercreate_apikey) +- [user/delete_apikey](#userdelete_apikey) + +## user/apikeys + +Required access level: `full` + +Return apikeys of the user. + +```javascript +// Success response +responseSuccess.data = { + "apikeys": { + apikey: { + "key": apikey, // this is the same as the key of this object + "created": Timestamp, + "comment": String, + "access_level": access-level, + }, + ... + }, +] +``` + +Example: +``` +> curl -s $base/user/apikeys -F apikey=$apikey | json_pp +{ + "data" : { + "apikeys" : { + "Sa71PVwKthRrrIEUIacqN9PNTouVQAWz" : { + "key" : "Sa71PVwKthRrrIEUIacqN9PNTouVQAWz", + "comment" : "fb-client flo@Marin", + "created" : 1378389775, + "access_level" : "full" + }, + } + }, + "status" : "success" +} +``` + +## user/create_apikey + +Required access level: `full` + +Create a new apikey. + +This is the only endpoint that may be called without an apikey, but with username and password instead. Sending both, username/password and an api key results in undefined behaviour. + +| POST field | Type | Comment | +| ---------- | ---- | ------- | +| username | String | Required if not called with api key. | +| password | String | Required if not called with api key. | +| access_level | access-level | Required | +| comment | String | Optional but recommended (username, hostname, client software name, ...). Maximum 255 chars. | + + +```javascript +// Success response +responseSuccess.data = { + "new_key": String, +} +``` + +Example: +``` +> curl -s $base/user/create_apikey -F username=test -F password=test -F access_level=apikey -F "comment=This is a test key" | json_pp +{ + "data" : { + "new_key" : "2qXhd9E4ezBE53KiRtB5EE95r6m6ZeI1" + }, + "status" : "success" +} +``` + +## user/delete_apikey + +Required access level: `full` + +Delete an apikey. + +| POST field | Type | Comment | +| ---------- | ---- | ------- | +| delete_key | apikey | Key to delete | + +| error_id | Message | Note | +| -------- | ------- | ---- | +| user/delete_apikey/failed | Apikey deletion failed. Possibly wrong owner. | | + +```javascript +// Success response +responseSuccess.data = { + "deleted_keys": { + apikey: { + "key": apikey, // this is the same as the key of this object + }, + }, +} +``` + +Example: +``` +> curl -s $base/user/delete_apikey -F apikey=$apikey -F delete_key=o0fDrc0LF8Kemqb9qzXXaScGsz9XCegj | json_pp +{ + "data" : { + "deleted_keys" : { + "o0fDrc0LF8Kemqb9qzXXaScGsz9XCegj" : { + "key" : "o0fDrc0LF8Kemqb9qzXXaScGsz9XCegj" + } + } + }, + "status" : "success" +} +``` + +| Version | Change | +| ------- | ------ | +| 1.2.0 | Add this endpoint | diff --git a/doc/setup.md b/doc/setup.md new file mode 100644 index 000000000..c955437b2 --- /dev/null +++ b/doc/setup.md @@ -0,0 +1,28 @@ +# Setup + +For installation instructions follow `./INSTALL`. + +## Fancy URLs + +Set `$config['index_page'] = '';` in `application/config/config-local.php` and adjust your webserver's rewrite config. + +### Apache + +See the shipped htaccess.txt + +### Nginx + +``` +location / { + try_files $uri $uri/ @ee; +} +location @ee { + rewrite ^(.*) /index.php?$1 last; +} +``` + +### Lighttpd + +``` +url.rewrite-if-not-file = ( "^(.*)$" => "/index.php/?$1" ) +``` |