bitbucket -> github

master
Gnieark 7 years ago
parent 954195b57f
commit 803b36ed3d

@ -2,12 +2,9 @@
Plugin dotclear ouvrant une API REST/JSON Plugin dotclear ouvrant une API REST/JSON
Interface d'administration commencée C'est en cours de développement et est loin d'être fini.
Dégrossi les specs / documentation de l'API (swagger).
Elles seront modifiées au fur et à mesure du développement de l'API.
Pour le moment les specifications Swagger sont basées sur la structure de la base de données.
A terme, elles seront basées plus sur les fonctions de dotclear.
Les spécifications swagger seront modifiées au fur et à mesure du développement de l'API.
PS: Des que l'architecture de ce plugin sera plus développée, je poursuivrai son dev sur Bitbucket. Pour le moment elles sont basées sur la structure de la base de données et ne sont pas exhaustives.
A terme, elles seront basées plus sur les fonctions de dotclear.

@ -3,7 +3,7 @@
if (!defined('DC_CONTEXT_ADMIN')) { return; } 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_256x256.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));

@ -12,12 +12,12 @@
if (!defined('DC_RC_PATH')) { return; } if (!defined('DC_RC_PATH')) { return; }
$this->registerModule( $this->registerModule(
/* Name */ "rest", /* Name */ "rest",
/* Description*/ "A JSON/REST API for Dotclear", /* Description*/ "A JSON/REST API for Dotclear",
/* Author */ "Gnieark (hope some others contributors)", /* Author */ "Gnieark (hope some others contributors)",
/* Version */ '0.0.1', /* Version */ '0.0.1',
array( array(
'permissions' => 'usage,contentadmin', 'permissions' => 'usage,contentadmin',
'type' => 'plugin', 'type' => 'plugin',
) )
); );

@ -5,4 +5,6 @@ $__autoload['ApiKey'] = dirname(__FILE__).'/inc/class.rest.key.php';
$__autoload['restAuth'] = dirname(__FILE__).'/inc/class.rest.auth.php'; $__autoload['restAuth'] = dirname(__FILE__).'/inc/class.rest.auth.php';
$__autoload['RestQuery'] = dirname(__FILE__).'/inc/class.rest.query.php'; $__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['RestQueryGetSpecs'] = dirname(__FILE__).'/inc/class.rest.query.get.specs.php'; $__autoload['RestQueryGetBlog'] = dirname(__FILE__).'/inc/class.rest.query.get.blog.php';
$__autoload['RestQueryGetSpecs'] = dirname(__FILE__).'/inc/class.rest.query.get.specs.php';
$__autoload['RestQueryPostBlogs'] = dirname(__FILE__).'/inc/class.rest.query.post.blogs.php';

@ -5,110 +5,116 @@ $core->url->register('rest','rest','^rest(?:/(.*))?$',array('rest','getResponse'
class rest extends dcUrlHandlers class rest extends dcUrlHandlers
{ {
/** /**
* Create the "good" RestQuery instance * Create the "good" RestQuery instance
* Input: $httpMethod: String (POST/GET/PATCH etc...) * Input: $httpMethod: String (POST/GET/PATCH etc...)
* $args Url arguments * $args Url arguments
* $user dcAuth object * $user dcAuth object
* $body Body of the input query. String * $body Body of the input query. String
* Output: object RestQuery * Output: object RestQuery
*/ */
private function restFactoryQuery($httpMethod,$args,$user,$body){ private function restFactoryQuery($httpMethod,$args,$body){
//définir la methode API (pas HTML) appelée
//définir la methode API (pas HTML) appelée switch($httpMethod){
switch($httpMethod){ case "GET":
case "GET": if($args == 'blogs'){
if($args == 'blogs'){ $queryObj = new RestQueryGetBlogs();
$queryObj = new RestQueryGetBlogs($user); break;
break; }elseif($args == 'specs'){
}elseif($args == 'specs'){ $queryObj = new RestQueryGetSpecs();
$queryObj = new RestQueryGetSpecs($user); break;
break; }elseif(preg_match('^blogs/(.+)$', $args )){
} $queryObj = new RestQueryGetBlog($args);
break; break;
case "POST":
}
break;
case "PUT": ///blogs/{blog-id}
break;
break;
case "PATCH": case "POST":
if($args == 'blogs'){
break; $queryObj = new RestQueryPostBlogs($body);
}
case "DELETE":
break;
break; case "PUT":
default:
$this->response_code = RestQuery::get_full_code_header(400); break;
$this->response_message = array(
"error" => "Unrecoknized method", case "PATCH":
"code" => 400
); break;
return;
break; case "DELETE":
}
break;
return $queryObj; default:
$queryObj = new RestQuery();
} break;
}
return $queryObj;
}
public static function getResponse($args) public static function getResponse($args)
{ {
global $core; global $core;
$active = (boolean)$core->blog->settings->rest->rest_active; $active = (boolean)$core->blog->settings->rest->rest_active;
if (!$active){ if (!$active){
self::p404(); self::p404();
return; return;
} }
error_log($args);
//coors headers
//exception pour la documentation if($core->blog->settings->rest->rest_send_cors_headers){
if($args == "documentation"){ header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, authorization, x_dc_key');
}
//exception pour la documentation
if($args == "documentation"){
include (dirname(__FILE__).'/documentation/swagger-ui-dist/index.php'); include (dirname(__FILE__).'/documentation/swagger-ui-dist/index.php');
return; return;
} }
header('Content-Type: application/json');
//coors headers
if($core->blog->settings->rest->rest_send_cors_headers){ //user authentification (facultative at this step)
header('Access-Control-Allow-Origin: *'); $apiKey = rest::get_api_key_sended();
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE'); //$user = false;
header('Access-Control-Allow-Headers: Content-Type, authorization, x_dc_key'); if($apiKey){
} $core->auth = new restAuth($core);
header('Content-Type: application/json'); if($core->auth->checkUser('','',$apiKey) === false){
header(RestQuery::get_full_code_header(403));
//user authentification (facultative at this step) echo json_encode(array(
$apiKey = rest::get_api_key_sended(); "error" => "Wrong API Key",
$user = false; "code" => 403
if($apiKey){ ));
$user = new restAuth($core); return;
if($user->checkUser('','',$apiKey) === false){ }
header(RestQuery::get_full_code_header(403)); }else{
echo json_encode(array( $core->auth = false;
"error" => "Wrong API Key", }
"code" => 403 $r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,file_get_contents('php://input'));
)); header($r->response_code);
return; echo json_encode($r->response_message);
}
} }
$r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,$user,file_get_contents('php://input')); private function get_api_key_sended()
header($r->response_code); {
echo json_encode($r->response_message); //to do: test it on nginx
$headers = apache_request_headers();
} if(isset($headers['x_dc_key'])){
return $headers['x_dc_key'];
private function get_api_key_sended() }else{
{ return false;
//to do: test it on nginx }
$headers = apache_request_headers(); }
if(isset($headers['x_dc_key'])){
return $headers['x_dc_key']; }
}else{
return false;
}
}
}

