Commit c77b59f7 by Malcolm Blaney

Added PuSH support.

parent c5e3a3d6
Pipeline #3022523 skipped
......@@ -208,7 +208,7 @@ class Post extends Base {
header('HTTP/1.1 410 Gone');
return '<article class="h-entry">'.
'<div class="published">'.
'<time class="dt-published" datetime="'.$atom_date.'">'.
'<time class="dt-deleted" datetime="'.$atom_date.'">'.
'<a href="'.$permalink_url.'" class="u-url">'.
$formatted_date.'</a>'.
'</time></div>'.
......
......@@ -65,6 +65,7 @@ dobrado.editor=null;$(".editable").attr("contenteditable",false);$.each(CKEDITOR
if(extended.content.source){source=extended.content.source;}
notify=false;if(extended.content.notify){notify=extended.content.notify;}
var label=$(dobrado.current).data("label");if(label==="commenteditor"){label="Comment Manager";}
else if(label==="simple"){label="Text Area";}
else{label=label.charAt(0).toUpperCase()+label.slice(1);}
$("#extended-tabs li a").first().html(label);$("#extended-custom").html('<div class="custom">'+custom+'</div>');$("#extended-content").html('<div class="edit">'+source+'</div>');dobrado.oldPermalink=extended.content.permalink;$("#extended-custom-settings").find(":input").change(function(){customChange=true;});$("#extended-custom-settings :submit").button().click(function(){$(".extended").dialog("close");return false;});if(extended.content.editor===true){var edit=$("#extended-content > div.edit");var editorCssProperties=["azimuth","background","background-attachment","background-color","background-image","background-position","background-repeat","background-size","caption-side","clear","clip","color","content","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","empty-cells","filter","font","font-family","font-size","font-style","font-variant","font-weight","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","opacity","orphans","outline","outline-color","outline-style","outline-width","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","pitch","pitch-range","play-during","quotes","richness","size","speak","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","text-align","text-decoration","text-indent","text-transform","unicode-bidi","vertical-align","voice-family","volume","white-space","widows","word-spacing"];var css=".cke_editable { ";var current=$(dobrado.current);for(var i=0;i<editorCssProperties.length;i++){var property=editorCssProperties[i];var value=current.css(property);if(value){css+=property+": "+value+";";}}
css+="}";CKEDITOR.addCss(css);dobrado.editor=CKEDITOR.replace(edit.get(0),{allowedContent:true,disableNativeSpellChecker:false,enterMode:CKEDITOR.ENTER_BR,filebrowserBrowseUrl:"/php/browse.php",height:240,removePlugins:"elementspath,contextmenu,tabletools,liststyle",resize_enabled:false,toolbar:[['Source','-','NewPage'],['Undo','Redo','-','SelectAll','RemoveFormat'],['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenField'],['Bold','Italic','Underline','Strike'],['Subscript','Superscript'],['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'],['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],['Link','Unlink','Anchor'],['Image','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],['Format','Font','FontSize'],['TextColor','BGColor'],['Maximize','ShowBlocks','-','About']]});}
......
......@@ -516,6 +516,9 @@ if (!this.dobrado.extended) {
if (label === "commenteditor") {
label = "Comment Manager";
}
else if (label === "simple") {
label = "Text Area";
}
else {
// Otherwise capitalize the first letter to match other tabs.
label = label.charAt(0).toUpperCase() + label.slice(1);
......
<?php
// Dobrado Content Management System
// Copyright (C) 2015 Malcolm Blaney
// Copyright (C) 2016 Malcolm Blaney
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
......@@ -20,14 +20,55 @@ include 'config.php';
include 'module.php';
include 'user.php';
function challenge($register, $url, $challenge, $lease = false) {
if ($lease !== false) {
$ch = curl_init($register.'?hub.mode=subscribe&hub.topic='.$url.
'&hub.challenge='.$challenge.'&hub.lease_seconds='.$lease);
}
else {
$ch = curl_init($register.'?url='.$url.'&challenge='.$challenge);
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = explode("\r\n", curl_exec($ch));
$count = count($data);
if ($count < 2) {
echo 'Error: could not check notification URL.';
return false;
}
// Check that the status code for the first header is in the 200's.
if (!preg_match('/^HTTP\/1.1 2[0-9][0-9]/', $data[0])) {
echo 'Error: incorrect status header.';
return false;
}
// Then the last entry in the data array must be the challenge value.
if ($data[$count - 1] !== $challenge) {
echo 'Error: challenge does not match.';
return false;
}
return true;
}
$user = new User();
$reader = new Module($user, '', 'reader');
if (!$reader->IsInstalled()) {
header("HTTP/1.1 404 Not Found");
echo 'Update notifications are not available.';
return;
}
if (isset($_POST['hub.mode']) && $_POST['hub.mode'] == 'subscribe') {
$url = $_POST['hub.topic'];
$register = $_POST['hub.callback'];
if (challenge($register, $url, md5(mt_rand()), 86400)) {
$reader->Factory('Register', array($url, $register));
echo 'Registration successful.';
}
return;
}
if (isset($_POST['protocol']) && $_POST['protocol'] != 'http-post') {
header("HTTP/1.1 404 Not Found");
echo 'Sorry only http-post protocol is supported.';
return;
}
......@@ -37,7 +78,6 @@ $path = isset($_POST['path']) ? $_POST['path'] : '/';
$domain = '';
$register = '';
$verify = false;
$challenge = md5(mt_rand());
$server = $user->config->ServerName();
if (isset($_POST['domain'])) {
......@@ -68,29 +108,11 @@ while (isset($_POST['url'.$i])) {
echo 'Error: cannot register for '.$url;
continue;
}
if ($verify) {
$ch = curl_init($register.'?url='.$url.'&challenge='.$challenge);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = explode("\r\n", curl_exec($ch));
$count = count($data);
if ($count < 2) {
echo 'Error: could not check notification URL.';
continue;
}
// Check that the status code for the first header is in the 200's.
if (preg_match('/^HTTP\/1.1 2[0-9][0-9]/', $data[0]) != 1) {
echo 'Error: incorrect status header.';
continue;
}
// Then the last entry in the data array must be the challenge value.
if ($data[$count - 1] !== $challenge) {
echo 'Error: challenge does not match.';
continue;
}
if ($verify && !challenge($register, $url, md5(mt_rand()))) {
continue;
}
$reader->Factory('Register', array($url, $register));
echo 'Registration successful.';
echo 'Registration for '.$url.' successful.';
}
?>
......@@ -2557,6 +2557,12 @@ class SimplePie
{
return $this->data['links'][$rel];
}
else if (isset($this->data['headers']['link']) &&
preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/',
$this->data['headers']['link'], $match))
{
return array($match[1]);
}
else
{
return null;
......
......@@ -25,6 +25,8 @@ class Simple extends Base {
// mode is used by the Extended module, which calls this function.
if ($_POST['mode'] == 'box') {
$id = (int)substr($_POST['id'], 9);
// TODO: Use the custom area to search for multiple id's to update
// content. (like site editor but just for the current user)
return array('source' => $this->PlainContent($id), 'editor' => true);
}
}
......
<?php
// Dobrado Content Management System
// Copyright (C) 2015 Malcolm Blaney
// Copyright (C) 2016 Malcolm Blaney
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
......@@ -46,7 +46,7 @@ class Page {
// When secure is true in config check the scheme and redirect if reqd.
if ($this->user->config->Secure() &&
(!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === '')) {
$this->Secure();
header('Location: '.$this->Url($this->name, $this->owner, true));
return;
}
......@@ -59,7 +59,7 @@ class Page {
$this->user->SetPermission($this->name, $owner);
if ($this->Permission()) $this->Display();
else $this->Unavailable();
else header('Location: '.$this->Url($this->user->config->Unavailable()));
}
private function Display() {
......@@ -145,6 +145,8 @@ class Page {
$this->user->config->Title();
$feed = '';
if ($post_feed) {
header('Link: <'.$this->Url($this->name, $this->owner).'>; rel="self"');
header('Link: <'.$this->Url('/php/cloud.php').'>; rel="hub"', false);
$feed .= '<link rel="alternate" type="application/rss+xml" '.
'title="new posts" href="rss/index.php?page='.$this->name.'">'."\n";
}
......@@ -254,22 +256,15 @@ class Page {
}
private function DefaultPage($name = '') {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== '' ?
'https://' : 'http://';
if ($this->user->config->Secure()) {
// Override current scheme if secure is true in config.
$scheme = 'https://';
}
$page = $this->user->config->FancyUrl() ? '/' : '/index.php?page=';
$page .= $name === '' ? $this->user->config->LoginPage() : $name;
if ($name === '') $name = $this->user->config->LoginPage();
// Override current scheme if secure is true in config.
$secure = $this->user->config->Secure();
// If not logged in user->name will be an empty string.
// Not using config ServerName here in case CNAME is being used.
if ($this->user->name == 'admin' || $this->user->name === '') {
header('Location: '.$scheme.$_SERVER['SERVER_NAME'].$page);
header('Location: '.$this->Url($name, 'admin', $secure));
}
else {
header('Location: '.$scheme.$_SERVER['SERVER_NAME'].'/'.
$this->user->name.$page);
header('Location: '.$this->Url($name, $this->user->name, $secure));
}
}
......@@ -301,25 +296,18 @@ class Page {
return $published_page;
}
private function Secure() {
$page = $this->user->config->FancyUrl() ? '/' : '/index.php?page=';
$page .= $this->name;
// Not using config ServerName here in case CNAME is being used.
if ($this->owner == 'admin') {
header('Location: https://'.$_SERVER['SERVER_NAME'].$page);
}
else {
header('Location: https://'.$_SERVER['SERVER_NAME'].'/'.
$this->owner.$page);
}
}
private function Unavailable() {
private function Url($name, $owner = 'admin', $secure = false) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== '' ?
'https://' : 'http://';
$url = $this->user->config->FancyUrl() ? '/' : '/index.php?page=';
header('Location: '.$scheme.$_SERVER['SERVER_NAME'].$url.
$this->user->config->Unavailable());
if ($secure) $scheme = 'https://';
// Not using config ServerName here in case CNAME is being used.
if (strpos($name, '.')) return $scheme.$_SERVER['SERVER_NAME'].$name;
$path = $this->user->config->FancyUrl() ? '/' : '/index.php?page=';
if ($owner == 'admin') {
return $scheme.$_SERVER['SERVER_NAME'].$path.$name;
}
return $scheme.$_SERVER['SERVER_NAME'].'/'.$owner.$path.$name;
}
}
......
......@@ -25,8 +25,10 @@ $reader = new Module($user, '', 'reader');
if (!$reader->IsInstalled()) exit;
$mysqli = connect_db();
if (isset($_POST['url'])) {
$url = $mysqli->escape_string($_POST['url']);
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_REQUEST['url'])) {
// RSSCloud explicitly posts the url, for PuSH it's added as a callback
// query parameter in Reader->RenewHub().
$url = $mysqli->escape_string($_REQUEST['url']);
// Check that we've registered for notifications for this feed.
if ($reader->Factory('RegisteredFeed', $url)) {
$reader->Factory('UpdateFeed', $url);
......@@ -40,6 +42,13 @@ else if (isset($_GET['url']) && isset($_GET['challenge'])) {
echo $_GET['challenge'];
}
}
else if (isset($_GET['hub.mode']) && $_GET['hub.mode'] == 'subscribe') {
$url = $mysqli->escape_string($_GET['hub.topic']);
$lease = (int)$_GET['hub.lease_seconds'];
if ($reader->Factory('RegisteredFeed', array($url, $lease))) {
echo $_GET['hub.challenge'];
}
}
$mysqli->close();
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment