bitbucket -> github

This commit is contained in:
gnieark 2017-05-11 23:10:01 +02:00
parent 803b36ed3d
commit eeac0740d2
20 changed files with 543 additions and 548 deletions

View File

@ -1,10 +1,38 @@
# Dotclear REST API # Dotclear REST API
Plugin dotclear ouvrant une API REST/JSON Plugin to serve a Rest/JSON API on Dotclear.
C'est en cours de développement et est loin d'être fini. This is a work in progress. API definitions and specifications are not stables. Its will be more exhaustive.
Real time code repository is https://bitbucket.org/gnieark/dc-rest-api
# Install:
Make a zip of this repository and install it on your Dotclear Blog.
# License
Dotclear rest/json plugin.
Copyright (C) [Gnieark](https://blog-du-grouik.tinad.fr/)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
# Third-party code
## Dotclear
The content management system Dotclear http://dotclear.org/ licensed under
GNU GENERAL PUBLIC LICENSE Version 2, June 1991
Les spécifications swagger seront modifiées au fur et à mesure du développement de l'API. ## SwaggerUI
Pour le moment elles sont basées sur la structure de la base de données et ne sont pas exhaustives. Documentation and the tool to test the API is a third party code integrated on this plugin:
A terme, elles seront basées plus sur les fonctions de dotclear. Swagger-UI https://github.com/swagger-api/swagger-ui Licensed under the Apache License, Version 2.0

View File

@ -4,6 +4,6 @@ if (!defined('DC_CONTEXT_ADMIN')) { return; }
$_menu['Blog']->addItem(__('Rest API'), $_menu['Blog']->addItem(__('Rest API'),
'plugin.php?p=rest', 'plugin.php?p=rest',
urldecode(dcPage::getPF('rest/rest_api_256x256.png')), urldecode(dcPage::getPF('rest/rest_api.png')),
preg_match('/plugin.php\?p=rest(&.*)?$/',$_SERVER['REQUEST_URI']), preg_match('/plugin.php\?p=rest(&.*)?$/',$_SERVER['REQUEST_URI']),
$core->auth->check('contentadmin',$core->blog->id)); $core->auth->check('contentadmin',$core->blog->id));

View File

@ -7,4 +7,8 @@ $__autoload['RestQuery'] = dirname(__FILE__).'/inc/class.rest.query.php';
$__autoload['RestQueryGetBlogs'] = dirname(__FILE__).'/inc/class.rest.query.get.blogs.php'; $__autoload['RestQueryGetBlogs'] = dirname(__FILE__).'/inc/class.rest.query.get.blogs.php';
$__autoload['RestQueryGetBlog'] = dirname(__FILE__).'/inc/class.rest.query.get.blog.php'; $__autoload['RestQueryGetBlog'] = dirname(__FILE__).'/inc/class.rest.query.get.blog.php';
$__autoload['RestQueryGetSpecs'] = dirname(__FILE__).'/inc/class.rest.query.get.specs.php'; $__autoload['RestQueryGetSpecs'] = dirname(__FILE__).'/inc/class.rest.query.get.specs.php';
$__autoload['RestQueryPostBlogs'] = dirname(__FILE__).'/inc/class.rest.query.post.blogs.php'; $__autoload['RestQueryPostBlogs'] = dirname(__FILE__).'/inc/class.rest.query.post.blogs.php';
$__autoload['ResQueryPatchBlogs'] = dirname(__FILE__).'/inc/class.rest.query.patch.blogs.php';
$__autoload['ResQueryPutBlogs'] = dirname(__FILE__).'/inc/class.rest.query.put.blogs.php';
$__autoload['ResQueryDeleteBlogs'] = dirname(__FILE__).'/inc/class.rest.query.delete.blogs.php';
$__autoload['RestQueryGetBlogSettings'] = dirname(__FILE__).'/inc/class.rest.query.get.blog.settings.php';

View File

@ -23,15 +23,15 @@ class rest extends dcUrlHandlers
}elseif($args == 'specs'){ }elseif($args == 'specs'){
$queryObj = new RestQueryGetSpecs(); $queryObj = new RestQueryGetSpecs();
break; break;
}elseif(preg_match('^blogs/(.+)$', $args )){ }elseif(preg_match('/^blogs\/(.*)$/', $args )){
///blogs/{blog-id}
$queryObj = new RestQueryGetBlog($args); $queryObj = new RestQueryGetBlog($args);
break;
}elseif(preg_match('/^(.*)\/settings$/', $args )){
$queryObj = new RestQueryGetBlogSettings($args);
break; break;
} }
///blogs/{blog-id}
break; break;
case "POST": case "POST":
if($args == 'blogs'){ if($args == 'blogs'){
@ -40,15 +40,25 @@ class rest extends dcUrlHandlers
break; break;
case "PUT": case "PUT":
if(preg_match('/^blogs\/(.*)$/', $args )){
$queryObj = new ResQueryPutBlogs($args,$body);
break;
}
break; break;
case "PATCH": case "PATCH":
if(preg_match('/^blogs\/(.*)$/', $args )){
$queryObj = new ResQueryPatchBlogs($args,$body);
break;
}
break; break;
case "DELETE": case "DELETE":
if(preg_match('/^blogs\/(.*)$/', $args )){
$queryObj = new ResQueryDeleteBlogs($args,$body);
break;
}
break; break;
default: default:
$queryObj = new RestQuery(); $queryObj = new RestQuery();
@ -101,7 +111,7 @@ class rest extends dcUrlHandlers
$core->auth = false; $core->auth = false;
} }
$r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,file_get_contents('php://input')); $r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,file_get_contents('php://input'));
header($r->response_code); header($r->get_full_code_header());
echo json_encode($r->response_message); echo json_encode($r->response_message);
} }

View File

@ -56,10 +56,17 @@ paths:
$ref: '#/definitions/blog' $ref: '#/definitions/blog'
required: true required: true
responses: responses:
'200': '201':
description: array containing the new blog's identifiant description: 'Success, array containing the new blog''s identifiant'
schema: schema:
$ref: '#/definitions/Ids' type: object
properties:
code:
type: integer
blog_id:
type: integer
message:
type: string
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
@ -78,9 +85,7 @@ paths:
required: true required: true
responses: responses:
'200': '200':
description: >- description: 'Core blog properties. use {blog_id}/settings methods for more settings.'
array containing blog properties. This list of attributes is not
exhaustive.
schema: schema:
$ref: '#/definitions/blogProperties' $ref: '#/definitions/blogProperties'
'404': '404':
@ -118,9 +123,7 @@ paths:
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
put: put:
summary: >- summary: 'Overwrite blog Properties (if an optional parameter is not set, his value will be erased by the default value)'
Overwrite blog Properties (if a parameter is not set, his value will be
erased by de default value)
parameters: parameters:
- name: x_dc_key - name: x_dc_key
in: header in: header
@ -135,7 +138,7 @@ paths:
description: This list of parameters is not exhaustive description: This list of parameters is not exhaustive
required: true required: true
schema: schema:
$ref: '#/definitions/blogProperties' $ref: '#/definitions/blogPropertiesPut'
responses: responses:
'200': '200':
description: array containing the edited blog's identifiant description: array containing the edited blog's identifiant
@ -169,6 +172,28 @@ paths:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
'/{blog_id}/settings':
get:
summary: 'Get the about:config'
description: Get all parameters
parameters:
- name: x_dc_key
in: header
type: string
required: true
- name: blog_id
in: path
type: string
required: true
responses:
'200':
description: OK
'404':
description: this blog id does not exists
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog-id}/posts': '/{blog-id}/posts':
get: get:
summary: Get list of posts summary: Get list of posts
@ -194,9 +219,7 @@ paths:
items: items:
type: string type: string
required: false required: false
description: >- description: 'Fields you want to get. If unset, fields are post_id, post_url, post_status, post_title, post_date'
Fields you want to get. If unset, fields are post_id, post_url,
post_status, post_title, post_date
responses: responses:
'200': '200':
description: list of posts description: list of posts
@ -222,9 +245,7 @@ paths:
required: true required: true
- name: properties - name: properties
in: body in: body
description: >- description: Some non required fields you don't define will be set (default value) by the API
Some non required fields you don't define will be set (default
value) by the API
schema: schema:
$ref: '#/definitions/new_dc_post' $ref: '#/definitions/new_dc_post'
responses: responses:
@ -489,164 +510,34 @@ definitions:
id: id:
type: integer type: integer
description: New blog id description: New blog id
blogPropertiesPut:
required:
- blog_id
- blog_name
- blog_url
- blog_desc
type: object
properties:
blog_id:
type: string
blog_name:
type: string
blog_url:
type: string
blog_desc:
type: string
blogProperties: blogProperties:
type: object type: object
properties: properties:
id: blog_id:
type: string type: string
name: blog_name:
type: string type: string
url: blog_url:
type: string type: string
description: blog_desc:
type: string type: string
author:
type: string
allow_comments:
type: boolean
allow_trackbacks:
type: boolean
blog_timezone:
type: string
comment_preview_optional:
type: string
comments_nofollow:
type: boolean
comments_pub:
type: boolean
comments_ttl:
type: integer
copyright_notice:
type: string
csp_admin_default:
type: string
csp_admin_img:
type: string
csp_admin_on:
type: boolean
csp_admin_report_only:
type: boolean
csp_admin_script:
type: string
csp_admin_style:
type: string
date_format:
type: string
date_formats:
type: array
items:
type: string
format: string
editor:
type: string
enable_html_filter:
type: boolean
enable_xmlrpc:
type: boolean
import_feed_ip_regexp:
type: string
import_feed_no_private_ip:
type: boolean
import_feed_port_regexp:
type: string
import_feed_url_control:
type: boolean
inc_subcats:
type: boolean
jquery_migrate_mute:
type: boolean
jquery_version:
type: string
lang:
type: string
media_exclusion:
type: string
media_flash_fallback:
type: boolean
media_img_default_alignment:
type: string
media_img_default_legend:
type: string
media_img_default_link:
type: string
media_img_default_size:
type: string
media_img_m_size:
type: integer
media_img_no_date_alone:
type: string
media_img_s_size:
type: integer
media_img_t_size:
type: integer
media_img_title_pattern:
type: string
media_img_use_dto_first:
type: string
media_video_height:
type: integer
media_video_width:
type: integer
nb_comment_per_feed:
type: integer
nb_post_for_home:
type: integer
nb_post_per_feed:
type: integer
nb_post_per_page:
type: integer
no_search:
type: boolean
note_title_tag:
type: string
post_url_format:
type: string
prevents_clickjacking:
type: string
public_path:
type: string
public_url:
type: string
robots_policy:
type: string
short_feed_items:
type: boolean
simpleMenu:
type: array
items:
type: string
simpleMenu_active:
type: boolean
store_plugin_url:
type: string
store_theme_url:
type: string
theme:
type: string
themes_path:
type: string
themes_url:
type: string
time_format:
type: string
time_formats:
type: array
items:
type: string
tpl_allow_php:
type: boolean
tpl_use_cache:
type: boolean
trackbacks_pub:
type: boolean
trackbacks_ttl:
type: integer
url_scan:
type: string
use_smilies:
type: boolean
wiki_comments:
type: boolean
new_dc_post: new_dc_post:
type: object type: object
required: required:

View File

@ -1,5 +0,0 @@
<?php
?>
<h1>Hey</h1>

View File

@ -1,93 +0,0 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body {
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
<defs>
<symbol viewBox="0 0 20 20" id="unlocked">
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
</symbol>
<symbol viewBox="0 0 20 20" id="locked">
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="close">
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="large-arrow">
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="large-arrow-down">
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
</symbol>
<symbol viewBox="0 0 24 24" id="jump-to">
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
</symbol>
<symbol viewBox="0 0 24 24" id="expand">
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
</symbol>
</defs>
</svg>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"> </script>
<script src="./swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "http://dotclear.localhost/dotclear/index.php?rest/specs",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
</script>
</body>
</html>

View File

@ -1,4 +1,6 @@
<!DOCTYPE html> <?php
if (!defined('DC_RC_PATH')) { return; }
?><!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">

View File

@ -83,10 +83,21 @@
} }
], ],
"responses": { "responses": {
"200": { "201": {
"description": "array containing the new blog's identifiant", "description": "Success, array containing the new blog's identifiant",
"schema": { "schema": {
"$ref": "#/definitions/Ids" "type": "object",
"properties": {
"code": {
"type": "integer"
},
"blog_id": {
"type": "integer"
},
"message": {
"type": "string"
}
}
} }
}, },
"default": { "default": {
@ -117,7 +128,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "array containing blog properties. This list of attributes is not exhaustive.", "description": "Core blog properties. use {blog_id}/settings methods for more settings.",
"schema": { "schema": {
"$ref": "#/definitions/blogProperties" "$ref": "#/definitions/blogProperties"
} }
@ -177,7 +188,7 @@
} }
}, },
"put": { "put": {
"summary": "Overwrite blog Properties (if a parameter is not set, his value will be erased by de default value)", "summary": "Overwrite blog Properties (if an optional parameter is not set, his value will be erased by the default value)",
"parameters": [ "parameters": [
{ {
"name": "x_dc_key", "name": "x_dc_key",
@ -197,7 +208,7 @@
"description": "This list of parameters is not exhaustive", "description": "This list of parameters is not exhaustive",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/blogProperties" "$ref": "#/definitions/blogPropertiesPut"
} }
} }
], ],
@ -254,6 +265,40 @@
} }
} }
}, },
"/{blog_id}/settings": {
"get": {
"summary": "Get the about:config",
"description": "Get all parameters",
"parameters": [
{
"name": "x_dc_key",
"in": "header",
"type": "string",
"required": true
},
{
"name": "blog_id",
"in": "path",
"type": "string",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "this blog id does not exists"
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/{blog-id}/posts": { "/{blog-id}/posts": {
"get": { "get": {
"summary": "Get list of posts", "summary": "Get list of posts",
@ -741,240 +786,43 @@
} }
} }
}, },
"blogPropertiesPut": {
"required": [
"blog_id",
"blog_name",
"blog_url",
"blog_desc"
],
"type": "object",
"properties": {
"blog_id": {
"type": "string"
},
"blog_name": {
"type": "string"
},
"blog_url": {
"type": "string"
},
"blog_desc": {
"type": "string"
}
}
},
"blogProperties": { "blogProperties": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "blog_id": {
"type": "string" "type": "string"
}, },
"name": { "blog_name": {
"type": "string" "type": "string"
}, },
"url": { "blog_url": {
"type": "string" "type": "string"
}, },
"description": { "blog_desc": {
"type": "string" "type": "string"
},
"author": {
"type": "string"
},
"allow_comments": {
"type": "boolean"
},
"allow_trackbacks": {
"type": "boolean"
},
"blog_timezone": {
"type": "string"
},
"comment_preview_optional": {
"type": "string"
},
"comments_nofollow": {
"type": "boolean"
},
"comments_pub": {
"type": "boolean"
},
"comments_ttl": {
"type": "integer"
},
"copyright_notice": {
"type": "string"
},
"csp_admin_default": {
"type": "string"
},
"csp_admin_img": {
"type": "string"
},
"csp_admin_on": {
"type": "boolean"
},
"csp_admin_report_only": {
"type": "boolean"
},
"csp_admin_script": {
"type": "string"
},
"csp_admin_style": {
"type": "string"
},
"date_format": {
"type": "string"
},
"date_formats": {
"type": "array",
"items": {
"type": "string",
"format": "string"
}
},
"editor": {
"type": "string"
},
"enable_html_filter": {
"type": "boolean"
},
"enable_xmlrpc": {
"type": "boolean"
},
"import_feed_ip_regexp": {
"type": "string"
},
"import_feed_no_private_ip": {
"type": "boolean"
},
"import_feed_port_regexp": {
"type": "string"
},
"import_feed_url_control": {
"type": "boolean"
},
"inc_subcats": {
"type": "boolean"
},
"jquery_migrate_mute": {
"type": "boolean"
},
"jquery_version": {
"type": "string"
},
"lang": {
"type": "string"
},
"media_exclusion": {
"type": "string"
},
"media_flash_fallback": {
"type": "boolean"
},
"media_img_default_alignment": {
"type": "string"
},
"media_img_default_legend": {
"type": "string"
},
"media_img_default_link": {
"type": "string"
},
"media_img_default_size": {
"type": "string"
},
"media_img_m_size": {
"type": "integer"
},
"media_img_no_date_alone": {
"type": "string"
},
"media_img_s_size": {
"type": "integer"
},
"media_img_t_size": {
"type": "integer"
},
"media_img_title_pattern": {
"type": "string"
},
"media_img_use_dto_first": {
"type": "string"
},
"media_video_height": {
"type": "integer"
},
"media_video_width": {
"type": "integer"
},
"nb_comment_per_feed": {
"type": "integer"
},
"nb_post_for_home": {
"type": "integer"
},
"nb_post_per_feed": {
"type": "integer"
},
"nb_post_per_page": {
"type": "integer"
},
"no_search": {
"type": "boolean"
},
"note_title_tag": {
"type": "string"
},
"post_url_format": {
"type": "string"
},
"prevents_clickjacking": {
"type": "string"
},
"public_path": {
"type": "string"
},
"public_url": {
"type": "string"
},
"robots_policy": {
"type": "string"
},
"short_feed_items": {
"type": "boolean"
},
"simpleMenu": {
"type": "array",
"items": {
"type": "string"
}
},
"simpleMenu_active": {
"type": "boolean"
},
"store_plugin_url": {
"type": "string"
},
"store_theme_url": {
"type": "string"
},
"theme": {
"type": "string"
},
"themes_path": {
"type": "string"
},
"themes_url": {
"type": "string"
},
"time_format": {
"type": "string"
},
"time_formats": {
"type": "array",
"items": {
"type": "string"
}
},
"tpl_allow_php": {
"type": "boolean"
},
"tpl_use_cache": {
"type": "boolean"
},
"trackbacks_pub": {
"type": "boolean"
},
"trackbacks_ttl": {
"type": "integer"
},
"url_scan": {
"type": "string"
},
"use_smilies": {
"type": "boolean"
},
"wiki_comments": {
"type": "boolean"
} }
} }
}, },

View File

@ -0,0 +1,52 @@
<?php
class ResQueryDeleteBlogs extends RestQuery
{
//$core->delBlog($blog_id);
public function __construct($args){
global $core;
$this->blog_id = substr($args,6);
$this->required_perms = 'admin';
//Is allowed?
if($this->is_allowed() === false){
//need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'You need to be admin to patch a blog');
return;
}
//does the blog exists?
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
try{
$core->delBlog($this->blog_id);
$this->response_code = 201;
$this->response_message = array(
'code' => 200,
'message' => 'Successfully deleted blog '.$this->blog_id
);
}
catch (Exception $e)
{
$this->response_code = 500;
$this->response_message = array(
'code' => 500,
'message' => $e->getMessage()
);
}
}
}

View File

@ -4,24 +4,50 @@
*/ */
class RestQueryGetBlog extends RestQuery class RestQueryGetBlog extends RestQuery
{ {
public function __construct(){ public function __construct($args)
{
global $core; global $core;
}
$this->blog_id = substr($args,6);
/* $this->required_perms = 'unauth';
* ça se complique niveau droits if($this->is_allowed() === false){
* //need To be authentified
* SI L'utilisateur n'est pas authentifié $this->response_code = 403;
* le blog est hors ligne $this->response_message = array('code' => 403, 'error' => 'This API is not open without KEY');
* -> 404 return;
* l'API n'est pas publique }
* -> refus //instance
* l'API est publique if($core->auth === false){
* -> OK, mais on ne retourne pas les infos techniques $core->auth = new dcAuth($core); //class dcBlog need it
* L'utilisateur est authentifié $unauth = true;
* n'est pas admin (du blog en question) if($core->blog->status == false){
* -> OK, mais on ne retourne pas les infos techniques //le blog n'est pas publié (et l'user n'est pas authentifié)
* est admin // on Sort en 404
* -> L'API retourne le maximum d'infos $this->response_code = 404;
*/ $this->response_message = array('code' => 404, 'error' => 'Resource '.$blog_id.' not found');
return;
}
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
$response = array(
'blog_id' => $core->blog->id,
'blog_status' => $core->blog->status,
'blog_name' => $core->blog->name,
'blog_desc' => $core->blog->desc,
'blog_url' => $core->blog->url
);
$this->response_code = 200;
$this->response_message = $response;
return;
}
} }