@ -2,18 +2,27 @@ swagger: '2.0'
info: info:
title: Dotclear API title: Dotclear API
description: Manage your(s) blogs with this API description: Manage your(s) blogs with this API
version: "0.0.1" version: 0.0.1
# the domain of the service
host: dotclear.localhost host: dotclear.localhost
# array of all schemes that your API supports
schemes: schemes:
- http - http
# will be prefixed to all paths basePath: /dotclear/index.php?rest
# (part of plugin url)
basePath: /dotclear/index.php?rest/
produces: produces:
- application/json - application/json
paths: paths:
/specs:
get:
summary: Get this API SWAGGER documentation
responses:
'200':
description: swagger.json
schema:
title: doc
type: string
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
/blogs: /blogs:
get: get:
summary: Get list of availables blogs summary: Get list of availables blogs
@ -23,13 +32,12 @@ paths:
required: false required: false
type: string type: string
responses: responses:
200: '200':
description: array serving blogs properties description: array serving blogs properties
schema: schema:
title: blogs
type: array type: array
items: items:
$ref: '#/definitions/blog' type: string
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
@ -48,7 +56,7 @@ paths:
$ref: '#/definitions/blog' $ref: '#/definitions/blog'
required: true required: true
responses: responses:
200: '200':
description: array containing the new blog's identifiant description: array containing the new blog's identifiant
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
@ -56,7 +64,7 @@ paths:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
/blogs/{blog-id}: '/blogs/{blog-id}':
get: get:
summary: Get a blog poperties summary: Get a blog poperties
parameters: parameters:
@ -69,11 +77,13 @@ paths:
type: string type: string
required: true required: true
responses: responses:
200: '200':
description: array containing blog properties. This list of attributes is not exhaustive. description: >-
array containing blog properties. This list of attributes is not
exhaustive.
schema: schema:
$ref: '#/definitions/blogProperties' $ref: '#/definitions/blogProperties'
404: '404':
description: this blog id does not exists description: this blog id does not exists
default: default:
description: Unexpected error description: Unexpected error
@ -97,18 +107,20 @@ paths:
schema: schema:
$ref: '#/definitions/blogProperties' $ref: '#/definitions/blogProperties'
responses: responses:
200: '200':
description: array containing the edited blog's identifiant description: array containing the edited blog's identifiant
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
404: '404':
description: this blog id does not exists description: this blog id does not exists
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
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 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
@ -125,17 +137,16 @@ paths:
schema: schema:
$ref: '#/definitions/blogProperties' $ref: '#/definitions/blogProperties'
responses: responses:
200: '200':
description: array containing the edited blog's identifiant description: array containing the edited blog's identifiant
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
404: '404':
description: this blog id does not exists description: this blog id does not exists
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
delete: delete:
summary: Delete this blog summary: Delete this blog
parameters: parameters:
@ -148,18 +159,17 @@ paths:
type: string type: string
required: true required: true
responses: responses:
200: '200':
description: array containing the deleted blog's identifiant description: array containing the deleted blog's identifiant
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
404: '404':
description: this blog id does not exists description: this blog id does not exists
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
'/{blog-id}/posts':
/{blog-id}/posts:
get: get:
summary: Get list of posts summary: Get list of posts
parameters: parameters:
@ -184,16 +194,17 @@ paths:
items: items:
type: string type: string
required: false required: false
description: Fields you want to get. If unset, fields are post_id, post_url, post_status, post_title, post_date description: >-
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
schema: schema:
title: posts title: posts
type: array type: array
items: items:
$ref: '#/definitions/dc_post' $ref: '#/definitions/dc_post'
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
@ -211,11 +222,13 @@ paths:
required: true required: true
- name: properties - name: properties
in: body in: body
description: Some non required fields you don't define will be set (default value) by the API description: >-
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:
200: '200':
description: Id of newly created post description: Id of newly created post
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
@ -223,8 +236,7 @@ paths:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
'/{blog-id}/posts/{post-id}':
/{blog-id}/posts/{post-id}:
get: get:
summary: Get a post entry summary: Get a post entry
parameters: parameters:
@ -253,11 +265,11 @@ paths:
items: items:
type: string type: string
required: false required: false
description: Fields you want to get. If unset, all available fields will be get. description: 'Fields you want to get. If unset, all available fields will be get.'
responses: responses:
200: '200':
description: The post values description: The post values
schema: schema:
$ref: '#/definitions/dc_post' $ref: '#/definitions/dc_post'
default: default:
description: Unexpected error description: Unexpected error
@ -283,16 +295,16 @@ paths:
schema: schema:
$ref: '#/definitions/dc_post' $ref: '#/definitions/dc_post'
responses: responses:
200: '200':
description: array containing the updated post's id description: array containing the updated post's id
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
404: '404':
description: this post does not exists description: this post does not exists
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
put: put:
summary: Update full blog properties. Unsetted parameters will be erased summary: Update full blog properties. Unsetted parameters will be erased
parameters: parameters:
@ -313,11 +325,11 @@ paths:
schema: schema:
$ref: '#/definitions/new_dc_post' $ref: '#/definitions/new_dc_post'
responses: responses:
200: '200':
description: array containing the updated post's id description: array containing the updated post's id
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
404: '404':
description: this post does not exists description: this post does not exists
default: default:
description: Unexpected error description: Unexpected error
@ -339,17 +351,17 @@ paths:
type: string type: string
required: true required: true
responses: responses:
200: '200':
description: array containing the deleted post's id description: array containing the deleted post's id
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
404: '404':
description: this post does not exists description: this post does not exists
default: default:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
/{blog-id}/categories: '/{blog-id}/categories':
get: get:
summary: Get list of available categories summary: Get list of available categories
parameters: parameters:
@ -362,7 +374,7 @@ paths:
type: string type: string
required: true required: true
responses: responses:
200: '200':
description: array containing the categories properties description: array containing the categories properties
schema: schema:
title: categories title: categories
@ -388,9 +400,8 @@ paths:
in: body in: body
schema: schema:
$ref: '#/definitions/new_category' $ref: '#/definitions/new_category'
responses: responses:
200: '200':
description: array containing the created category id description: array containing the created category id
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
@ -398,8 +409,7 @@ paths:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
'/{blog-id}/categories/{cat-id}':
/{blog-id}/categories/{cat-id}:
get: get:
summary: get one category properties summary: get one category properties
parameters: parameters:
@ -416,7 +426,7 @@ paths:
type: string type: string
required: true required: true
responses: responses:
200: '200':
description: array containing the created category properties description: array containing the created category properties
schema: schema:
$ref: '#/definitions/category' $ref: '#/definitions/category'
@ -440,7 +450,7 @@ paths:
schema: schema:
$ref: '#/definitions/category' $ref: '#/definitions/category'
responses: responses:
200: '200':
description: array containing the modified category id description: array containing the modified category id
schema: schema:
$ref: '#/definitions/Ids' $ref: '#/definitions/Ids'
@ -448,13 +458,6 @@ paths:
description: Unexpected error description: Unexpected error
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
definitions: definitions:
blog: blog:
type: object type: object
@ -469,14 +472,12 @@ definitions:
type: string type: string
blog_url: blog_url:
type: string type: string
description: blog_desc:
type: string type: string
blog_status: lang:
type: string
blog_timezone:
type: string type: string
enum:
- En ligne
- Hors ligne
- Retiré
url_scan: url_scan:
type: string type: string
enum: enum:
@ -497,7 +498,7 @@ definitions:
type: string type: string
url: url:
type: string type: string
description: description:
type: string type: string
author: author:
type: string type: string
@ -799,7 +800,6 @@ definitions:
type: integer type: integer
temporary: temporary:
type: boolean type: boolean
Error: Error:
type: object type: object
properties: properties:
@ -809,4 +809,4 @@ definitions:
message: message:
type: string type: string
fields: fields:
type: string type: string

