bitbucket -> github

This commit is contained in:
Gnieark 2017-05-05 21:46:14 +02:00
parent 954195b57f
commit 803b36ed3d
21 changed files with 953 additions and 519 deletions

View File

@ -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. Les spécifications swagger 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. 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. A terme, elles seront basées plus sur les fonctions de dotclear.
PS: Des que l'architecture de ce plugin sera plus développée, je poursuivrai son dev sur Bitbucket.

View File

@ -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));

View File

@ -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',
) )
); );

View File

@ -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['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';

View File

@ -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
switch($httpMethod){
case "GET":
if($args == 'blogs'){
$queryObj = new RestQueryGetBlogs();
break;
}elseif($args == 'specs'){
$queryObj = new RestQueryGetSpecs();
break;
}elseif(preg_match('^blogs/(.+)$', $args )){
$queryObj = new RestQueryGetBlog($args);
break;
//définir la methode API (pas HTML) appelée }
switch($httpMethod){
case "GET":
if($args == 'blogs'){
$queryObj = new RestQueryGetBlogs($user);
break;
}elseif($args == 'specs'){
$queryObj = new RestQueryGetSpecs($user);
break;
}
break;
case "POST":
break; ///blogs/{blog-id}
case "PUT":
break;
case "PATCH": break;
case "POST":
if($args == 'blogs'){
$queryObj = new RestQueryPostBlogs($body);
}
break; break;
case "PUT":
case "DELETE": break;
break; case "PATCH":
default:
$this->response_code = RestQuery::get_full_code_header(400);
$this->response_message = array(
"error" => "Unrecoknized method",
"code" => 400
);
return;
break;
}
return $queryObj; break;
} case "DELETE":
public static function getResponse($args) break;
{ default:
global $core; $queryObj = new RestQuery();
$active = (boolean)$core->blog->settings->rest->rest_active; break;
if (!$active){ }
self::p404();
return;
}
error_log($args);
//exception pour la documentation return $queryObj;
if($args == "documentation"){
}
public static function getResponse($args)
{
global $core;
$active = (boolean)$core->blog->settings->rest->rest_active;
if (!$active){
self::p404();
return;
}
//coors headers
if($core->blog->settings->rest->rest_send_cors_headers){
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 //user authentification (facultative at this step)
if($core->blog->settings->rest->rest_send_cors_headers){ $apiKey = rest::get_api_key_sended();
header('Access-Control-Allow-Origin: *'); //$user = false;
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE'); if($apiKey){
header('Access-Control-Allow-Headers: Content-Type, authorization, x_dc_key'); $core->auth = new restAuth($core);
} if($core->auth->checkUser('','',$apiKey) === false){
header('Content-Type: application/json'); header(RestQuery::get_full_code_header(403));
echo json_encode(array(
"error" => "Wrong API Key",
"code" => 403
));
return;
}
}else{
$core->auth = false;
}
$r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,file_get_contents('php://input'));
header($r->response_code);
echo json_encode($r->response_message);
//user authentification (facultative at this step) }
$apiKey = rest::get_api_key_sended();
$user = false;
if($apiKey){
$user = new restAuth($core);
if($user->checkUser('','',$apiKey) === false){
header(RestQuery::get_full_code_header(403));
echo json_encode(array(
"error" => "Wrong API Key",
"code" => 403
));
return;
}
}
$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;
}
}
} }

View File

@ -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,9 +265,9 @@ 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'
@ -283,11 +295,11 @@ 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
@ -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:
@ -799,7 +800,6 @@ definitions:
type: integer type: integer
temporary: temporary:
type: boolean type: boolean
Error: Error:
type: object type: object
properties: properties:

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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":""}

View File

@ -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",

View File

@ -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 { try {
$rs = $core->con->select($sqlStr); $rs = $core->con->select($sqlStr);
} 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;
} }
//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;
}
} }

View File

@ -2,90 +2,89 @@
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)){
$infoFormApiKey = __('Your api key has already been created.');
$buttonFormApiKey = __('Erase existing API key and generate a new one for').' '.$dcUserId;
}else{
$infoFormApiKey = __('No API key found.');
$buttonFormApiKey = __('Generate a API key for').' '.$dcUserId;
}
if($this->dc_is_key_setting_set($dcUserId)){ if($this->key == ''){
$infoFormApiKey = __('Your api key has already been created.'); $infoKey = $infoFormApiKey;
$buttonFormApiKey = __('Erase existing API key and generate a new one for').' '.$dcUserId; }else{
}else{ $infoKey = '<p class="info">'.__('The api key is').':<input type ="texte" value="'.$this->key.'"/><br/>'.
$infoFormApiKey = __('No API key found.'); __('Copy and paste it, You will cannot see it again.').'</p>';
$buttonFormApiKey = __('Generate a API key for').' '.$dcUserId; }
}
if($this->key == ''){
$infoKey = $infoFormApiKey;
}else{
$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>';
}
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;
} }
$hash = md5($this->key); $hashedKey = $core->auth->crypt($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),
$hash, $hashedKey,
'string' 'string'
); );
return $hash; return $hashedKey;
} }
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;
} }
} }

View File

@ -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
*/
}

View File

@ -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
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'get Blogs methods requires to be authentified');
return;
}
//error_log(json_encode($user->findUserBlog()));
}
global $core;
$this->blog_id = false; //this method doesn't depend on a bolg_id
$this->required_perms = 'none'; //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' => '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;
}
} }

View File

@ -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'));
$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;
} if($this->is_allowed() === false){
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'this method is not open');
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;
}
} }

View File

@ -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;
protected $required_perms = 'admin'; //must be changed by the childs class
/*
should be:
'admin'
'usage'
'publish'
'delete'
'contentadmin'
'categories'
'media'
'media_admin'
'none' //must be have an account (without any rights)
'unauth' //Open to the world
*/
public function get_full_code_header($code){ public function __construct()
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])){ $this->response_code = RestQuery::get_full_code_header(400);
return "HTTP/1.0 ".$code." ".$codes[$code]; $this->response_message = array(
}else{ "error" => "Unrecoknized method",
return "HTTP/1.0 ".$code." Something wrong happened"; "code" => 400
} );
} }
/**
* Check if required fields are set
* $strict => Go on error if a additionnal field is given
*/
protected function check_for_required_fields($arrayToCheck,$fieldsRequired,$fieldsOptionals = '')
{
if ($fieldsOptionals == ''){
$fieldsOptionals == array();
}
$fieldsSetted = array_keys($arrayToCheck);
if($fieldsOptionals == ''){
if(empty(array_diff($fieldsSetted,$fieldsRequired))){
return true;
}else{
$this->response_code = RestQuery::get_full_code_header(400);
$this->response_message = array(
"error" => "Only and each of following parameters ".
implode(", ",$fieldsRequired)." are required",
"code" => 400
);
return false;
}
}else{
//check if all required fields are set
foreach($fieldsRequired as $key){
if(!isset($arrayToCheck[$key])){
$this->response_code = RestQuery::get_full_code_header(400);
$this->response_message = array(
"error" => "field ".$key." is needed",
"code" => 400
);
return false;
}
}
//check if a field is not in required and in fieldsOptionals
foreach($fieldsSetted as $keyToTest){
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";
}
}
} }

View File

@ -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;
}
}

106
index.php
View File

@ -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;
?> ?>