View File

@ -0,0 +1,48 @@
<?php
class RestQueryGetBlogSettings extends RestQuery
{
public function __construct($args)
{
global $core;
$this->blog_id = explode("/",$args)[0];
//check if user is allowed
$this->required_perms = 'admin';
if($this->is_allowed() === false){
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'No enough privileges');
return;
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
try{
$settings = array();
foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) {
foreach ($namespace->dumpSettings() as $k => $v) {
$settings[$ns][$k] = $v;
}
}
$this->response_code = 200;
$this->response_message = $settings;
}catch (Exception $e){
$this->response_code = 500;
$this->response_message = array(
'code' => 500,
'message' => $e->getMessage()
);
}
return;
}
}

View File

@ -5,7 +5,7 @@ class RestQueryGetBlogs extends RestQuery
public function __construct(){ public function __construct(){
global $core; global $core;
$this->blog_id = false; //this method doesn't depend on a bolg_id $this->blog_id = false; //this method doesn't depend on a blog_id
$this->required_perms = 'none'; //I want user have an account $this->required_perms = 'none'; //I want user have an account
if($this->is_allowed() === false){ if($this->is_allowed() === false){

View File

@ -0,0 +1,74 @@
<?php
class ResQueryPatchBlogs extends RestQuery
{
public function __construct($args,$body)
{
global $core;
$this->blog_id = substr($args,6);
$this->required_perms = 'admin';
//Is allowed?
if($this->is_allowed() === false){
//need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'You need to be admin to patch a blog');
return;
}
//Is JSON valid?
$inputArray = $this-> body_to_array($body);
if ($inputArray === false){
return;
}
//is it valid fields?
if(!$this->check_for_required_fields( $inputArray, array(),
array('blog_id','blog_url','blog_name','blog_desc','lang','blog_timezone','url_scan')) ){
return;
}
//does the blog exists?
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
$cur = $core->con->openCursor($core->prefix.'blog');
if(isset($inputArray['blog_id']))
$cur->blog_id = $inputArray['blog_id'];
else
$cur->blog_id = $core->blog->id;
if(isset($inputArray['blog_url']))
$cur->blog_url = preg_replace('/\?+$/','?', $inputArray['blog_url']);
else
$cur->blog_url = $core->blog->url;
if(isset($inputArray['blog_name']))
$cur->blog_name = $inputArray['blog_name'];
if(isset($inputArray['blog_desc']))
$cur->blog_desc = $inputArray['blog_desc'];
$core->updBlog($this->blog_id,$cur);
//$cur->blog_upddt = date('Y-m-d H:i:s');
//$cur->update("WHERE blog_id = '".$core->con->escape($id)."'");
$this -> response_code = 200;
$this -> response_message = array(
'code' => 200,
'message' => 'blog '.$this->blog_id.' Successfully updated'
);
return;
}
}

View File

@ -1,9 +1,9 @@
<?php <?php
class RestQuery{ class RestQuery{
public $response_code; protected $response_code;
public $response_message; //array public $response_message; //array
public $blog_id; protected $blog_id;
protected $required_perms = 'admin'; //must be changed by the childs class protected $required_perms = 'admin'; //must be changed by the childs class
/* /*
should be: should be:
@ -22,7 +22,7 @@ class RestQuery{
public function __construct() public function __construct()
{ {
$this->response_code = RestQuery::get_full_code_header(400); $this->response_code = 400;
$this->response_message = array( $this->response_message = array(
"error" => "Unrecoknized method", "error" => "Unrecoknized method",
"code" => 400 "code" => 400
@ -44,7 +44,7 @@ class RestQuery{
if(empty(array_diff($fieldsSetted,$fieldsRequired))){ if(empty(array_diff($fieldsSetted,$fieldsRequired))){
return true; return true;
}else{ }else{
$this->response_code = RestQuery::get_full_code_header(400); $this->response_code = 400;
$this->response_message = array( $this->response_message = array(
"error" => "Only and each of following parameters ". "error" => "Only and each of following parameters ".
implode(", ",$fieldsRequired)." are required", implode(", ",$fieldsRequired)." are required",
@ -56,7 +56,7 @@ class RestQuery{
//check if all required fields are set //check if all required fields are set
foreach($fieldsRequired as $key){ foreach($fieldsRequired as $key){
if(!isset($arrayToCheck[$key])){ if(!isset($arrayToCheck[$key])){
$this->response_code = RestQuery::get_full_code_header(400); $this->response_code = 400;
$this->response_message = array( $this->response_message = array(
"error" => "field ".$key." is needed", "error" => "field ".$key." is needed",
"code" => 400 "code" => 400
@ -102,8 +102,6 @@ class RestQuery{
switch($this->required_perms){ switch($this->required_perms){
case 'unauth': case 'unauth':
//on verifie quand même que l'API est ouverte //on verifie quand même que l'API est ouverte
if((!$core->blog->settings->rest->rest_is_open) && ($core->auth === false)){ if((!$core->blog->settings->rest->rest_is_open) && ($core->auth === false)){
return false; return false;
@ -112,7 +110,7 @@ class RestQuery{
} }
break; break;
//to do
case 'none': case 'none':
//user must be valid //user must be valid
if($core->auth === false){ if($core->auth === false){
@ -147,7 +145,10 @@ class RestQuery{
break; break;
} }
} }
public function get_full_code_header($code){ public function get_full_code_header($code=''){
if($code == ''){
$code = $this->response_code;
}
static $codes = array( static $codes = array(
100 =>"Continue", 100 =>"Continue",
101 =>"Switching Protocols", 101 =>"Switching Protocols",

View File

@ -75,9 +75,10 @@ class RestQueryPostBlogs extends RestQuery
$core->callBehavior('adminAfterBlogCreate',$cur,$blog_id,$blog_settings); $core->callBehavior('adminAfterBlogCreate',$cur,$blog_id,$blog_settings);
//cool //cool
$this->response_code = 200; $this->response_code = 201;
$this->response_message = array( $this->response_message = array(
'code' => 200, 'code' => 201,
'id' => $blog_id
'message' => 'Successfully created blog'.$blog_id 'message' => 'Successfully created blog'.$blog_id
); );

View File

@ -0,0 +1,73 @@
<?php
class ResQueryPutBlogs extends RestQuery
{
public function __construct($args,$body)
{
global $core;
$this->blog_id = substr($args,6);
$this->required_perms = 'admin';
//Is allowed?
if($this->is_allowed() === false){
//need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'You need to be admin to put a blog');
return;
}
//Is JSON valid?
$inputArray = $this-> body_to_array($body);
if ($inputArray === false){
return;
}
//is it valid fields?
if(!$this->check_for_required_fields( $inputArray, array('blog_id','blog_url','blog_name','blog_desc'), array())){
return;
}
//does the blog exists?
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
$cur = $core->con->openCursor($core->prefix.'blog');
if(isset($inputArray['blog_id']))
$cur->blog_id = $inputArray['blog_id'];
else
$cur->blog_id = $core->blog->id;
if(isset($inputArray['blog_url']))
$cur->blog_url = preg_replace('/\?+$/','?', $inputArray['blog_url']);
else
$cur->blog_url = $core->blog->url;
if(isset($inputArray['blog_name']))
$cur->blog_name = $inputArray['blog_name'];
if(isset($inputArray['blog_desc']))
$cur->blog_desc = $inputArray['blog_desc'];
$core->updBlog($this->blog_id,$cur);
//$cur->blog_upddt = date('Y-m-d H:i:s');
//$cur->update("WHERE blog_id = '".$core->con->escape($id)."'");
$this -> response_code = 200;
$this -> response_message = array(
'code' => 200,
'message' => 'blog '.$this->blog_id.' Successfully updated'
);
return;
}
}

View File

@ -56,11 +56,11 @@ if(!empty($_POST['resetApiKey'])){
?> ?>
<html> <html>
<head> <head>
<title>Rest API config</title> <title><?php echo __('REST API configuration'); ?></title>
</head> </head>
<body> <body>
<h2>Documentation</h2> <h2>Documentation</h2>
<p><a href="<?php echo $core->blog->url."rest/documentation"; ?>">Go to the Swagger documentation</a></p> <p><a href="<?php echo $core->blog->url."rest/documentation" . '">' . __('Documentation and test interface Swagger UI') .'</a></p>'; ?>
<h2><?php echo __('Your API key');?></h2> <h2><?php echo __('Your API key');?></h2>
<?php echo $apiKey-> get_dc_admin_form($core->auth->userID()); ?> <?php echo $apiKey-> get_dc_admin_form($core->auth->userID()); ?>
@ -76,10 +76,9 @@ if($core->auth->isSuperAdmin()):
</p> </p>
<p> <p>
<?php echo form::checkbox('open', 1, $openApi); ?> <?php echo form::checkbox('open', 1, $openApi); ?>
<label class="classic" for="open">&nbsp;<?php echo __('API is open');?></label> <label class="classic" for="open">&nbsp;<?php echo __('API is open without key');?></label>
</p> </p>
<p class="info"><?php echo __("If checked, few methods as GET will be allowed to externals users without API key. <p class="info"><?php echo __("If checked, few methods as GET will be allowed to externals users without API key. However, they won't be able to request for non public content."); ?></p>
However, they won't be able to request for non public content."); ?></p>
<?php echo $core->formNonce(); ?> <?php echo $core->formNonce(); ?>
<p> <p>
<?php echo form::checkbox('sendHeaders', 1, $sendHeaders); ?> <?php echo form::checkbox('sendHeaders', 1, $sendHeaders); ?>

View File

@ -4,5 +4,41 @@ msgstr "Activer l'API REST"
msgid "Your API key" msgid "Your API key"
msgstr "Votre clef" msgstr "Votre clef"
msgid "Your new key is"
msgstr "Votre nouvelle clef est"
msgid "API is open without key"
msgstr "L'API est ouverte sans authentification"
msgid "Rest API configuration" msgid "Rest API configuration"
msgstr "Configuration de l'API" msgstr "Configuration de l'API"
msgid "If checked, few methods as GET will be allowed to externals users without API key. However, they won't be able to request for non public content."
msgstr "Si coché, Certaines méthodes seront accessibles sans authentification par clef (ni aucune autre authentification). Cependant, seules les actions et informations normalement accessibles sur le blog par les visiteurs non authentifiés sont concernés."
msgid "Send Coors headers"
msgstr "Insérer les Headers autorisant les requêtes cross domaine"
msgid "Save configuration"
msgstr "Enregistrer la configuration"
msgid "REST API configuration"
msgstr "Configurer l'API REST JSON"
msgid "Documentation and test interface Swagger UI"
msgstr "Documentation et interface de test de l'API via Swagger UI"
msgid "Your api key has already been created."
msgstr "Votre clef a déjà été générée"
msgid "Erase existing API key and generate a new one for"
msgstr "Réinitialiser la clef de "
msgid "No API key found."
msgstr "La clef de l'API n'a pas été initialisée"
msgid "Generate a API key for"
msgstr "Créer une clef pour"
msgid "Copy and paste it, You will cannot see it again."
msgstr "Copiez collez la. Cette clef ne pourra pas vous être refournie."

View File

Before

Width:  |  Height:  |  Size: 675 B

After

Width:  |  Height:  |  Size: 675 B