@ -0,0 +1,93 @@
<!-- 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>

@ -1,4 +1,3 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>

File diff suppressed because one or more lines are too long

@ -1 +1 @@
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAmTA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA2pJA;AA+uFA;AA2rGA;AAgiFA;AA0rFA;AAk9CA;AA2hDA;AA4rCA;AAi6EA;;;;;AA2gCA;AA02JA;;;;;;;;;;;;;;AAuyEA;AA4mIA;AAquJA;AAwsHA;AA2mGA;AAiiEA;AAq4DA;AA+2DA;AAqlBA;;;;;;AAilFA;AAs1FA;;;;;AAy3CA;AA2qFA;AAw2CA;AAwkCA;AAs/CA;AA4kFA;AAy1FA;;;;;;;;;AAm5CA;AA2zIA;AAk4DA;AAolDA","sourceRoot":""} {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAoTA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA2pJA;AA+uFA;AA2rGA;AAgiFA;AA0rFA;AAk9CA;AA2hDA;AA4rCA;AAi6EA;;;;;AA2gCA;AA02JA;;;;;;;;;;;;;;AAuyEA;AA4mIA;AAquJA;AAwsHA;AA2mGA;AAiiEA;AAq4DA;AA+2DA;AAqlBA;;;;;;AAilFA;AAs1FA;;;;;AAy3CA;AA2qFA;AAw2CA;AAwkCA;AAs/CA;AA4kFA;AAy1FA;;;;;;;;;AAm5CA;AA2zIA;AAk4DA;AAolDA","sourceRoot":""}

File diff suppressed because one or more lines are too long

@ -1 +1 @@
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAwxCA;AAoyHA;AAuxHA;AAy4FA;AA2sCA;AAmgCA;AA0iCA;AA+3BA","sourceRoot":""} {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAyxCA;AAoyHA;AAuxHA;AAy4FA;AA2sCA;AAmgCA;AA0iCA;AA+3BA","sourceRoot":""}

