summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/api.md128
-rw-r--r--doc/api/file.md284
-rw-r--r--doc/api/user.md113
-rw-r--r--doc/setup.md24
4 files changed, 549 insertions, 0 deletions
diff --git a/doc/api.md b/doc/api.md
new file mode 100644
index 000000000..7ac67705d
--- /dev/null
+++ b/doc/api.md
@@ -0,0 +1,128 @@
+# API
+
+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.0`.
+
+### 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 |
+
+## General response structure
+
+Replies will always contain a `status` field which can contain the following
+values: `success`, `error`. If the reply does not contain the status field
+it should be regarded as invalid.
+
+If `status=success` the reply will contain a `data` field which contains
+function specific data.
+
+### Error handling
+
+If `status=error` the reply 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 |
+
+## Endpoints
+
+All return values below assume success unless stated otherwise and are the
+content of the `data` field mentioned above.
+
+```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,
+}
+```
+
+For the examples 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"
+```
diff --git a/doc/api/file.md b/doc/api/file.md
new file mode 100644
index 000000000..6f5489511
--- /dev/null
+++ b/doc/api/file.md
@@ -0,0 +1,284 @@
+### 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. |
+
+| error_id | Message | Note |
+| -------- | ------- | ---- |
+| file/no-file | No file was uploaded or unknown error occurred | |
+| 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/"
+ ]
+ }
+}
+```
+
+### 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'' |
+
+### 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"
+}
+```
+
+### 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. |
+
+| error_id | Message | Note |
+| -------- | ------- | ---- |
+| 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'' |
diff --git a/doc/api/user.md b/doc/api/user.md
new file mode 100644
index 000000000..f90c92e55
--- /dev/null
+++ b/doc/api/user.md
@@ -0,0 +1,113 @@
+### 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"
+}
+```
+
diff --git a/doc/setup.md b/doc/setup.md
new file mode 100644
index 000000000..f01a2ab6b
--- /dev/null
+++ b/doc/setup.md
@@ -0,0 +1,24 @@
+# Setup
+
+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" )
+```