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

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

@ -13,20 +13,30 @@ class rest extends dcUrlHandlers
* $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($user); $queryObj = new RestQueryGetBlogs();
break; break;
}elseif($args == 'specs'){ }elseif($args == 'specs'){
$queryObj = new RestQueryGetSpecs($user); $queryObj = new RestQueryGetSpecs();
break; break;
}elseif(preg_match('^blogs/(.+)$', $args )){
$queryObj = new RestQueryGetBlog($args);
break;
} }
///blogs/{blog-id}
break; break;
case "POST": case "POST":
if($args == 'blogs'){
$queryObj = new RestQueryPostBlogs($body);
}
break; break;
case "PUT": case "PUT":
@ -41,12 +51,7 @@ class rest extends dcUrlHandlers
break; break;
default: default:
$this->response_code = RestQuery::get_full_code_header(400); $queryObj = new RestQuery();
$this->response_message = array(
"error" => "Unrecoknized method",
"code" => 400
);
return;
break; break;
} }
@ -62,14 +67,6 @@ class rest extends dcUrlHandlers
self::p404(); self::p404();
return; return;
} }
error_log($args);
//exception pour la documentation
if($args == "documentation"){
include (dirname(__FILE__).'/documentation/swagger-ui-dist/index.php');
return;
}
//coors headers //coors headers
if($core->blog->settings->rest->rest_send_cors_headers){ if($core->blog->settings->rest->rest_send_cors_headers){
@ -77,14 +74,22 @@ class rest extends dcUrlHandlers
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE'); header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, authorization, x_dc_key'); 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');
return;
}
header('Content-Type: application/json'); header('Content-Type: application/json');
//user authentification (facultative at this step) //user authentification (facultative at this step)
$apiKey = rest::get_api_key_sended(); $apiKey = rest::get_api_key_sended();
$user = false; //$user = false;
if($apiKey){ if($apiKey){
$user = new restAuth($core); $core->auth = new restAuth($core);
if($user->checkUser('','',$apiKey) === false){ if($core->auth->checkUser('','',$apiKey) === false){
header(RestQuery::get_full_code_header(403)); header(RestQuery::get_full_code_header(403));
echo json_encode(array( echo json_encode(array(
"error" => "Wrong API Key", "error" => "Wrong API Key",
@ -92,9 +97,10 @@ class rest extends dcUrlHandlers
)); ));
return; return;
} }
}else{
$core->auth = false;
} }
$r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,file_get_contents('php://input'));
$r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,$user,file_get_contents('php://input'));
header($r->response_code); header($r->response_code);
echo json_encode($r->response_message); echo json_encode($r->response_message);

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

@ -18,12 +18,13 @@ class restAuth extends dcAuth
global $core; global $core;
$hashedKey = $core->auth->crypt($user_key);
//Check for the user api key //Check for the user api key
$sqlStr = " SELECT setting_id $sqlStr = " SELECT setting_id
FROM dc_setting FROM dc_setting
WHERE setting_ns='rest' WHERE setting_ns='rest'
AND setting_id LIKE 'rest_key_%' AND setting_id LIKE 'rest_key_%'
AND setting_value = md5('".$core->con->escape($user_key)."');"; AND setting_value = '".$core->con->escape($hashedKey)."';";
try { try {
$rs = $core->con->select($sqlStr); $rs = $core->con->select($sqlStr);
@ -46,8 +47,8 @@ class restAuth extends dcAuth
'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);
@ -78,8 +79,45 @@ class restAuth extends dcAuth
$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_options = array_merge($this->core->userDefaults(),$rs->options());
$this->user_prefs = new dcPrefs($this->core,$this->user_id); $this->user_prefs = new dcPrefs($this->core,$this->user_id);
return true; 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

@ -25,7 +25,6 @@ class ApiKey
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;
@ -70,13 +69,13 @@ class ApiKey
//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)

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){
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 //need To be authentified
$this->response_code = 403; $this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'get Blogs methods requires to be authentified'); $this->response_message = array('code' => 403, 'error' => 'get Blogs methods requires to be authentified');
return; return;
} }
//error_log(json_encode($user->findUserBlog())); //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,10 +1,18 @@
<?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;
$this->required_perms = 'unauth';
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); $specs = json_decode(file_get_contents(dirname(__FILE__).'/../documentation/swagger.json'),true);
//change some parameters //change some parameters
$url = parse_url($core->blog->url.$core->url->getBase('rest')); $url = parse_url($core->blog->url.$core->url->getBase('rest'));

View File

@ -3,7 +3,150 @@
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 __construct()
{
$this->response_code = RestQuery::get_full_code_header(400);
$this->response_message = array(
"error" => "Unrecoknized method",
"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){ public function get_full_code_header($code){
static $codes = array( static $codes = array(
100 =>"Continue", 100 =>"Continue",

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