@ -9,11 +9,31 @@
"schemes": [ "schemes": [
"http" "http"
], ],
"basePath": "/dotclear/index.php?rest/", "basePath": "/dotclear/index.php?rest",
"produces": [ "produces": [
"application/json" "application/json"
], ],
"paths": { "paths": {
"/specs": {
"get": {
"summary": "Get this API SWAGGER documentation",
"responses": {
"200": {
"description": "swagger.json",
"schema": {
"title": "doc",
"type": "string"
}
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/blogs": { "/blogs": {
"get": { "get": {
"summary": "Get list of availables blogs", "summary": "Get list of availables blogs",
@ -29,10 +49,9 @@
"200": { "200": {
"description": "array serving blogs properties", "description": "array serving blogs properties",
"schema": { "schema": {
"title": "blogs",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/blog" "type": "string"
} }
} }
}, },
@ -695,16 +714,14 @@
"blog_url": { "blog_url": {
"type": "string" "type": "string"
}, },
"description": { "blog_desc": {
"type": "string" "type": "string"
}, },
"blog_status": { "lang": {
"type": "string", "type": "string"
"enum": [ },
"En ligne", "blog_timezone": {
"Hors ligne", "type": "string"
"Retiré"
]
}, },
"url_scan": { "url_scan": {
"type": "string", "type": "string",

@ -2,84 +2,122 @@
class restAuth extends dcAuth class restAuth extends dcAuth
{ {
# L'utilisateur n'a pas le droit de changer son mot de passe # L'utilisateur n'a pas le droit de changer son mot de passe
protected $allow_pass_change = false; protected $allow_pass_change = false;
/** /**
* Méthode de vérification de la clef d'api_key * Méthode de vérification de la clef d'api_key
* Remplace la méthode chekUser (id: password) * Remplace la méthode chekUser (id: password)
* Only use $user_key (all others parameters are for compatibility with the parent function) * Only use $user_key (all others parameters are for compatibility with the parent function)
* input: $user_key STRING * input: $user_key STRING
* output: boolean * output: boolean
*/ */
public function checkUser($user_id, $pwd = NULL, $user_key = NULL, $check_blog = true) public function checkUser($user_id, $pwd = NULL, $user_key = NULL, $check_blog = true)
{ {
global $core; global $core;
//Check for the user api key $hashedKey = $core->auth->crypt($user_key);
$sqlStr = " SELECT setting_id //Check for the user api key
FROM dc_setting $sqlStr = " SELECT setting_id
WHERE setting_ns='rest' FROM dc_setting
AND setting_id LIKE 'rest_key_%' WHERE setting_ns='rest'
AND setting_value = md5('".$core->con->escape($user_key)."');"; AND setting_id LIKE 'rest_key_%'
AND setting_value = '".$core->con->escape($hashedKey)."';";
try {
$rs = $core->con->select($sqlStr); try {
} catch (Exception $e) { $rs = $core->con->select($sqlStr);
$err = $e->getMessage(); } catch (Exception $e) {
return false; $err = $e->getMessage();
} return false;
}
if ($rs->isEmpty()) { if ($rs->isEmpty()) {
sleep(rand(2,5)); sleep(rand(2,5));
return false; return false;
} }
//get the user ID from the previous query //get the user ID from the previous query
$userId = explode("_", $rs->setting_id)[2]; $userId = explode("_", $rs->setting_id)[2];
//get USER infos //get USER infos
$strReq = 'SELECT user_id, user_super, user_pwd, user_change_pwd, '. $strReq = 'SELECT user_id, user_super, user_pwd, user_change_pwd, '.
'user_name, user_firstname, user_displayname, user_email, '. 'user_name, user_firstname, user_displayname, user_email, '.
'user_url, user_default_blog, user_options, '. 'user_url, user_default_blog, user_options, '.
'user_lang, user_tz, user_post_status, user_creadt, user_upddt '. 'user_lang, user_tz, user_post_status, user_creadt, user_upddt '.
'FROM '.$this->con->escapeSystem($this->user_table).' '. 'FROM '.$core->con->escapeSystem($this->user_table).' '.
"WHERE user_id = '".$this->con->escape($userId)."'"; "WHERE user_id = '".$core->con->escape($userId)."'";
try { try {
$rs = $core->con->select($strReq); $rs = $core->con->select($strReq);
} catch (Exception $e) { } catch (Exception $e) {
$err = $e->getMessage(); $err = $e->getMessage();
return false; return false;
} }
if ($rs->isEmpty()) { if ($rs->isEmpty()) {
sleep(rand(2,5)); sleep(rand(2,5));
return false; return false;
} }
$this->user_id = $rs->user_id; $this->user_id = $rs->user_id;
$this->user_change_pwd = (boolean) $rs->user_change_pwd; $this->user_change_pwd = (boolean) $rs->user_change_pwd;
$this->user_admin = (boolean) $rs->user_super; $this->user_admin = (boolean) $rs->user_super;
$this->user_info['user_pwd'] = $rs->user_pwd; $this->user_info['user_pwd'] = $rs->user_pwd;
$this->user_info['user_name'] = $rs->user_name; $this->user_info['user_name'] = $rs->user_name;
$this->user_info['user_firstname'] = $rs->user_firstname; $this->user_info['user_firstname'] = $rs->user_firstname;
$this->user_info['user_displayname'] = $rs->user_displayname; $this->user_info['user_displayname'] = $rs->user_displayname;
$this->user_info['user_email'] = $rs->user_email; $this->user_info['user_email'] = $rs->user_email;
$this->user_info['user_url'] = $rs->user_url; $this->user_info['user_url'] = $rs->user_url;
$this->user_info['user_default_blog'] = $rs->user_default_blog; $this->user_info['user_default_blog'] = $rs->user_default_blog;
$this->user_info['user_lang'] = $rs->user_lang; $this->user_info['user_lang'] = $rs->user_lang;
$this->user_info['user_tz'] = $rs->user_tz; $this->user_info['user_tz'] = $rs->user_tz;
$this->user_info['user_post_status'] = $rs->user_post_status; $this->user_info['user_post_status'] = $rs->user_post_status;
$this->user_info['user_creadt'] = $rs->user_creadt; $this->user_info['user_creadt'] = $rs->user_creadt;
$this->user_info['user_upddt'] = $rs->user_upddt; $this->user_info['user_upddt'] = $rs->user_upddt;
$this->user_info['user_cn'] = dcUtils::getUserCN($rs->user_id, $rs->user_name, $this->user_info['user_cn'] = dcUtils::getUserCN($rs->user_id, $rs->user_name,
$rs->user_firstname, $rs->user_displayname); $rs->user_firstname, $rs->user_displayname);
//$this->user_options = array_merge($this->core->userDefaults(),$rs->options());
$this->user_prefs = new dcPrefs($this->core,$this->user_id); //$this->user_options = array_merge($this->core->userDefaults(),$rs->options());
return true; $this->user_prefs = new dcPrefs($this->core,$this->user_id);
} return true;
}
//return user permission for all blogs
//[blog_id] => permission
public function getAllPermissions()
{
global $core;
//conserve the value
static $blogs = false;
if($blogs !== false){
return $blogs;
}
if ($this->user_admin) { //user_admin == super admin
$strReq = 'SELECT blog_id '.
'from '.$this->blog_table;
$rs = $core->con->select($strReq);
while ($rs->fetch())
{
$blogs[$rs->blog_id] = 'admin';
}
return $blogs;
}
$strReq = 'SELECT blog_id, permissions '.
'FROM '.$this->perm_table.' '.
"WHERE user_id = '".$this->con->escape($this->user_id)."' ".
"AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') ";
$rs = $this->con->select($strReq);
while ($rs->fetch()){
$blogs[$rs->blog_id] = $this->parsePermissions($rs->permissions);
}
return $blogs;
}
} }

@ -1,91 +1,90 @@
<?php <?php
class ApiKey class ApiKey
{ {
public $key; public $key;
public function __construct(){ public function __construct(){
$this->key = ''; $this->key = '';
} }
public function new_key($dcUserId) public function new_key($dcUserId)
{ {
$this->key = $this->rand_str(); $this->key = $this->rand_str();
$this -> put_dc_setting_user_key($dcUserId); $this -> put_dc_setting_user_key($dcUserId);
return $this->key; return $this->key;
} }
public function set_key($key) public function set_key($key)
{ {
$this->key = $key; $this->key = $key;
} }
public function get_dc_admin_form($dcUserId) public function get_dc_admin_form($dcUserId)
{ {
global $core; global $core;
//tester si une clef d'API a été générée //tester si une clef d'API a été générée
if($this->dc_is_key_setting_set($dcUserId)){
if($this->dc_is_key_setting_set($dcUserId)){ $infoFormApiKey = __('Your api key has already been created.');
$infoFormApiKey = __('Your api key has already been created.'); $buttonFormApiKey = __('Erase existing API key and generate a new one for').' '.$dcUserId;
$buttonFormApiKey = __('Erase existing API key and generate a new one for').' '.$dcUserId; }else{
}else{ $infoFormApiKey = __('No API key found.');
$infoFormApiKey = __('No API key found.'); $buttonFormApiKey = __('Generate a API key for').' '.$dcUserId;
$buttonFormApiKey = __('Generate a API key for').' '.$dcUserId; }
}
if($this->key == ''){
if($this->key == ''){ $infoKey = $infoFormApiKey;
$infoKey = $infoFormApiKey; }else{
}else{ $infoKey = '<p class="info">'.__('The api key is').':<input type ="texte" value="'.$this->key.'"/><br/>'.
$infoKey = '<p class="info">'.__('The api key is').':<input type ="texte" value="'.$this->key.'"/><br/>'. __('Copy and paste it, You will cannot see it again.').'</p>';
__('Copy and paste it, You will cannot see it again.').'</p>'; }
}
return '<form method="post" action="'.http::getSelfURI().'">'.
return '<form method="post" action="'.http::getSelfURI().'">'. $infoKey.
$infoKey. '<p><input type="submit" name="resetApiKey" value="'.$buttonFormApiKey.'"/></p>'.
'<p><input type="submit" name="resetApiKey" value="'.$buttonFormApiKey.'"/></p>'. $core->formNonce().
$core->formNonce(). '</form>';
'</form>'; }
}
private function dc_is_key_setting_set($dcUserId)
private function dc_is_key_setting_set($dcUserId) {
{ global $core;
global $core;
$apiKeyName = $this->get_dc_setting_api_name($dcUserId);
$apiKeyName = $this->get_dc_setting_api_name($dcUserId); $currentHashedKey = $core->blog->settings->rest->{$apiKeyName};
$currentHashedKey = $core->blog->settings->rest->{$apiKeyName}; if(empty($currentHashedKey)){
if(empty($currentHashedKey)){ return false;
return false; }else{
}else{ return true;
return true; }
} }
}
private function put_dc_setting_user_key($dcUserId)
private function put_dc_setting_user_key($dcUserId) {
{ global $core;
global $core;
if ($this->key == ''){
if ($this->key == ''){ //don't save an empty key
//don't save an empty key return false;
return false; }
} $hashedKey = $core->auth->crypt($this->key);
$hash = md5($this->key); $core->blog->settings->rest->put(
$core->blog->settings->rest->put( $this->get_dc_setting_api_name($dcUserId),
$this->get_dc_setting_api_name($dcUserId), $hashedKey,
$hash, 'string'
'string' );
); return $hashedKey;
return $hash; }
}
private function get_dc_setting_api_name($dcUserId)
private function get_dc_setting_api_name($dcUserId) {
{ return 'rest_key_'.$dcUserId;
return 'rest_key_'.$dcUserId; }
}
private function rand_str($length = 32, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890')
private function rand_str($length = 32, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890') {
{
$chars_length = (strlen($chars) - 1); $chars_length = (strlen($chars) - 1);
$string = $chars{rand(0, $chars_length)}; $string = $chars{rand(0, $chars_length)};
for ($i = 1; $i < $length; $i = strlen($string)){ for ($i = 1; $i < $length; $i = strlen($string)){
@ -93,5 +92,5 @@ class ApiKey
if ($r != $string{$i - 1}) $string .= $r; if ($r != $string{$i - 1}) $string .= $r;
} }
return $string; return $string;
} }
} }

@ -0,0 +1,27 @@
<?php
/*
*Methode permettant de retourner des informations sur un blog particulier
*/
class RestQueryGetBlog extends RestQuery
{
public function __construct(){
global $core;
}
/*
* ça se complique niveau droits
*
* SI L'utilisateur n'est pas authentifié
* le blog est hors ligne
* -> 404
* l'API n'est pas publique
* -> refus
* l'API est publique
* -> OK, mais on ne retourne pas les infos techniques
* L'utilisateur est authentifié
* n'est pas admin (du blog en question)
* -> OK, mais on ne retourne pas les infos techniques
* est admin
* -> L'API retourne le maximum d'infos
*/
}

@ -2,17 +2,25 @@
class RestQueryGetBlogs extends RestQuery class RestQueryGetBlogs extends RestQuery
{ {
public function __construct($user){ public function __construct(){
if($user === false){
//need To be authentified global $core;
$this->response_code = 403; $this->blog_id = false; //this method doesn't depend on a bolg_id
$this->response_message = array('code' => 403, 'error' => 'get Blogs methods requires to be authentified'); $this->required_perms = 'none'; //I want user have an account
return;
} if($this->is_allowed() === false){
//error_log(json_encode($user->findUserBlog())); //need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'get Blogs methods requires to be authentified');
} return;
}
//list the blogs the user can access
$blgs = $core->auth->getAllPermissions();
$ret = array();
foreach($blgs as $key=>$value){
$ret[] = $key;
}
$this->response_code = 200;
$this->response_message = $ret;
}
} }

@ -1,19 +1,27 @@
<?php <?php
class RestQueryGetSpecs extends RestQuery class RestQueryGetSpecs extends RestQuery
{ {
public function __construct($user){ public function __construct(){
global $core; global $core;
$this->response_code = 200; $this->response_code = 200;
$specs = json_decode(file_get_contents(dirname(__FILE__).'/../documentation/swagger.json'),true); $this->required_perms = 'unauth';
//change some parameters
$url = parse_url($core->blog->url.$core->url->getBase('rest')); if($this->is_allowed() === false){
$specs['host'] = $url['host']; $this->response_code = 403;
$specs['schemes'] = $url['scheme']; $this->response_message = array('code' => 403, 'error' => 'this method is not open');
preg_match('/https?:\/\/[^\/]*(\/.*)/',$core->blog->url.$core->url->getBase('rest'),$end); return;
$specs['basePath'] = $end[1]; }
$this->response_message = $specs;
return; $specs = json_decode(file_get_contents(dirname(__FILE__).'/../documentation/swagger.json'),true);
//change some parameters
} $url = parse_url($core->blog->url.$core->url->getBase('rest'));
$specs['host'] = $url['host'];
$specs['schemes'] = $url['scheme'];
preg_match('/https?:\/\/[^\/]*(\/.*)/',$core->blog->url.$core->url->getBase('rest'),$end);
$specs['basePath'] = $end[1];
$this->response_message = $specs;
return;
}
} }

@ -1,72 +1,215 @@
<?php <?php
class RestQuery{ class RestQuery{
public $response_code; public $response_code;
public $response_message; //array public $response_message; //array
public $blog_id;
public function get_full_code_header($code){ protected $required_perms = 'admin'; //must be changed by the childs class
static $codes = array( /*
100 =>"Continue", should be:
101 =>"Switching Protocols", 'admin'
102 =>"Processing", 'usage'
200 =>"OK", 'publish'
201 =>"Created", 'delete'
202 =>"Accepted", 'contentadmin'
203 =>"Non-Authoritative Information", 'categories'
204 =>"No Content", 'media'
205 =>"Reset Content", 'media_admin'
206 =>"Partial Content", 'none' //must be have an account (without any rights)
207 =>"Multi-Status", 'unauth' //Open to the world
210 =>"Content Different", */
226 =>"IM Used",
300 =>"Multiple Choices", public function __construct()
301 =>"Moved Permanently", {
302 =>"Moved Temporarily",
303 =>"See Other", $this->response_code = RestQuery::get_full_code_header(400);
304 =>"Not Modified", $this->response_message = array(
305 =>"Use Proxy", "error" => "Unrecoknized method",
306 =>"(aucun)", "code" => 400
307 =>"Temporary Redirect", );
308 =>"Permanent Redirect", }
310 =>"Too many Redirects", /**
400 =>"Bad Request", * Check if required fields are set
401 =>"Unauthorized", * $strict => Go on error if a additionnal field is given
402 =>"Payment Required", */
403 =>"Forbidden", protected function check_for_required_fields($arrayToCheck,$fieldsRequired,$fieldsOptionals = '')
404 =>"Not Found", {
405 =>"Method Not Allowed", if ($fieldsOptionals == ''){
406 =>"Not Acceptable", $fieldsOptionals == array();
407 =>"Proxy Authentication Required", }
408 =>"Request Time-out",
409 =>"Conflict", $fieldsSetted = array_keys($arrayToCheck);
410 =>"Gone",
411 =>"Length Required", if($fieldsOptionals == ''){
412 =>"Precondition Failed", if(empty(array_diff($fieldsSetted,$fieldsRequired))){
413 =>"Request Entity Too Large", return true;
414 =>"Request-URI Too Long", }else{
415 =>"Unsupported Media Type", $this->response_code = RestQuery::get_full_code_header(400);
416 =>"Requested range unsatisfiable", $this->response_message = array(
417 =>"Expectation failed", "error" => "Only and each of following parameters ".
418 =>"Im a teapot", implode(", ",$fieldsRequired)." are required",
421 =>"Bad mapping / Misdirected Request", "code" => 400
422 =>"Unprocessable entity", );
423 =>"Locked", return false;
424 =>"Method failure", }
425 =>"Unordered Collection", }else{
426 =>"Upgrade Required", //check if all required fields are set
428 =>"Precondition Required", foreach($fieldsRequired as $key){
429 =>"Too Many Requests", if(!isset($arrayToCheck[$key])){
431 =>"Request Header Fields Too Large", $this->response_code = RestQuery::get_full_code_header(400);
449 =>"Retry With", $this->response_message = array(
450 =>"Blocked by Windows Parental Controls", "error" => "field ".$key." is needed",
451 =>"Unavailable For Legal Reasons", "code" => 400
456 =>"Unrecoverable Error" );
); return false;
}
if(isset($codes[$code])){ }
return "HTTP/1.0 ".$code." ".$codes[$code]; //check if a field is not in required and in fieldsOptionals
}else{ foreach($fieldsSetted as $keyToTest){
return "HTTP/1.0 ".$code." Something wrong happened"; if((!in_array($keyToTest,$fieldsRequired)) && (!in_array($keyToTest,$fieldsOptionals))){
} $this->response_message = array(
} "error" => "Unwanted field '".$keyToTest."'",
"code" => 400
);
return false;
}
}
return true;
}
}
protected function body_to_array($body){
if($ret = json_decode($body,true)){
return $ret;
}else{
$this->response_code = 301;
$this->response_message = array(
'error' => 'Can\'t parse input JSON',
'code' => 400
);
return false;
}
}
protected function is_allowed()
{
global $core;
if($core->auth){
$perms = $core->auth->getAllPermissions();
}
switch($this->required_perms){
case 'unauth':
//on verifie quand même que l'API est ouverte
if((!$core->blog->settings->rest->rest_is_open) && ($core->auth === false)){
return false;
}else{
return true;
}
break;
//to do
case 'none':
//user must be valid
if($core->auth === false){
return false;
}else{
return true;
}
break;
case 'media_admin':
break;
case 'media':
break;
case 'categories':
break;
case 'contentadmin':
break;
case 'delete':
break;
case 'publish':
break;
case 'usage':
break;
case 'admin':
if($core->auth === false){
return false;
}
if ($core->auth->isSuperAdmin()){
return true;
}else{
return false;
}
break;
}
}
public function get_full_code_header($code){
static $codes = array(
100 =>"Continue",
101 =>"Switching Protocols",
102 =>"Processing",
200 =>"OK",
201 =>"Created",
202 =>"Accepted",
203 =>"Non-Authoritative Information",
204 =>"No Content",
205 =>"Reset Content",
206 =>"Partial Content",
207 =>"Multi-Status",
210 =>"Content Different",
226 =>"IM Used",
300 =>"Multiple Choices",
301 =>"Moved Permanently",
302 =>"Moved Temporarily",
303 =>"See Other",
304 =>"Not Modified",
305 =>"Use Proxy",
306 =>"(aucun)",
307 =>"Temporary Redirect",
308 =>"Permanent Redirect",
310 =>"Too many Redirects",
400 =>"Bad Request",
401 =>"Unauthorized",
402 =>"Payment Required",
403 =>"Forbidden",
404 =>"Not Found",
405 =>"Method Not Allowed",
406 =>"Not Acceptable",
407 =>"Proxy Authentication Required",
408 =>"Request Time-out",
409 =>"Conflict",
410 =>"Gone",
411 =>"Length Required",
412 =>"Precondition Failed",
413 =>"Request Entity Too Large",
414 =>"Request-URI Too Long",
415 =>"Unsupported Media Type",
416 =>"Requested range unsatisfiable",
417 =>"Expectation failed",
418 =>"Im a teapot",
421 =>"Bad mapping / Misdirected Request",
422 =>"Unprocessable entity",
423 =>"Locked",
424 =>"Method failure",
425 =>"Unordered Collection",
426 =>"Upgrade Required",
428 =>"Precondition Required",
429 =>"Too Many Requests",
431 =>"Request Header Fields Too Large",
449 =>"Retry With",
450 =>"Blocked by Windows Parental Controls",
451 =>"Unavailable For Legal Reasons",
456 =>"Unrecoverable Error"
);
if(isset($codes[$code])){
return "HTTP/1.0 ".$code." ".$codes[$code];
}else{
return "HTTP/1.0 ".$code." Something wrong happened";
}
}
} }

@ -0,0 +1,97 @@
<?php
class RestQueryPostBlogs extends RestQuery
{
public function __construct($body)
{
global $core;
$this->blog_id = false; //this method doesn't depend on a bolg_id
$this->required_perms = 'admin'; //I want user have an account
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 create a new blog');
return;
}
$inputArray = $this-> body_to_array($body);
if ($inputArray === false){
return false;
}
//permit optional description
if(!isset($inputArray['blog_desc'])){
$inputArray["blog_desc"] = '';
}
//check if parameters are set
if(!$this->check_for_required_fields( $inputArray, array('blog_id','blog_url','blog_name','blog_desc'),
array('lang','blog_timezone','url_scan')) ){
return;
}
//Following lines are same as admin/blog.php
$cur = $core->con->openCursor($core->prefix.'blog');
$blog_id = $cur->blog_id = $inputArray['blog_id'];
$blog_url = $cur->blog_url = $inputArray['blog_url'];
$blog_name = $cur->blog_name = $inputArray['blog_name'];
$blog_desc = $cur->blog_desc = $inputArray['blog_desc'];
try
{
# --BEHAVIOR-- adminBeforeBlogCreate
$core->callBehavior('adminBeforeBlogCreate',$cur,$blog_id);
$core->addBlog($cur);
# Default settings and override some
$core->blogDefaults($cur->blog_id);
$blog_settings = new dcSettings($core,$cur->blog_id);
$blog_settings->addNamespace('system');
if(isset($inputArray['lang'])){
$blog_settings->system->put('lang',$inputArray['lang']);
}else{
$blog_settings->system->put('lang',$core->auth->getInfo('user_lang'));
}
if(isset($inputArray['blog_timezone'])){
$blog_settings->system->put('blog_timezone',$inputArray['blog_timezone']);
}else{
$blog_settings->system->put('blog_timezone',$core->auth->getInfo('user_tz'));
}
if(isset($inputArray['url_scan'])){
$blog_settings->system->put('url_scan',$inputArray['url_scan']);
}elseif(substr($blog_url,-1) == '?') {
$blog_settings->system->put('url_scan','query_string');
} else {
$blog_settings->system->put('url_scan','path_info');
}
# --BEHAVIOR-- adminAfterBlogCreate
$core->callBehavior('adminAfterBlogCreate',$cur,$blog_id,$blog_settings);
//cool
$this->response_code = 200;
$this->response_message = array(
'code' => 200,
'message' => 'Successfully created blog'.$blog_id
);
}
catch (Exception $e)
{
$this->response_code = 500;
$this->response_message = array(
'code' => 500,
'message' => $e->getMessage()
);
}
return;
}
}

@ -8,16 +8,16 @@ $apiKey = new ApiKey;
// Setting default parameters if missing configuration // Setting default parameters if missing configuration
$core->blog->settings->addNamespace('rest'); $core->blog->settings->addNamespace('rest');
if (is_null($core->blog->settings->rest->rest_active)) { if (is_null($core->blog->settings->rest->rest_active)) {
try { try {
$core->blog->settings->rest->put('rest_active',false,'boolean',true); $core->blog->settings->rest->put('rest_active',false,'boolean',true);
$core->blog->settings->rest->put('rest_is_open',false,'boolean',true); $core->blog->settings->rest->put('rest_is_open',false,'boolean',true);
$core->blog->settings->rest->put('rest_send_cors_headers',true,'boolean',true); $core->blog->settings->rest->put('rest_send_cors_headers',true,'boolean',true);
$core->blog->triggerBlog(); $core->blog->triggerBlog();
http::redirect($p_url); http::redirect($p_url);
} }
catch (Exception $e) { catch (Exception $e) {
$core->error->add($e->getMessage()); $core->error->add($e->getMessage());
} }
} }
// Getting current parameters // Getting current parameters
$active = (boolean)$core->blog->settings->rest->rest_active; $active = (boolean)$core->blog->settings->rest->rest_active;
@ -26,70 +26,70 @@ $sendHeaders =(boolean)$core->blog->settings->rest->rest_send_cors_headers;
//Sousmission Formulaire parametres //Sousmission Formulaire parametres
if ((!empty($_POST['saveconfig'])) && ($core->auth->isSuperAdmin())) { if ((!empty($_POST['saveconfig'])) && ($core->auth->isSuperAdmin())) {
try try
{ {
$core->blog->settings->addNameSpace('rest'); $core->blog->settings->addNameSpace('rest');
$active = (empty($_POST['active'])) ? false : true; $active = (empty($_POST['active'])) ? false : true;
$core->blog->settings->rest->put('rest_active',$active,'boolean'); $core->blog->settings->rest->put('rest_active',$active,'boolean');
$openApi = (empty($_POST['open'])) ? false : true; $openApi = (empty($_POST['open'])) ? false : true;
$core->blog->settings->rest->put('rest_is_open',$openApi,'boolean'); $core->blog->settings->rest->put('rest_is_open',$openApi,'boolean');
$sendHeaders = (empty($_POST['sendHeaders'])) ? false : true; $sendHeaders = (empty($_POST['sendHeaders'])) ? false : true;
$core->blog->settings->rest->put('rest_send_cors_headers',$sendHeaders,'boolean'); $core->blog->settings->rest->put('rest_send_cors_headers',$sendHeaders,'boolean');
dcPage::addSuccessNotice(__('Configuration successfully updated.')); dcPage::addSuccessNotice(__('Configuration successfully updated.'));
http::redirect($p_url); http::redirect($p_url);
}catch (Exception $e) }catch (Exception $e)
{ {
$core->error->add($e->getMessage()); $core->error->add($e->getMessage());
} }
} }
//Sousmission Formulaire Reset API Key //Sousmission Formulaire Reset API Key
if(!empty($_POST['resetApiKey'])){ if(!empty($_POST['resetApiKey'])){
$core->blog->settings->addNameSpace('rest'); $core->blog->settings->addNameSpace('rest');
$apiKey -> new_key($core->auth->userID()); $apiKey -> new_key($core->auth->userID());
dcPage::addSuccessNotice(__('Your new key is').' '.$apiKey->key); dcPage::addSuccessNotice(__('Your new key is').' '.$apiKey->key);
} }
?> ?>
<html> <html>
<head> <head>
<title>Rest API config</title> <title>Rest API config</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"; ?>">Go to the Swagger documentation</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()); ?>
<?php <?php
//Seulement si administrateur: //Seulement si administrateur:
if($core->auth->isSuperAdmin()): if($core->auth->isSuperAdmin()):
?> ?>
<h2><?php echo __('Rest API configuration'); ?></h2> <h2><?php echo __('Rest API configuration'); ?></h2>
<form method="post" action="<?php http::getSelfURI(); ?>"> <form method="post" action="<?php http::getSelfURI(); ?>">
<p> <p>
<?php echo form::checkbox('active', 1, $active); ?> <?php echo form::checkbox('active', 1, $active); ?>
<label class="classic" for="active">&nbsp;<?php echo __('Enable REST API');?></label> <label class="classic" for="active">&nbsp;<?php echo __('Enable REST API');?></label>
</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');?></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); ?>
<label class="classic" for="sendHeaders">&nbsp;<?php echo __('Send Coors headers');?></label> <label class="classic" for="sendHeaders">&nbsp;<?php echo __('Send Coors headers');?></label>
</p> </p>
<p> <p>
<input type="submit" name="saveconfig" value="<?php echo __('Save configuration'); ?>" /> <input type="submit" name="saveconfig" value="<?php echo __('Save configuration'); ?>" />
</p> </p>
</from> </from>
<?php <?php
endif; endif;
?> ?>

Loading…
Cancel
Save