Compare commits

..

12 Commits

Author SHA1 Message Date
Christian Weiske
635be284de use autoloader 2014-03-26 22:49:40 +01:00
Christian Weiske
90ba326f85 show error when openid is already registered 2014-03-26 22:49:36 +01:00
Christian Weiske
09cf21aa7e use custom HTTP adapter to get rid of HTTP warnings thrown by XML_XRD's simplexml_load_file usage 2014-03-26 22:49:31 +01:00
Christian Weiske
3acd0e8db4 WebFinger support! 2014-03-26 22:49:27 +01:00
Christian Weiske
e1655f0e22 adding new openids in user profile works now 2014-03-26 22:49:23 +01:00
Christian Weiske
3afbf11087 restructure code a bit 2014-03-26 22:49:08 +01:00
Christian Weiske
8258c39e54 CS: tab2spaces 2014-03-26 22:46:59 +01:00
Christian Weiske
da38761814 begin describing OpenID login process 2014-03-26 22:45:39 +01:00
Christian Weiske
9ac32984eb catch openid errors 2014-03-26 22:45:36 +01:00
Christian Weiske
1ab3c45d71 Move OpenID login handling into separate class 2014-03-26 22:45:32 +01:00
Christian Weiske
14640ed8a5 openid identifier table 2014-03-26 22:45:27 +01:00
Christian Weiske
16c08eb3b6 first working openid login (very very rough, but works!) 2014-03-26 22:45:23 +01:00
53 changed files with 1048 additions and 1330 deletions

View File

@ -1,12 +0,0 @@
Patched SemanticScuttle (social bookmarking tool).
================================================
### New :
* Better import for XML bookmark file.
* Support for adding multiple bookmarks at once with my modified Firefox's Scuttle plugin.
* Block everything if global private mode enabled and user not logged on.
* Shoulder surfing protection.
* Batch tagging.
* Search will now look in bookmarks addresses too.

View File

@ -105,11 +105,15 @@
channel="pear.php.net"
minimum_version="0.4.0"
/>
<!-- unit tests: -->
<package name="HTML_Request2"
channel="pear.php.net"
minimum_version="2.0.0"
/>
<package name="Net_WebFinger"
channel="pear.php.net"
minimum_version="0.2.0"
/>
<!-- unit tests: -->
<package name="Stream_Var"
channel="pear.php.net"
minimum_version="1.1.0"

View File

@ -253,13 +253,10 @@ $adminsAreAdvisedTagsFromOtherAdmins = false;
*
* @var array
*/
$reservedusers = array('all', 'watchlist');
$reservedusers = array('all', 'watchlist');
/**
* If global private mode is enabled (everything will be blocked for unlogged users).
* @var boolean
*/
$privatemode = false;
/***************************************************
* Anti SPAM measures
@ -545,27 +542,35 @@ $defaults['privacy'] = 0;
*/
/**
* Which thumbnail service type to use.
* Enable bookmark website thumbnails.
*
* Currently supported:
* - null (no screenshots)
* - 'phancap', see http://cweiske.de/phancap.htm
* According to artviper.net license, buy a license if you
* gain profit with your pages.
*
* @var boolean
* @link http://www.websitethumbnail.de/
*/
$enableWebsiteThumbnails = false;
/**
* User ID from websitethumbnail.de
*
* You need to register on
* http://www.artviper.net/registerapi.php
* in order to use thumbnails on your domain
*
* @var string
* @link http://www.artviper.net/registerapi.php
*/
$thumbnailsUserId = null;
/**
* API key.
* Sent to you by artviper.net after registration.
*
* @var string
*/
$thumbnailsType = null;
/**
* Configuration for thumbnail service.
*
* Phancap requires an array with the following keys:
* - url: URL to phancap's get.php file
* - token: user name (if access protected)
* - secret: password for the user (if access protected)
*
* @var array
*/
$thumbnailsConfig = array();
$thumbnailsKey = null;
@ -615,13 +620,6 @@ $menu2Tags = array(
'menu2', 'tags', 'configurable', 'in', 'data/config.php'
);
/**
* Tag protected from shoulder surfing.
* This tag, his children and the associated bookmarks won't appear anywhere unless enabled in the UI.
*
* @var string
*/
$shoulderSurfingProtectedTag = 's_hidden';
/****************************

View File

@ -79,6 +79,15 @@ CREATE TABLE `sc_users` (
-- --------------------------------------------------------
CREATE TABLE `sc_users_openids` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uId` int(11) NOT NULL,
`url` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) CHARACTER SET utf8 COLLATE utf8_general_ci;
-- --------------------------------------------------------
CREATE TABLE `sc_users_sslclientcerts` (
`id` INT NOT NULL AUTO_INCREMENT ,
`uId` INT NOT NULL ,

View File

@ -115,38 +115,3 @@ echo jsEscTitle(htmlspecialchars($link));
}
//]]>
</script>
<script type="text/javascript">
function activateSocialApi(node) {
var baseurl = <?php echo json_encode(addProtocolToUrl(createURL())); ?>;
var socialApiData = {
// currently required
"name": <?php echo json_encode($GLOBALS['sitename']); ?>,
"iconURL": baseurl + "themes/default/images/logo.png",
"icon32URL": baseurl + "themes/default/images/logo.png",
"icon64URL": baseurl + "themes/default/images/logo.png",
"markURL": "<?php echo addProtocolToUrl(createURL('bookmarks', $GLOBALS['user'])); ?>?action=add&amp;popup=1&amp;width=800&amp;height=470&amp;address=%{url}&amp;title=%{title}&amp;description=%{description}%{text}",
"markedIcon": baseurl + "themes/default/images/logo.png",
"unmarkedIcon": baseurl + "themes/default/images/logo-empty.png",
// should be available for display purposes
"description": "Self-hosted bookmark manager",
"author": "Christian Weiske",
"homepageURL": "http://semanticscuttle.sf.net/",
// optional
"version": "0.0.3"
};
var event = new CustomEvent("ActivateSocialFeature");
node.setAttribute("data-service", JSON.stringify(socialApiData));
node.dispatchEvent(event);
}
</script>
<p>
<button onclick="activateSocialApi(this)" title="activate semanticscuttle in firefox">
Add SemanticScuttle to Firefox
</button>
</p>

View File

@ -5,14 +5,14 @@
*
* Expects a $row variable with bookmark data.
*/
$thumbnailer = SemanticScuttle_Service_Factory::get('Thumbnails')->getThumbnailer();
$imgUrl = $thumbnailer->getThumbnailUrl($address, 120, 90);
if ($imgUrl !== false) {
echo '<a href="' . htmlspecialchars($address) . '">'
. '<img class="thumbnail" width="120" height="90" src="'
. htmlspecialchars($imgUrl).
'" />'
. '</a>';
if (!$GLOBALS['enableWebsiteThumbnails']) {
return;
}
$thumbnailHash = md5(
$address . $GLOBALS['thumbnailsUserId'] . $GLOBALS['thumbnailsKey']
);
//echo '<a href="'. $address .'"'. $rel .' ><img class="thumbnail" src="http://www.artviper.net/screenshots/screener.php?url='.$address.'&w=120&sdx=1280&userID='.$GLOBALS['thumbnailsUserId'].'&hash='.$thumbnailHash.'" />';
echo '<img class="thumbnail" onclick="window.location.href=\''.htmlspecialchars($address).'\'" src="http://www.artviper.net/screenshots/screener.php?url='.htmlspecialchars($address).'&amp;w=120&amp;sdx=1280&amp;userID='.$GLOBALS['thumbnailsUserId'].'&amp;hash='.$thumbnailHash.'" />';
?>

View File

@ -162,14 +162,6 @@ default:
<a href="?sort=<?php echo $votingSort ?>"><?php echo T_("Voting").$votingArrow; ?></a>
<span>/</span>
<?php } ?>
<?php
if ($userservice->isLoggedOn() && $_SERVER['PHP_SELF'] !== "/index.php") {
echo '<form method="get" action="'. $_SERVER['REQUEST_URI'] .'">';
echo '<input type="hidden" name="batch" value="1"/>';
echo '<input type="submit" value="Batch tagging"/>';
echo "</form>";
}
?>
<?php
if ($currenttag!= '') {
@ -186,6 +178,7 @@ if ($currenttag!= '') {
}
}
?></p>
<?php
// PAGINATION

View File

@ -6,6 +6,11 @@ echo '<a href="'.createURL('about').'">'.T_('About').'</a>';
echo ' - ';
echo T_("Propulsed by ");
echo " <a href=\"https://sourceforge.net/projects/semanticscuttle/\">SemanticScuttle</a>";
if($GLOBALS['enableWebsiteThumbnails']) {
// Licence to the thumbnails provider (OBLIGATORY IF YOU USE ARTVIPER SERVICE)
echo ' (Thumbnails by <a href="http://www.artviper.net">webdesign</a>)';
}
?>
</div>

View File

@ -1,5 +1,6 @@
<?php
$this->includeTemplate($GLOBALS['top_include']);
$accessPublic = '';
$accessShared = '';
$accessPrivate = '';
@ -32,14 +33,6 @@ if (is_array($row['tags'])) {
$row['tags'] = implode(', ', $row['tags']);
}
if (! is_array($row['bAddress'])) {
$row['bAddress'] = array($row['bAddress']);
}
if (! is_array($row['bTitle'])) {
$row['bTitle'] = array($row['bTitle']);
}
$ajaxUrl = ROOT . 'ajax/'
. (
($GLOBALS['adminsAreAdvisedTagsFromOtherAdmins'] && $currentUser->isAdmin())
@ -47,8 +40,18 @@ $ajaxUrl = ROOT . 'ajax/'
: 'getcontacttags'
) . '.php';
?>
<form onsubmit="var ind = 0; var cb = document.getElementById('checkbox'+ind); while (cb !== null) {var title = document.getElementById('titleField'+ind); var address = document.getElementById('address'+ind); if(cb.checked) {cb.parentNode.removeChild(cb);} else {cb.parentNode.removeChild(cb); title.parentNode.removeChild(title); address.parentNode.removeChild(address);} ind++; cb = document.getElementById('checkbox'+ind);}" action="<?php echo $formaction; ?>" method="post">
<form action="<?php echo $formaction; ?>" method="post">
<table>
<tr>
<th align="left"><?php echo T_('Address'); ?></th>
<td><input type="text" id="address" name="address" size="75" maxlength="65535" value="<?php echo filter($row['bAddress'], 'xml'); ?>" onblur="useAddress(this)" /></td>
<td> <?php echo T_('Required'); ?></td>
</tr>
<tr>
<th align="left"><?php echo T_('Title'); ?></th>
<td><input type="text" id="titleField" name="title" size="75" maxlength="255" value="<?php echo filter($row['bTitle'], 'xml'); ?>" onkeypress="this.style.backgroundImage = 'none';" /></td>
<td> <?php echo T_('Required'); ?></td>
</tr>
<tr>
<th align="left">
<?php echo T_('Description'); ?>
@ -75,44 +78,13 @@ $ajaxUrl = ROOT . 'ajax/'
<td> <?php echo T_('Just visible by you and your contacts.'); ?>
</td>
</tr>
<?php if(! isset($batch)): ?>
<tr>
<th align="left"><?php echo T_('Tags'); ?></th>
<td class="scuttletheme">
<input type="text" id="tags" class="tags" name="tags" size="75" value="<?php echo filter($row['tags'], 'xml'); ?>"/>
<input type="text" id="tags" name="tags" size="75" value="<?php echo filter($row['tags'], 'xml'); ?>"/>
</td>
<td> <?php echo T_('Comma-separated'); ?></td>
</tr>
<?php else: ?>
<tr>
<th align="left"><?php echo 'Common tags'; ?></th>
<td class="scuttletheme">
<span><?php echo filter($commontags, 'xml'); ?></span>
</td>
<td> <?php echo 'Tags common to all those bookmarks'; ?></td>
</tr>
<tr>
<th align="left"><?php echo 'Associated tags'; ?></th>
<td class="scuttletheme">
<span><?php echo filter($alltags, 'xml'); ?></span>
</td>
<td> <?php echo 'All tags associated to those bookmarks'; ?></td>
</tr>
<tr>
<th align="left"><?php echo 'Add those tags'; ?></th>
<td class="scuttletheme">
<input type="text" id="tags" class="tags" name="tags" size="75" value="<?php echo filter($row['tags'], 'xml'); ?>"/>
</td>
<td> <?php echo T_('Comma-separated'); ?></td>
</tr>
<tr>
<th align="left"><?php echo 'Remove those tags'; ?></th>
<td class="scuttletheme">
<input type="text" id="removetags" class="tags" name="removetags" size="75" value="<?php echo filter($row['tags'], 'xml'); ?>"/>
</td>
<td> <?php echo T_('Comma-separated'); ?></td>
</tr>
<?php endif; ?>
<tr>
<th></th>
<td align="right"><small><?php echo htmlspecialchars(T_('Note: use ">" to include one tag in another. e.g.: europe>france>paris'))?></small></td>
@ -143,9 +115,6 @@ $ajaxUrl = ROOT . 'ajax/'
<input type="submit" name="delete" value="<?php echo T_('Delete Bookmark'); ?>" />
<?php
}
?>
<button type="button" id="button" title="Invert selection" onclick="var ind = 0; var cb = document.getElementById('checkbox'+ind); while (cb !== null) {var title = document.getElementById('titleField'+ind); var address = document.getElementById('address'+ind); if(cb.checked) {cb.checked=false;} else {cb.checked=true;} ind++; cb = document.getElementById('checkbox'+ind);}">Invert selection</button>
<?php
if (isset($showdelete) && $showdelete) {
echo ' (<a href="'.createURL('bookmarkcommondescriptionedit', $row['bHash']).'">';
echo T_('edit common description').'</a>)';
@ -157,42 +126,14 @@ $ajaxUrl = ROOT . 'ajax/'
<?php
} elseif (isset($referrer)) {
?>
<input type="hidden" name="referrer" value="<?php echo filter($referrer, 'xml'); ?>" />
<input type="hidden" name="referrer" value="<?php echo $referrer; ?>" />
<?php
}
?>
</td>
<td></td>
</tr>
<?php
$ind = 0;
foreach($row['bAddress'] as $index => $address) {
?>
<tr>
<td height="20px"></td>
<td><input type="checkbox" id="checkbox<?php echo $ind; ?>" checked="checked" /></td>
<td></td>
</tr>
<tr>
<th align="left"><?php echo T_('Address'); ?></th>
<td><input type="text" id="address<?php echo $ind; ?>" name="address[<?php echo $index; ?>]" size="75" maxlength="65535" value="<?php echo filter($address, 'xml'); ?>" onblur="useAddress(this)" /></td>
<td> <?php echo T_('Required'); ?></td>
</tr>
<tr>
<th align="left"><?php echo T_('Title'); ?></th>
<td><input type="text" id="titleField<?php echo $ind; ?>" name="title[<?php echo $index; ?>]" size="75" maxlength="255" value="<?php echo filter($row['bTitle'][$index], 'xml'); ?>" onkeypress="this.style.backgroundImage = 'none';" /></td>
<td> <?php echo T_('Required'); ?></td>
</tr>
<tr>
<td height="20px"></td>
<td></td>
<td></td>
</tr>
<?php
$ind++;
}
?>
</table>
</table>
</form>
<link href="<?php echo ROOT ?>js/jquery-ui-1.8.11/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css"/>
@ -215,8 +156,7 @@ jQuery(document).ready(function() {
}
//var availableTags = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby"];
//jQuery("input#tags").autocomplete({
jQuery("input.tags").autocomplete({
jQuery("input#tags").autocomplete({
autoFocus: true,
minLength: 1,

View File

@ -0,0 +1,48 @@
<?php
/**
* User's own profile page: OpenID management
*
* @param array $openIds Array of OpenID association objects
* @param string $formaction URL where to send the forms to
* @param SemanticScuttle_Model_User_OpenId
* $currentOpenId Current OpenID object (may be null)
*/
?>
<h3><?php echo T_('OpenIDs'); ?></h3>
<?php if (count($openIds)) { ?>
<table>
<thead>
<tr>
<th>Options</th>
<th><?php echo T_('OpenID URL'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach($openIds as $openId) { ?>
<tr <?php if ($openId->isCurrent()) { echo 'class="openid-current"'; } ?>>
<td>
<form method="post" action="<?php echo $formaction; ?>">
<input type="hidden" name="openIdUrl" value="<?php echo htmlspecialchars($openId->url); ?>"/>
<button type="submit" name="action" value="deleteOpenId">
<?php echo T_('delete'); ?>
</button>
</form>
</td>
<td><?php echo htmlspecialchars($openId->url); ?></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php } else { ?>
<p><?php echo T_('No OpenIDs registered'); ?></p>
<?php } ?>
<p>
<form method="post" action="<?php echo $formaction; ?>">
<label for="openid"><?php echo T_('New E-Mail or OpenID'); ?></label>
<input type="text" id="openid" name="openid_identifier" size="20" />
<button type="submit" name="action" value="registerOpenId">
<?php echo T_('Register'); ?>
</button>
</form>
</p>

View File

@ -59,6 +59,7 @@ $this->includeTemplate($GLOBALS['top_include']);
</tr>
</table>
<?php include 'editprofile-openid.tpl.php'; ?>
<?php include 'editprofile-sslclientcerts.tpl.php'; ?>
<h3><?php echo T_('Actions'); ?></h3>
<table class="profile">

View File

@ -17,6 +17,15 @@ if (!$userservice->isSessionStable()) {
<form action="<?php echo $formaction; ?>" method="post">
<div><input type="hidden" name="query" value="<?php echo $querystring; ?>" /></div>
<table>
<tr>
<th align="left"><label for="openid"><?php echo T_('E-Mail or OpenID'); ?></label></th>
<td><input type="text" id="openid" name="openid_identifier" size="20" /></td>
<td></td>
</tr>
<tr>
<td></td>
<td colspan="2" class="login-or">or</td>
</tr>
<tr>
<th align="left"><label for="username"><?php echo T_('Username'); ?></label></th>
<td><input type="text" id="username" name="username" size="20" /></td>

View File

@ -11,62 +11,14 @@ if ($userservice->isLoggedOn() && is_object($currentUser)) {
<li><a href="<?php echo createURL('watchlist', $cUsername); ?>"><?php echo T_('Watchlist'); ?></a></li>
<li><a href="<?php echo $userservice->getProfileUrl($cUserId, $cUsername); ?>"><?php echo T_('Profile'); ?></a></li>
<li><a href="<?php echo createURL('bookmarks', $cUsername . '?action=add'); ?>"><?php echo T_('Add a Bookmark'); ?></a></li>
<?php if (isset($loadjs)) :?>
<li class="access"><button type="button" id="button" title="shoulder surfing protection" onclick="if(! $.cookie('noshoulderSurfingProtection')) {toggle();} else {$.removeCookie('noshoulderSurfingProtection', { path: '/' }); location.reload();}"><?php if(! isset($_COOKIE["noshoulderSurfingProtection"])) {echo "Protected";} else {echo "Unprotected";} ?></button></li>
<?php endif ?>
<li class="access"><?php echo $cUsername?><a href="<?php echo ROOT ?>?action=logout">(<?php echo T_('Log Out'); ?>)</a></li>
<li><a href="<?php echo createURL('about'); ?>"><?php echo T_('About'); ?></a></li>
<?php if($currentUser->isAdmin()): ?>
<li><a href="<?php echo createURL('admin', ''); ?>"><?php echo '['.T_('Admin').']'; ?></a></li>
<?php endif; ?>
</ul>
<?php if (isset($loadjs)) :?>
<div id="password-form" style="background:white; z-index: 2; position:absolute; top:55px; right:10px; visibility:hidden;">
<form id="noshoulderSurfingProtectionPassword">
<input type="password" name="password" id="password" size="40" placeholder="Type your password then press Enter to unprotect."/>
<!-- Allow form submission with keyboard without duplicating the dialog button -->
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px"/>
</form>
</div>
<script>
// Prevents browser autocompletion. autocomplete="off" as input type="password" attribute only works with HTML5.
setTimeout(
clear(),
1000 //1,000 milliseconds = 1 second
);
function clear() {
$('#password').val('');
}
function toggle() {
if ($("#password-form").css("visibility") == "visible") {
$("#password-form").css("visibility", "hidden");
}
else {
clear();
$("#password-form").css("visibility", "visible");
}
}
$( "#noshoulderSurfingProtectionPassword" ).submit(function( event ) {
$.post(
'<?php echo ROOT ?>ajax/checkpassword.php',
{
password : $("#password").val(),
},
function(data) {
if(data == 'true') {
$.cookie('noshoulderSurfingProtection', 'null', { path: '/' });
location.reload();
}
},
'text'
);
event.preventDefault();
});
</script>
<?php endif ?>
<?php
} else {
?>

View File

@ -22,35 +22,19 @@ if (isset($rsschannels)) {
<?php if (DEBUG_MODE) : ?>
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery-1.4.2.js"></script>
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery.jstree.js"></script>
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery.cookie-1.4.1.js"></script>
<?php else: ?>
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery.jstree.min.js"></script>
<script type="text/javascript" src="<?php echo ROOT_JS ?>jquery.cookie-1.4.1.js"></script>
<?php endif ?>
<script type="text/javascript" src="<?php echo ROOT ?>jsScuttle.php"></script>
<?php endif ?>
</head>
<?php
$bodystyle = '';
if (isset($_GET['popup'])) {
if (isset($_GET['height'])) {
$bodystyle .= 'height:' . intval($_GET['height']) . 'px;';
}
if (isset($_GET['width'])) {
$bodystyle .= 'width:' . intval($_GET['width']) . 'px;';
}
if ($bodystyle != '') {
$bodystyle = ' style="' . $bodystyle . '"';
}
}
?>
<body<?php echo $bodystyle; ?>>
<body>
<?php
$headerstyle = '';
if (isset($_GET['popup'])) {
if(isset($_GET['popup'])) {
$headerstyle = ' class="popup"';
}
?>

View File

@ -8,7 +8,7 @@ Prerequisites
=============
To run SemanticScuttle, you need:
- PHP5 with filter functions enabled
- PHP5
- A web server, for example Apache

View File

@ -211,6 +211,3 @@ Here we authenticate against an active directory server.
);
$authEmailSuffix = '@example.org';
More LDAP options can be found in the `PEAR manual`__.
__ http://pear.php.net/manual/en/package.authentication.auth.storage.ldap.php

Binary file not shown.

82
doc/developers/OpenID.rst Normal file
View File

@ -0,0 +1,82 @@
**************
OpenID support
**************
Since SemanticScuttle 0.99.0, users may log in via OpenID.
=============
Login Process
=============
::
.
+------------------+
/ OpenID URL entry /
+------------------+
|
v
+----------------------------+ Cancel +------------+
| Request to OpenID provider | ------------------------> | Login fail |
+----------------------------+ +------------+
| Success ^
_____ v ________________________ | No
/ \ No +----------------------------+
| OpenID associated with a user? | ----------> | User registration enabled? |
\________________________________/ +----------------------------+
| | Yes
| Yes v
| +-------------------------+
| / Registration form /
| / prefilled with data /
| / from OpenID provider /
| / /
| / Password not required /
| / Email not required /
| +-------------------------+
| |
v v
+-------+ +----------------+
| Login | <----------------------------------------- | Create account |
+-------+ +----------------+
|
_____v_______________
/ \ Yes +------------------+
| Data update active? |------------> | Update user data |
\_____________________/ | from OpenID |
| +------------------+
v |
+----------------+ |
| Login finished | <--------------------------+
+----------------+
Automatic registration?
=======================
No. We show the user the login form prefilled with data.
1. It prevents users from creating several accounts when they use multiple
OpenIDs and forgot which they used in this instance.
2. In case the user name is already taken, we need to ask for a new user name
anyway.
3. People may not want to use the data from their OpenID provider when
registering
Discussion on this topic happened in http://drupal.org/node/637850
=====
Links
=====
- http://stackoverflow.com/questions/4564337/guidance-on-flow-for-openid-registration-form
- http://stackoverflow.com/questions/1316983/to-openid-or-not-to-openid-is-it-worth-it
- http://wiki.openid.net/w/page/12995223/Relying%20Party%20Best%20Practices
====
TODO
====
Blog post:
- automatic registration
- openid login/registration process flow chart

View File

@ -51,8 +51,7 @@ Existing themes
===============
* `Flat`__ by Roman Lehnhof. See the `introduction blog post`__
* `sscuttlizr`__
__ https://github.com/rlehnhof/flat
__ http://lehnhof.net/2013/08/semantic-scuttle-new-flat-interface-theme-template/
__ https://github.com/jonrandoem/sscuttlizr

View File

@ -2,35 +2,7 @@
Tools to use with SemanticScuttle
=================================
Scuttleoid
==========
Scuttloid is an android client for managing your bookmarks that are
stored on a Semantic Scuttle server.
It allows to list/search your personal bookmarks, add and edit existing
bookmarks, and share them to other applications.
Installable via `f-droid`__.
Also see the `source code`__.
__ https://f-droid.org/repository/browse/?fdid=gr.ndre.scuttloid
__ https://github.com/ilesinge/scuttloid
Scuttle for Android
===================
Scuttle for Android is a client for the Scuttle bookmarking software.
Enter your Scuttle login information and you will presented with a list of your
bookmarks.
Touching a bookmark will load that web page in the browser.
Use the browser's "Share" menu option to add bookmarks to your Scuttle.
See the homepage__ and `source code`__.
__ http://slideme.org/application/scuttle-android
__ https://github.com/shadybrooksoftware/Scuttle-For-Android
ttrss2scuttle
TTRSS2SCUTTLE
=============
Announced in a `blog post`__, the plugin for the feed reader `Tiny Tiny RSS`__
allows you to bookmark any of the articles in your own SemanticScuttle

View File

@ -0,0 +1,33 @@
<?php
require_once 'SemanticScuttle/Exception/User.php';
class SemanticScuttle_Exception extends Exception
{
/**
* Returns an error message that can be shown to the user.
*
* FIXME: maybe move that method to somewhere else
*
* @return string Error message to display to the user
*/
public static function getErrorMessage(Exception $e)
{
if ($e instanceof SemanticScuttle_Exception_User) {
if (isset($GLOBALS['debugMode']) && $GLOBALS['debugMode']) {
$prev = $e->getPrevious();
if ($prev) {
$msg = $prev->getMessage();
} else {
$msg = $e->getMessage();
}
} else {
$msg = $e->getMessage();
}
} else {
$msg = $e->getMessage();
}
return $msg;
}
}
?>

View File

@ -0,0 +1,10 @@
<?php
/**
* Exception class whose message may be displayed to users in the frontend.
*
* The detailled message is in the previous exception (getPrevious()).
*/
class SemanticScuttle_Exception_User extends Exception
{
}
?>

View File

@ -0,0 +1,60 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license AGPL http://www.gnu.org/licenses/agpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
/**
* OpenID model. Represents one single OpenID association to a user.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license AGPL http://www.gnu.org/licenses/agpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
class SemanticScuttle_Model_OpenId
{
public $id;
public $uId;
public $url;
/**
* Creates and returns a new object and fills it with
* the passed values from the database.
*
* @param array $arOpenIdRow Database row array
*
* @return SemanticScuttle_Model_OpenId
*/
public static function fromDb($arOpenIdRow)
{
$openId = new self();
foreach (get_object_vars($openId) as $variable => $dummy) {
if (isset($arOpenIdRow[$variable])) {
$openId->$variable = $arOpenIdRow[$variable];
}
}
return $openId;
}
/**
* Returns if this OpenID is the one the user is logged in with currently.
*
* @return boolean True if the User logged in with this OpenID
*/
public function isCurrent()
{
//FIXME
return false;
}
}

View File

@ -51,7 +51,7 @@ class SemanticScuttle_Service
{
static $instance;
if (!isset($instance)) {
$instance = new static($db);
$instance = new self($db);
}
return $instance;
}

View File

@ -733,26 +733,11 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
if (!is_array($tags) && !is_null($tags)) {
$tags = explode('+', trim($tags));
}
if (!is_null($tags)) {
$tags = array_map('trim', $tags);
}
// Remove shoulder surfing protected tags.
if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
$shoulderSurfingProtectedTags = $tag2tagservice->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $sId, array());
$shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
$tags2 = [];
foreach ($tags as $tag) {
if (! in_array($tag, $shoulderSurfingProtectedTags, true)) {
$tags2[] = $tag;
}
}
// If we filtered everything, we stop here and return nothing.
if(! empty($tags) && empty($tags2)) {
return array();
}
$tags = $tags2;
}
$tagcount = count($tags);
for ($i = 0; $i < $tagcount; $i ++) {
$tags[$i] = trim($tags[$i]);
}
// Set up the SQL query.
$query_1 = 'SELECT DISTINCT ';
@ -888,13 +873,10 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
// but private notes won't appear if not allowed.
$query_4 .= ' OR B.bPrivateNote LIKE "'
. $this->db->sql_escape($aTerms[$i])
. '%"';
.'%"';
$query_4 .= ' OR U.username = "'
. $this->db->sql_escape($aTerms[$i])
. '"'; //exact match for username
$query_4 .= ' OR B.bAddress LIKE "%'
. $this->db->sql_escape($aTerms[$i])
. '%"';
if ($dotags) {
$query_4 .= ' OR T.tag LIKE "'
. $this->db->sql_escape($aTerms[$i])
@ -917,20 +899,6 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$query_4 .= ' AND B.bHash = "'. $hash .'"';
}
// Exclude bookmarks with shoulder surfing protected tags.
if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
$query_4 .= ' AND B.bId NOT IN (SELECT DISTINCT B0.bId FROM '.
$this->getTableName() .' AS B0, ' . $userservice->getTableName()
.' AS U, ' . $b2tservice->getTableName() .' AS T WHERE B0.uId = U.'
. $userservice->getFieldName('primary') . $privacy .' AND B0.uId = '
. $sId . ' AND (';
$count_s = count($shoulderSurfingProtectedTags);
for ($i = 0; $i < $count_s - 1; $i++) {
$query_4 .= 'T.tag = "'. $shoulderSurfingProtectedTags[$i] .'" OR ';
}
$query_4 .= 'T.tag = "'. $shoulderSurfingProtectedTags[$count_s - 1] .'")'
.' AND T.bId = B0.bId)';
}
$query = $query_1 . $query_2 . $query_3 . $query_4 . $query_5;
@ -943,10 +911,10 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
'', __LINE__, __FILE__, $query, $this->db
);
}
// Disabled because breaks when in debug mode…
//if (SQL_LAYER == 'mysql4') {
// $totalquery = 'SELECT FOUND_ROWS() AS total';
//} else {
if (SQL_LAYER == 'mysql4') {
$totalquery = 'SELECT FOUND_ROWS() AS total';
} else {
if ($hash) {
$totalquery = 'SELECT COUNT(*) AS total'. $query_2
. $query_3 . $query_4;
@ -954,7 +922,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$totalquery = 'SELECT COUNT(DISTINCT bAddress) AS total'
. $query_2 . $query_3 . $query_4;
}
//}
}
if (!($totalresult = $this->db->sql_query($totalquery))
|| (!($row = $this->db->sql_fetchrow($totalresult)))

View File

@ -149,7 +149,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
foreach ($tags as $key => $tag) {
if (strpos($tag, '=')) {
// case "="
$pieces = $tagservice->normalize(explode('=', $tag));
$pieces = explode('=', $tag);
$nbPieces = count($pieces);
if ($nbPieces <= 1) {
continue;
@ -163,7 +163,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
$tags[$key] = $pieces[0];
} else {
// case ">"
$pieces = $tagservice->normalize(explode('>', $tag));
$pieces = explode('>', $tag);
$nbPieces = count($pieces);
if ($nbPieces <= 1) {
continue;
@ -329,7 +329,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
$query = 'SELECT tag, bId FROM ' . $this->getTableName()
. ' WHERE bId IN (' . implode(',', $bookmarkids) . ')'
. ' AND LEFT(tag, 7) <> "system:"'
. ' AND LEFT(tag, 7) <> "system:"'
. ' ORDER BY id, bId ASC';
if (!($dbresult = $this->db->sql_query($query))) {
@ -353,7 +353,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
function &getTags($userid = NULL) {
$userservice = SemanticScuttle_Service_Factory::get('User');
$userservice =SemanticScuttle_Service_Factory::get('User');
$logged_on_user = $userservice->getCurrentUserId();
$query = 'SELECT T.tag, COUNT(B.bId) AS bCount FROM '. $GLOBALS['tableprefix'] .'bookmarks AS B INNER JOIN '. $userservice->getTableName() .' AS U ON B.uId = U.'. $userservice->getFieldName('primary') .' INNER JOIN '. $GLOBALS['tableprefix'] .'bookmarks2tags AS T ON B.bId = T.bId';
@ -366,6 +366,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
} else {
$conditions['B.bStatus'] = 0;
}
$query .= ' WHERE '. $this->db->sql_build_array('SELECT', $conditions) .' AND LEFT(T.tag, 7) <> "system:" GROUP BY T.tag ORDER BY bCount DESC, tag';
if (!($dbresult = $this->db->sql_query($query))) {
@ -374,34 +375,11 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
}
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
return $this->filterShoulderSurfingProtectedTags($output);
}
function &filterShoulderSurfingProtectedTags($dboutput) {
$userservice = SemanticScuttle_Service_Factory::get('User');
if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
$logged_on_user = $userservice->getCurrentUserId();
$ttt = SemanticScuttle_Service_Factory::get('Tag2Tag');
$shoulderSurfingProtectedTags = $ttt->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $logged_on_user, array());
$shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
$output = array();
foreach ($dboutput as $array) {
$flag = 1;
foreach ($shoulderSurfingProtectedTags as $tag) {
if ($array['tag'] === $tag) {
$flag = 0;
break;
}
}
if ($flag) {$output[] = $array;}
}
return $output;
}
else {return $dboutput;}
}
// Returns the tags related to the specified tags; i.e. attached to the same bookmarks
function &getRelatedTags($tags, $for_user = NULL, $logged_on_user = NULL, $limit = 10) {
$conditions = array();
@ -445,7 +423,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
}
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
return $this->filterShoulderSurfingProtectedTags($output);
return $output;
}
// Returns the most popular tags used for a particular bookmark hash
@ -475,7 +453,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
}
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
return $this->filterShoulderSurfingProtectedTags($output);
return $output;
}
@ -635,7 +613,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
return $this->filterShoulderSurfingProtectedTags($output);
return $output;
}

View File

@ -0,0 +1,378 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license AGPL http://www.gnu.org/licenses/agpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
require_once 'SemanticScuttle/Exception/User.php';
require_once 'SemanticScuttle/Model/OpenId.php';
require_once 'OpenID.php';
require_once 'OpenID/RelyingParty.php';
require_once 'OpenID/Extension/SREG11.php';
/**
* SemanticScuttle OpenID verification and management
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license AGPL http://www.gnu.org/licenses/agpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
class SemanticScuttle_Service_OpenId extends SemanticScuttle_DbService
{
/**
* Creates a new instance, sets database variable and table name.
*
* @param sql_db $db Database object
*/
protected function __construct($db)
{
$this->db = $db;
$this->tablename = $GLOBALS['tableprefix'] . 'users_openids';
}
/**
* Returns the single service instance
*
* @param sql_db $db Database object
*
* @return SemanticScuttle_Service_OpenId
*/
public static function getInstance($db)
{
static $instance;
if (!isset($instance)) {
$instance = new self($db);
}
return $instance;
}
/**
* When the user gives an e-mail address instead of an OpenID, we use
* WebFinger to find his OpenID.
*
* @param string $identifier OpenID URL OR e-mail address
*
* @return string Raw/unnormalized OpenID URL.
*
* @throws SemanticScuttle_Exception_User When the user's mail host does not
* support WebFinger
*/
protected function resolveEmailIdentifier($identifier)
{
if (filter_var($identifier, FILTER_VALIDATE_EMAIL) === false) {
//no valid email
return $identifier;
}
require_once 'Net/WebFinger.php';
require_once 'HTTP/Request2.php';
$req = new HTTP_Request2();
$req->setConfig('follow_redirects', true);
$req->setHeader('User-Agent', 'SemanticScuttle');
$wf = new Net_WebFinger();
$wf->setHttpClient($req);
$react = $wf->finger($identifier);
if ($react->openid === null) {
throw new SemanticScuttle_Exception_User(
'No OpenID found for the given email address ' . $identifier,
20
);
}
return $react->openid;
}
/**
* Part 1 of the OpenID login process: Send user to his identity provider.
*
* If an e-mail address is given, a WebFinger lookup is made to find out the
* user's OpenID.
*
* This method exits the PHP process.
*
* @param string $identifier OpenID URL OR e-mail address
* @param string $returnUrl URL the identity provider shall send the user
* back to
*
* @return void No return value needed since it exits.
*
* @throws SemanticScuttle_Exception_User When something goes wrong
*/
public function sendIdRequest($identifier, $returnUrl)
{
$identifier = $this->resolveEmailIdentifier($identifier);
//send request to ID provider
try {
$identifier = OpenID::normalizeIdentifier($identifier);
} catch (OpenID_Exception $e) {
throw new SemanticScuttle_Exception_User(
'Invalid OpenID identifier', 11, $e
);
}
try {
$rp = new OpenID_RelyingParty(
$returnUrl,
addProtocolToUrl(ROOT)/* realm */,
$identifier
);
$authRequest = $rp->prepare();
//FIXME: when user exists already, use immediate mode first and
// fall back to normal when it fails
//FIXME: (?) when user exists already, don't request details
$sreg = new OpenID_Extension_SREG11(OpenID_Extension::REQUEST);
//$sreg->set('required', 'email');
$sreg->set('optional', 'email,nickname,fullname');
$authRequest->addExtension($sreg);
//$auth->setMode(OpenID::MODE_CHECKID_IMMEDIATE);
header('Location: ' . $authRequest->getAuthorizeURL());
exit();
} catch (OpenID_Exception $e) {
throw new SemanticScuttle_Exception_User(
'Error communicating with OpenID identity server', 12, $e
);
}
}
/**
* Part 2 of the OpenID login process: Handle the IDP response
*
* @param string $returnUrl URL the identity provider shall send the user
* back to
*
* @return array Array with user data. Keys:
* - identifier - OpenID URL/identifier
* - userId - Local user ID from database
* - email - OpenID-submitted email
* - nickname - OpenID-submitted nickname
* - fullname - OpenID-submitted full name
*
* @throws SemanticScuttle_Exception_User When something goes wrong
*/
public function handleIdResponse($returnUrl)
{
$rp = new OpenID_RelyingParty(
$returnUrl,
addProtocolToUrl(ROOT)/* realm */
);
if (!count($_POST)) {
list(, $queryString) = explode('?', $_SERVER['REQUEST_URI']);
} else {
$queryString = file_get_contents('php://input');
}
try {
$request = new Net_URL2($returnUrl . '?' . $queryString);
$message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
$mode = $message->get('openid.mode');
if ($mode == 'cancel') {
throw new SemanticScuttle_Exception_User(
'OpenID login cancelled', 10
);
} else if ($mode == 'setup_needed') {
throw new SemanticScuttle_Exception_User(
'Immediate OpenID login not possible', 12
);
}
$result = $rp->verify($request, $message);
if (!$result->success()) {
throw new SemanticScuttle_Exception_User(
'OpenID verification failed', 13
);
}
$identifier = $message->get('openid.claimed_id');
} catch (OpenID_Exception $e) {
throw new SemanticScuttle_Exception_User(
'Unknown OpenID error', 14, $e
);
}
try {
$identifier = OpenID::normalizeIdentifier($identifier);
} catch (OpenID_Exception $e) {
throw new SemanticScuttle_Exception_User(
'Invalid OpenID identifier', 11, $e
);
}
return array(
'identifier' => $identifier,
'userId' => $this->getUserId($identifier),
'email' => $message->get('openid.sreg.email'),
'nickname' => $message->get('openid.sreg.nickname'),
'fullname' => $message->get('openid.sreg.fullname'),
);
}
/**
* Returns the user ID for the given OpenID identifier.
*
* @param string $identifier OpenID identifier (URL)
*
* @return integer User ID or NULL if not found
*
* @throws SemanticScuttle_Exception_User When the identifier is invalid
*/
public function getUserId($identifier)
{
$query = 'SELECT sc_users_openids.uId'
. ' FROM sc_users_openids JOIN sc_users USING (uId)'
. ' WHERE url = "' . $this->db->sql_escape($identifier) . '"';
if (!($dbresult = $this->db->sql_query($query))) {
message_die(
GENERAL_ERROR,
'Could not get user',
'', __LINE__, __FILE__, $query, $this->db
);
}
$row = $this->db->sql_fetchrow($dbresult);
$this->db->sql_freeresult($dbresult);
if (!$row) {
//OpenID not found in database.
return null;
}
return $row['uId'];
}
/**
* Add an OpenID to a given user
*
* @param integer $uId User ID to attach the OpenID to
* @param string $identifier OpenID identifier (URL)
* @param string $email OpenID-delivered e-mail address of the user
*
* @return void
*
* @throws SemanticScuttle_Exception When something goes wrong,
* e.g. the OpenID is already registered
*/
public function register($uId, $identifier, $email = null)
{
if ($this->getId($identifier) !== null) {
//already registered
throw new SemanticScuttle_Exception_User(
'OpenID already registered: ' . $identifier,
21
);
}
//FIXME: use email when google-openid
$query = 'INSERT INTO ' . $this->getTableName()
. ' ' . $this->db->sql_build_array(
'INSERT', array(
'uId' => $uId,
'url' => $identifier,
)
);
if (!($dbresult = $this->db->sql_query($query))) {
message_die(
GENERAL_ERROR, 'Could not register OpenID',
'', __LINE__, __FILE__, $query, $this->db
);
}
}
/**
* Deletes the OpenID with the given numeric database ID
*
* @param integer $id Numeric ID from database
*
* @return boolean True if it worked, false if not
*/
public function delete($id)
{
if ($id instanceof SemanticScuttle_Model_OpenId) {
$id = $id->id;
}
$id = (int)$id;
$query = 'DELETE FROM ' . $this->getTableName()
.' WHERE id = ' . $id;
if (!($dbresult = $this->db->sql_query($query))) {
message_die(
GENERAL_ERROR, 'Could not delete OpenID',
'', __LINE__, __FILE__, $query, $this->db
);
return false;
}
return true;
}
/**
* Loads an OpenID object from the given identifiert
*
* @param string $identifier OpenID identifier (URL)
*
* @return SemanticScuttle_Model_OpenId OpenID object or NULL if not found
*/
public function getId($identifier)
{
$query = 'SELECT * FROM ' . $this->getTableName()
. ' WHERE url = "' . $this->db->sql_escape($identifier) . '"';
if (!($dbresult = $this->db->sql_query($query))) {
message_die(
GENERAL_ERROR, 'Could not load OpenID',
'', __LINE__, __FILE__, $query, $this->db
);
return null;
}
if ($row = $this->db->sql_fetchrow($dbresult)) {
$cert = SemanticScuttle_Model_OpenId::fromDb($row);
} else {
$cert = null;
}
$this->db->sql_freeresult($dbresult);
return $cert;
}
/**
* Fetch all OpenIDs the given user has attached
*
* @param integer $uId User ID to fetch registered OpenIDs for
*
* @return array Array of SemanticScuttle_Model_OpenId objects
*/
public function getIds($uId)
{
$query = 'SELECT * FROM ' . $this->getTableName()
. ' WHERE uId = ' . (int)$uId
. ' ORDER BY url ASC';
if (!($dbresult = $this->db->sql_query($query))) {
message_die(
GENERAL_ERROR, 'Could not load OpenIDs',
'', __LINE__, __FILE__, $query, $this->db
);
return array();
}
$certs = array();
while ($row = $this->db->sql_fetchrow($dbresult)) {
$certs[] = SemanticScuttle_Model_OpenId::fromDb($row);
}
$this->db->sql_freeresult($dbresult);
return $certs;
}
}
?>

View File

@ -151,10 +151,6 @@ class SemanticScuttle_Service_SearchHistory extends SemanticScuttle_DbService
$range = null, $uId = null, $nb = null,
$start = null, $distinct = false, $withResults = false
) {
$userservice = SemanticScuttle_Service_Factory::get('User');
if ($userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
return array();
}
$sql = 'SELECT DISTINCT(shTerms),'
. ' shId, shRange, shNbResults, shDatetime, uId';
$sql.= ' FROM '. $this->getTableName();

View File

@ -318,8 +318,7 @@ class SemanticScuttle_Service_Tag2Tag extends SemanticScuttle_DbService
}
$output = $this->db->sql_fetchrowset($dbresult);
$this->db->sql_freeresult($dbresult);
$btt = SemanticScuttle_Service_Factory::get('Bookmark2Tag');
return $btt->filterShoulderSurfingProtectedTags($output);
return $output;
}
function getMenuTags($uId) {
@ -378,25 +377,6 @@ class SemanticScuttle_Service_Tag2Tag extends SemanticScuttle_DbService
$dbres = $this->db->sql_query($query);
$rowset = $this->db->sql_fetchrowset($dbres);
$this->db->sql_freeresult($dbres);
$userservice = SemanticScuttle_Service_Factory::get('User');
if (count($rowset)>0 && ! empty($GLOBALS['shoulderSurfingProtectedTag']) && $userservice->isLoggedOn() && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
$logged_on_user = $userservice->getCurrentUserId();
$shoulderSurfingProtectedTags = $this->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $logged_on_user, array());
$shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
$output = array();
foreach($rowset as $link) {
$flag = 1;
foreach ($shoulderSurfingProtectedTags as $tag) {
if ($link['tag1'] === $tag || $link['tag2'] === $tag) {
$flag = 0;
break;
}
}
if ($flag) {$output[] = $link;}
}
$rowset = $output;
}
return $rowset;
}

View File

@ -1,59 +0,0 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
/**
* Instantiates the configured website thumbnailer object.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
class SemanticScuttle_Service_Thumbnails extends SemanticScuttle_Service
{
/**
* Instantiates the configured website thumbnailer object.
*
* @return object Website thumbnailer
*/
public function getThumbnailer()
{
if (!isset($GLOBALS['thumbnailsType'])
|| $GLOBALS['thumbnailsType'] == ''
) {
$class = 'SemanticScuttle_Thumbnailer_Null';
} else {
$class = 'SemanticScuttle_Thumbnailer_'
. ucfirst($GLOBALS['thumbnailsType']);
}
if (!class_exists($class)) {
//PEAR classname to filename rule
$file = str_replace('_', '/', $class) . '.php';
include_once $file;
}
$thumbnailer = new $class();
if (!isset($GLOBALS['thumbnailsConfig'])
|| $GLOBALS['thumbnailsConfig'] == ''
) {
$thumbnailer->setConfig(null);
} else {
$thumbnailer->setConfig($GLOBALS['thumbnailsConfig']);
}
return $thumbnailer;
}
}
?>

View File

@ -1,52 +0,0 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
/**
* Dummy thumbnailer that never returns a thumbnail URL
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
class SemanticScuttle_Thumbnailer_Null
{
/**
* Set dummy configuration
*
* @param array $config Dummy configuration
*
* @return void
*/
public function setConfig($config)
{
}
/**
* Get the URL for a website thumbnail.
* Always returns false.
*
* @param string $bookmarkUrl URL of website to create thumbnail for
* @param integer $width Screenshot width
* @param integer $height Screenshot height
*
* @return mixed FALSE when no screenshot could be obtained,
* string with the URL otherwise
*/
public function getThumbnailUrl($bookmarkUrl, $width, $height)
{
return false;
}
}
?>

View File

@ -1,92 +0,0 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
/**
* Show website thumbnails/screenshots using phancap
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
* @see http://cweiske.de/phancap.htm
*/
class SemanticScuttle_Thumbnailer_Phancap
{
/**
* Configuration array.
* Required keys:
* - url
* - token
* - secret
*/
protected $config = array();
/**
* Set phancap configuration
*
* @param array $config Phancap configuration
*
* @return void
*/
public function setConfig($config)
{
$this->config = $config;
}
/**
* Get the URL for a website thumbnail
*
* @param string $bookmarkUrl URL of website to create thumbnail for
* @param integer $width Screenshot width
* @param integer $height Screenshot height
*
* @return mixed FALSE when no screenshot could be obtained,
* string with the URL otherwise
*/
public function getThumbnailUrl($bookmarkUrl, $width, $height)
{
//default parameters for the phancap service
$parameters = array(
'url' => $bookmarkUrl,
'swidth' => $width,
'sheight' => $height,
'sformat' => 'jpg',
);
if (isset($this->config['token']) && $this->config['token'] != '') {
$parameters['atoken'] = $this->config['token'];
$parameters['atimestamp'] = time();
//create signature
ksort($parameters);
foreach ($parameters as $key => $value) {
$encparams[] = $key . '=' . rawurlencode($value);
}
$encstring = implode('&', $encparams);
$signature = hash_hmac('sha1', $encstring, $this->config['secret']);
//append signature to parameters
$parameters['asignature'] = $signature;
}
//url-encode the parameters
$urlParams = array();
foreach ($parameters as $key => $value) {
$urlParams[] = $key . '=' . urlencode($value);
}
//final URL
return $this->config['url'] . '?' . implode('&', $urlParams);
}
}
?>

View File

@ -281,14 +281,13 @@ class sql_db
if ($query_id)
{
$id = (int) $query_id;
unset($this->rowset[$id]);
unset($this->row[$id]);
unset($this->rowset[$query_id]);
unset($this->row[$query_id]);
$result = array();
while ($this->rowset[$id] = $this->sql_fetchrow($query_id))
while ($this->rowset[$query_id] = $this->sql_fetchrow($query_id))
{
$result[] = $this->rowset[$id];
$result[] = $this->rowset[$query_id];
}
return $result;
}
@ -550,4 +549,4 @@ class sql_db
} // if ... define
?>
?>

View File

@ -87,7 +87,7 @@ require_once 'SemanticScuttle/constants.php';
// Debug Management using constants
if (DEBUG_MODE) {
ini_set('display_errors', '0');
ini_set('display_errors', '1');
ini_set('mysql.trace_mode', '1');
error_reporting(E_ALL);
} else {
@ -96,15 +96,12 @@ if (DEBUG_MODE) {
error_reporting(0);
}
// 2 // Second requirements part which could display bugs
// (must come after debug management)
require_once 'SemanticScuttle/Service.php';
require_once 'SemanticScuttle/DbService.php';
require_once 'SemanticScuttle/Service/Factory.php';
require_once 'silex.phar';
//modify silex/symfony autoloader
$loader->useIncludePath(true);
require_once 'SemanticScuttle/functions.php';
require_once 'SemanticScuttle/Model/Bookmark.php';
require_once 'SemanticScuttle/Model/UserArray.php';
require_once 'SemanticScuttle/Model/User/SslClientCert.php';
if (count($GLOBALS['serviceoverrides']) > 0
&& !defined('UNIT_TEST_MODE')
@ -171,29 +168,4 @@ if (!defined('UNIT_TEST_MODE') || defined('HTTP_UNIT_TEST_MODE')) {
header('Content-Type: ' . $httpContentType . '; charset=utf-8');
}
}
// 7 // Block everything if global private mode enabled and user not logged on
// This is required to prevent breaking the API. Some API PHP source files include httpauth.inc.php
// which already check if the user is logged on and include www-header.php.
// We also allow password.php so users can reset their password and login.php so they can log in.
if (isset($GLOBALS['privatemode'])) {
if ($GLOBALS['privatemode'] && ! $userservice->isLoggedOn()) {
$flag = 1;
$included_files = get_included_files();
foreach ($included_files as $filename) {
if (strpos($filename,'httpauth.inc.php') !== false || strpos($filename,'password.php') !== false || strpos($filename,'login.php') !== false) {
$flag = 0;
break;
}
}
if ($flag) {
$tplVars['error'] = T_('You must log in.');
$tplVars['subtitle'] = T_('Log In');
$tplVars['formaction'] = createURL('login');
$tplVars['querystring'] = filter($_SERVER['QUERY_STRING']);
$templateservice->loadTemplate('login.tpl', $tplVars);
die();
}
}
}
?>

View File

@ -1,149 +0,0 @@
<?php
/***************************************************************************
The MIT License (MIT)
Copyright (c) 2015 kafene
https://github.com/kafene/netscape-bookmark-parser
http://kafene.org
Slightly modified by yohan.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
***************************************************************************/
/**
* Basically netscape bookmark files often come so badly formed, there's
* no reliable way I could find to parse them with DOM or SimpleXML,
* even after running HTML Tidy on them. So, this function does a bunch of
* transformations on the general format of a netscape bookmark file, to get
* Each bookmark and its description onto one line, and goes through line by
* line, matching tags and attributes. It's messy, but it works better than
* anything I could find in hours of googling, and anything that I could
* write after hours with DOM and SimpleXML. I didn't want to pull in a big
* DOM parsing library just to do this one thing, so this is it.
*/
/*
print '<PRE>';
var_dump(parse_netscape_bookmarks(file_get_contents('bookmarks_export.htm')));
*/
function parse_netscape_bookmarks($bkmk_str, $default_tag = null) {
$i = 0;
$next = false;
$items = [];
$current_tag = $default_tag = $default_tag ?: 'autoimported-'.date("Ymd");
$bkmk_str = str_replace(["\r","\n","\t"], ['','',' '], $bkmk_str);
$bkmk_str = preg_replace_callback('@<dd>(.*?)(<A|<\/|<DL|<DT|<P)@mis', function($m) {
return '<dd>'.str_replace(["\r", "\n"], ['', '<br>'], trim($m[1])).'</';
}, $bkmk_str);
$bkmk_str = preg_replace('/>(\s*?)</mis', ">\n<", $bkmk_str);
$bkmk_str = preg_replace('/(<!DOCTYPE|<META|<!--|<TITLE|<H1|<P)(.*?)\n/i', '', $bkmk_str);
$bkmk_str = trim($bkmk_str);
$bkmk_str = preg_replace('/\n<dd/i', '<dd', $bkmk_str);
//best way to do it :
$bkmk_str = preg_replace('/(?<=.)<\/DL>/', "\n</DL>", $bkmk_str);
$lines = explode("\n", $bkmk_str);
$str_bool = function($str, $default = false) {
if (!$str) {
return false;
} elseif (!is_string($str) && $str) {
return true;
}
$true = 'y|yes|on|checked|ok|1|true|array|\+|okay|yes+|t|one';
$false = 'n|no|off|empty|null|false|0|-|exit|die|neg|f|zero|void';
if (preg_match("/^($true)$/i", $str)) {
return true;
} elseif (preg_match("/^($false)$/i", $str)) {
return false;
}
return $default;
};
$tags = array($default_tag);
foreach ($lines as $line_no => $line) {
/* If we match a tag, set current tag to that, if <DL>, stop tag. */
if (preg_match('/^<h\d(.*?)>(.*?)<\/h\d>/i', $line, $m1)) {
$current_tag = trim(preg_replace("/\s+/", "_", strtr($m1[2], ', /+', '____')));
$tags[] = $current_tag;
continue;
} elseif (preg_match('/^<\/DL>/i', $line)) {
$current_tag = $default_tag;
array_pop($tags);
}
if (preg_match('/<a/i', $line, $m2)) {
$items[$i]['tags'] = $tags;
if (preg_match('/href="(.*?)"/i', $line, $m3)) {
$items[$i]['uri'] = $m3[1];
// $items[$i]['meta'] = meta($m3[1]);
} else {
$items[$i]['uri'] = '';
// $items[$i]['meta'] = '';
}
if (preg_match('/<a(.*?)>(.*?)<\/a>/i', $line, $m4)) {
$items[$i]['title'] = $m4[2];
// $items[$i]['slug'] = slugify($m4[2]);
} else {
$items[$i]['title'] = 'untitled';
// $items[$i]['slug'] = '';
}
if (preg_match('/note="(.*?)"<\/a>/i', $line, $m5)) {
$items[$i]['note'] = $m5[1];
} elseif (preg_match('/<dd>(.*?)<\//i', $line, $m6)) {
$items[$i]['note'] = str_replace('<br>', "\n", $m6[1]);
} else {
$items[$i]['note'] = '';
}
if (preg_match('/(tags?|labels?|folders?)="(.*?)"/i', $line, $m7)) {
array_unique(array_merge($items[$i]['tags'], explode(' ', trim(preg_replace("/\s+/", " ", strtr($m7[2], ',', ' '))))));
}
if (preg_match('/add_date="(.*?)"/i', $line, $m8)) {
$items[$i]['time'] = $m8[1];
} else {
$items[$i]['time'] = time();
}
if (preg_match('/(public|published|pub)="(.*?)"/i', $line, $m9)) {
$items[$i]['pub'] = $str_bool($m9[2], false) ? 1 : 0;
} elseif (preg_match('/(private|shared)="(.*?)"/i', $line, $m10)) {
$items[$i]['pub'] = $str_bool($m10[2], true) ? 0 : 1;
}
$i++;
}
}
ksort($items);
return $items;
}
?>

BIN
src/silex.phar Normal file

Binary file not shown.

View File

@ -22,7 +22,6 @@ require_once 'www-header.php';
$tplVars['pagetitle'] = T_('About');
$tplVars['subtitle'] = T_('About');
$tplVars['loadjs'] = true;
$templateservice->loadTemplate('about.tpl', $tplVars);
?>
?>

View File

@ -1,33 +0,0 @@
<?php
require_once '../www-header.php';
if(isset($_POST['password']) && $userservice->isLoggedOn()){
$password = $userservice->sanitisePassword($_POST['password']);
$username = $currentUser->getUsername();
$db = SemanticScuttle_Service_Factory::getDb();
$query = 'SELECT '. $userservice->getFieldName('primary') .' FROM '. $userservice->getTableName() .' WHERE '. $userservice->getFieldName('username') .' = "'. $db->sql_escape($username) .'" AND '. $userservice->getFieldName('password') .' = "'. $db->sql_escape($password) .'"';
if (!($dbresult = $db->sql_query($query))) {
message_die(
GENERAL_ERROR,
'Could not get user',
'', __LINE__, __FILE__, $query, $db
);
echo 'false';
}
else {
$row = $db->sql_fetchrow($dbresult);
$db->sql_freeresult($dbresult);
if ($row) {
echo 'true';
}
else {
echo 'false';
}
}
}
else {
echo 'false';
}
?>

View File

@ -138,4 +138,4 @@ $tagData = assembleLinkedTagData(
SemanticScuttle_Service_Factory::get('Tag2Tag')
);
echo json_encode($tagData);
?>
?>

View File

@ -72,6 +72,7 @@ if (isset($userid)) {
} else {
$tplVars['cat_url'] = createURL('tags', '%2$s');
}
$tplVars['sidebar_blocks'] = array('linked');
$tplVars['userid'] = $userid;
$tplVars['loadjs'] = true;

View File

@ -29,21 +29,15 @@ $cacheservice =SemanticScuttle_Service_Factory::get('Cache');
isset($_GET['action']) ? define('GET_ACTION', $_GET['action']): define('GET_ACTION', '');
isset($_POST['submitted']) ? define('POST_SUBMITTED', $_POST['submitted']): define('POST_SUBMITTED', '');
// define does not support arrays before PHP version 7
isset($_GET['title']) ? $TITLE = $_GET['title']: $TITLE = array();
//isset($_GET['title']) ? define('GET_TITLE', $_GET['title']): define('GET_TITLE', '');
isset($_GET['address']) ? $ADDRESS = $_GET['address']: $ADDRESS = array();
//isset($_GET['address']) ? define('GET_ADDRESS', $_GET['address']): define('GET_ADDRESS', '');
isset($_GET['title']) ? define('GET_TITLE', $_GET['title']): define('GET_TITLE', '');
isset($_GET['address']) ? define('GET_ADDRESS', $_GET['address']): define('GET_ADDRESS', '');
isset($_GET['description']) ? define('GET_DESCRIPTION', $_GET['description']): define('GET_DESCRIPTION', '');
isset($_GET['privateNote']) ? define('GET_PRIVATENOTE', $_GET['privateNote']): define('GET_PRIVATENOTE', '');
isset($_GET['tags']) ? define('GET_TAGS', $_GET['tags']): define('GET_TAGS', '');
isset($_GET['copyOf']) ? define('GET_COPYOF', $_GET['copyOf']): define('GET_COPYOF', '');
// define does not support arrays before PHP version 7
isset($_POST['title']) ? $TITLE = $_POST['title']: $TITLE = array();
//isset($_POST['title']) ? define('POST_TITLE', $_POST['title']): define('POST_TITLE', '');
isset($_POST['address']) ? $ADDRESS = $_POST['address']: $ADDRESS = array();
//isset($_POST['address']) ? define('POST_ADDRESS', $_POST['address']): define('POST_ADDRESS', '');
isset($_POST['title']) ? define('POST_TITLE', $_POST['title']): define('POST_TITLE', '');
isset($_POST['address']) ? define('POST_ADDRESS', $_POST['address']): define('POST_ADDRESS', '');
isset($_POST['description']) ? define('POST_DESCRIPTION', $_POST['description']): define('POST_DESCRIPTION', '');
isset($_POST['privateNote']) ? define('POST_PRIVATENOTE', $_POST['privateNote']): define('POST_PRIVATENOTE', '');
isset($_POST['status']) ? define('POST_STATUS', $_POST['status']): define('POST_STATUS', '');
@ -54,22 +48,12 @@ isset($_POST['popup']) ? define('POST_POPUP', $_POST['popup']): define('POST_POP
isset($_GET['page']) ? define('GET_PAGE', $_GET['page']): define('GET_PAGE', 0);
isset($_GET['sort']) ? define('GET_SORT', $_GET['sort']): define('GET_SORT', '');
isset($_GET['batch']) ? define('GET_BATCH', $_GET['batch']): define('GET_BATCH', 0);
if (!isset($_POST['tags'])) {
$_POST['tags'] = array();
}
if (!isset($_POST['removetags'])) {
$_POST['removetags'] = array();
}
//echo '<p>' . var_export($_POST, true) . '</p>';die();
if (! is_array($ADDRESS)) {
$ADDRESS = array($ADDRESS);
}
if (! is_array($TITLE)) {
$TITLE = array($TITLE);
}
if ((GET_ACTION == "add") && !$userservice->isLoggedOn()) {
$loginqry = str_replace("'", '%27', stripslashes($_SERVER['QUERY_STRING']));
@ -146,119 +130,71 @@ $tplVars['loadjs'] = true;
$saved = false;
$templatename = 'bookmarks.tpl';
if ($userservice->isLoggedOn() && POST_SUBMITTED != '') {
if (!$TITLE || !$ADDRESS) {
if (!POST_TITLE || !POST_ADDRESS) {
$tplVars['error'] = T_('Your bookmark must have a title and an address');
$templatename = 'editbookmark.tpl';
}
else {
$address = array_map('trim', $ADDRESS);
$valid = 1;
foreach($address as $value) {
if (!SemanticScuttle_Model_Bookmark::isValidUrl($value)) {
$tplVars['error'] = T_('This bookmark URL may not be added' + $value);
$templatename = 'editbookmark.tpl';
$valid = 0;
break;
}
}
if ($valid) {
$title = array_map('trim', $TITLE);
$description = trim(POST_DESCRIPTION);
$privateNote = trim(POST_PRIVATENOTE);
$status = intval(POST_STATUS);
$categories = array_map('trim', explode(',', trim($_POST['tags'])));
$removecategories = array_map('trim', explode(',', trim($_POST['removetags'])));
$saved = true;
foreach($address as $index => $value) {
if ($bookmarkservice->bookmarkExists($value, $currentUserID)) {
// If the bookmark exists already, edit the original
$bookmark = $bookmarkservice->getBookmarkByAddress($value);
$bId = intval($bookmark['bId']);
$row = $bookmarkservice->getBookmark($bId, true);
$categories = array_unique(array_merge($row['tags'], $categories));
// remove tags
$categories = array_diff($categories, $removecategories);
if (!$bookmarkservice->updateBookmark($bId, $value, $title[$index], $description, $privateNote, $status, $categories)) {
$tplvars['error'] = T_('Error while saving this bookmark : ' + $value);
$templatename = 'editbookmark.tpl';
$saved = false;
break;
}
}
// If it's new, save it
elseif (!$bookmarkservice->addBookmark($value, $title[$index], $description, $privateNote, $status, $categories)) {
$tplVars['error'] = T_('There was an error saving this bookmark : ' + $value + ' Please try again or contact the administrator.');
$templatename = 'editbookmark.tpl';
$saved = false;
break;
}
}
if ($saved) {
if (POST_POPUP != '') {
$tplVars['msg'] = '<script type="text/javascript">window.close();</script>';
}
else {
$tplVars['msg'] = T_('Bookmark saved') . ' <a href="javascript:history.go(-2)">'.T_('(Come back to previous page.)').'</a>';
}
}
}
} else {
$address = trim(POST_ADDRESS);
if (!SemanticScuttle_Model_Bookmark::isValidUrl($address)) {
$tplVars['error'] = T_('This bookmark URL may not be added');
$templatename = 'editbookmark.tpl';
} else if ($bookmarkservice->bookmarkExists($address, $currentUserID)) {
// If the bookmark exists already, edit the original
$bookmark = $bookmarkservice->getBookmarkByAddress($address);
header('Location: '. createURL('edit', $bookmark['bId']));
exit();
// If it's new, save it
} else {
$title = trim(POST_TITLE);
$description = trim(POST_DESCRIPTION);
$privateNote = trim(POST_PRIVATENOTE);
$status = intval(POST_STATUS);
$categories = explode(',', $_POST['tags']);
$saved = true;
if ($bookmarkservice->addBookmark($address, $title, $description, $privateNote, $status, $categories)) {
if (POST_POPUP != '') {
$tplVars['msg'] = '<script type="text/javascript">window.close();</script>';
} else {
$tplVars['msg'] = T_('Bookmark saved') . ' <a href="javascript:history.go(-2)">'.T_('(Come back to previous page.)').'</a>';
// Redirection option
if ($GLOBALS['useredir']) {
$address = $GLOBALS['url_redir'] . $address;
}
}
} else {
$tplVars['error'] = T_('There was an error saving your bookmark. Please try again or contact the administrator.');
$templatename = 'editbookmark.tpl';
$saved = false;
}
}
}
}
if (GET_ACTION == "add" || GET_BATCH) {
if (GET_ACTION == "add") {
// If the bookmark exists already, edit the original
if (count($ADDRESS) === 1) {
if ($bookmarkservice->bookmarkExists(stripslashes($ADDRESS[0]), $currentUserID)) {
$bookmark =& $bookmarkservice->getBookmarks(0, NULL, $currentUserID, NULL, NULL, NULL, NULL, NULL, NULL, $bookmarkservice->getHash(stripslashes($ADDRESS[0])));
$popup = (GET_POPUP!='') ? '?popup=1' : '';
header('Location: '. createURL('edit', $bookmark['bookmarks'][0]['bId'] . $popup));
exit();
}
if ($bookmarkservice->bookmarkExists(stripslashes(GET_ADDRESS), $currentUserID)) {
$bookmark = $bookmarkservice->getBookmarks(0, NULL, $currentUserID, NULL, NULL, NULL, NULL, NULL, NULL, $bookmarkservice->getHash(stripslashes(GET_ADDRESS)));
$popup = (GET_POPUP!='') ? '?popup=1' : '';
header('Location: '. createURL('edit', $bookmark['bookmarks'][0]['bId'] . $popup));
exit();
}
$templatename = 'editbookmark.tpl';
}
if ($templatename == 'editbookmark.tpl') { // Prepare to display the edit bookmark page.
if ($templatename == 'editbookmark.tpl') {
if ($userservice->isLoggedOn()) {
$tplVars['formaction'] = createURL('bookmarks', $currentUsername);
if (POST_SUBMITTED != '') {
$tplVars['row'] = array(
'bTitle' => array_map('stripslashes', $TITLE),
'bAddress' => array_map('stripslashes', $ADDRESS),
'bDescription' => stripslashes(POST_DESCRIPTION),
'bPrivateNote' => stripslashes(POST_PRIVATENOTE),
'tags' => ($_POST['tags'] ? $_POST['tags'] : array()),
'bTitle' => stripslashes(POST_TITLE),
'bAddress' => stripslashes(POST_ADDRESS),
'bDescription' => stripslashes(POST_DESCRIPTION),
'bPrivateNote' => stripslashes(POST_PRIVATENOTE),
'tags' => ($_POST['tags'] ? $_POST['tags'] : array()),
'bStatus' => $GLOBALS['defaults']['privacy'],
);
$tplVars['tags'] = $_POST['tags'];
}
elseif (GET_BATCH) {
$completebookmarks = $bookmarkservice->getBookmarks(0, null, $userid, $cat, null, getSortOrder());
$addresses2 = array();
$titles2 = array();
$tags2 = array();
foreach ($completebookmarks['bookmarks'] as $key => &$row) {
$addresses2[$row['bId']] = $row['bAddress'];
$titles2[$row['bId']] = $row['bTitle'];
$row = $bookmarkservice->getBookmark($row['bId'], true);
$tags2[] = $row['tags'];
}
$alltags2 = array_unique(call_user_func_array('array_merge', $tags2));
$commontags2 = call_user_func_array('array_intersect', $tags2);
$tplVars['row'] = array(
'bTitle' => $titles2,
'bAddress' => $addresses2,
'bDescription' => '',
'bPrivateNote' => '',
'tags' => array(),
'bStatus' => $GLOBALS['defaults']['privacy']
);
$tplVars['batch'] = '1';
$tplVars['alltags'] = implode(', ', $alltags2);
$tplVars['commontags'] = implode(', ', $commontags2);
}
else {
} else {
if(GET_COPYOF != '') { //copy from bookmarks page
$tplVars['row'] = $bookmarkservice->getBookmark(intval(GET_COPYOF), true);
if(!$currentUser->isAdmin()) {
@ -266,12 +202,12 @@ if ($templatename == 'editbookmark.tpl') { // Prepare to display the edit bookma
}
}else { //copy from pop-up bookmarklet
$tplVars['row'] = array(
'bTitle' => array_map('stripslashes', $TITLE),
'bAddress' => array_map('stripslashes', $ADDRESS),
'bDescription' => stripslashes(GET_DESCRIPTION),
'bPrivateNote' => stripslashes(GET_PRIVATENOTE),
'tags' => (GET_TAGS ? explode(',', stripslashes(GET_TAGS)) : array()),
'bStatus' => $GLOBALS['defaults']['privacy']
'bTitle' => stripslashes(GET_TITLE),
'bAddress' => stripslashes(GET_ADDRESS),
'bDescription' => stripslashes(GET_DESCRIPTION),
'bPrivateNote' => stripslashes(GET_PRIVATENOTE),
'tags' => (GET_TAGS ? explode(',', stripslashes(GET_TAGS)) : array()),
'bStatus' => $GLOBALS['defaults']['privacy']
);
}
@ -293,46 +229,20 @@ if ($templatename == 'editbookmark.tpl') { // Prepare to display the edit bookma
$tplVars['sidebar_blocks'] = array('watchstatus');
if (!$cat) { //user page without tags
$rssTitle = "My Bookmarks";
$rssTitle = "My Bookmarks";
$cat = NULL;
$tplVars['currenttag'] = NULL;
//$tplVars['sidebar_blocks'][] = 'menu2';
$tplVars['sidebar_blocks'][] = 'linked';
$tplVars['sidebar_blocks'][] = 'popular';
} else { //pages with tags
$rssTitle = "Tags" . $catTitle;
$rssTitle = "Tags" . $catTitle;
$rssCat = '/'. filter($cat, 'url');
$tplVars['currenttag'] = $cat;
$tplVars['sidebar_blocks'][] = 'tagactions';
//$tplVars['sidebar_blocks'][] = 'menu2';
if (! empty($GLOBALS['shoulderSurfingProtectedTag']) && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
$tag2tagservice = SemanticScuttle_Service_Factory::get('Tag2Tag');
$b2tservice = SemanticScuttle_Service_Factory::get('Bookmark2Tag');
$alltags = $b2tservice->getTags($currentUserID);
$shoulderSurfingProtectedTags = $tag2tagservice->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $currentUserID, array());
$shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
$flag = 0;
if (! in_array($cat, $shoulderSurfingProtectedTags, true)) {
foreach ($alltags as $tag) {
if ($tag['tag'] === $cat) {
$flag = 1;
break;
}
}
}
if ($flag) {
$tplVars['sidebar_blocks'][] = 'tagactions';
$tplVars['sidebar_blocks'][] = 'linked';
$tplVars['sidebar_blocks'][] = 'related';
}
}
else {
$tplVars['sidebar_blocks'][] = 'tagactions';
$tplVars['sidebar_blocks'][] = 'linked';
$tplVars['sidebar_blocks'][] = 'related';
}
$tplVars['sidebar_blocks'][] = 'linked';
$tplVars['sidebar_blocks'][] = 'related';
/*$tplVars['sidebar_blocks'][] = 'menu';*/
}
$tplVars['sidebar_blocks'][] = 'menu2';
@ -363,24 +273,24 @@ if ($templatename == 'editbookmark.tpl') { // Prepare to display the edit bookma
)
);
if ($userservice->isLoggedOn()) {
$currentUsername = $currentUser->getUsername();
if ($userservice->isPrivateKeyValid($currentUser->getPrivateKey())) {
array_push(
$tplVars['rsschannels'],
array(
sprintf(
T_('%s: %s (+private %s)'),
$sitename, $rssTitle, $currentUsername
),
createURL('rss', filter($currentUsername, 'url'))
. $rssCat
. '?sort=' . getSortOrder()
. '&privateKey=' . $currentUser->getPrivateKey()
)
);
}
if ($userservice->isLoggedOn()) {
$currentUsername = $currentUser->getUsername();
if ($userservice->isPrivateKeyValid($currentUser->getPrivateKey())) {
array_push(
$tplVars['rsschannels'],
array(
sprintf(
T_('%s: %s (+private %s)'),
$sitename, $rssTitle, $currentUsername
),
createURL('rss', filter($currentUsername, 'url'))
. $rssCat
. '?sort=' . getSortOrder()
. '&privateKey=' . $currentUser->getPrivateKey()
)
);
}
}
$tplVars['page'] = $page;
$tplVars['start'] = $start;

View File

@ -29,12 +29,8 @@ $bookmarkservice = SemanticScuttle_Service_Factory :: get('Bookmark');
isset($_POST['submitted']) ? define('POST_SUBMITTED', $_POST['submitted']): define('POST_SUBMITTED', '');
isset($_POST['delete']) ? define('POST_DELETE', $_POST['delete']): define('POST_DELETE', '');
// define does not support arrays before PHP version 7
isset($_POST['title']) ? $TITLE = $_POST['title']: $TITLE = array();
//isset($_POST['title']) ? define('POST_TITLE', $_POST['title']): define('POST_TITLE', '');
isset($_POST['address']) ? $ADDRESS = $_POST['address']: $ADDRESS = array();
//isset($_POST['address']) ? define('POST_ADDRESS', $_POST['address']): define('POST_ADDRESS', '');
isset($_POST['title']) ? define('POST_TITLE', $_POST['title']): define('POST_TITLE', '');
isset($_POST['address']) ? define('POST_ADDRESS', $_POST['address']): define('POST_ADDRESS', '');
isset($_POST['description']) ? define('POST_DESCRIPTION', $_POST['description']): define('POST_DESCRIPTION', '');
isset($_POST['privateNote']) ? define('POST_PRIVATENOTE', $_POST['privateNote']): define('POST_PRIVATENOTE', '');
isset($_POST['status']) ? define('POST_STATUS', $_POST['status']): define('POST_STATUS', $GLOBALS['defaults']['privacy']);
@ -44,14 +40,6 @@ isset($_GET['popup']) ? define('GET_POPUP', $_GET['popup']): define('GET_POPUP',
isset($_POST['popup']) ? define('POST_POPUP', $_POST['popup']): define('POST_POPUP', '');
isset($_POST['referrer']) ? define('POST_REFERRER', $_POST['referrer']): define('POST_REFERRER', '');
if (! is_array($ADDRESS)) {
$ADDRESS = array($ADDRESS);
}
if (! is_array($TITLE)) {
$TITLE = array($TITLE);
}
// Header variables
$tplVars['pagetitle'] = T_('Edit Bookmark');
$tplVars['subtitle'] = T_('Edit Bookmark');
@ -64,24 +52,28 @@ if (!($row = $bookmarkservice->getBookmark(intval($bookmark), true))) {
$templateservice->loadTemplate('error.404.tpl', $tplVars);
exit();
} else {
if (!$bookmarkservice->editAllowed($row)) {
$tplVars['error'] = T_('You are not allowed to edit this bookmark');
$templateservice->loadTemplate('error.500.tpl', $tplVars);
exit();
} else if (POST_SUBMITTED != '') {
if (!$TITLE || !$ADDRESS) {
if (!POST_TITLE || !POST_ADDRESS) {
$tplVars['error'] = T_('Your bookmark must have a title and an address');
} else {
// Update bookmark
$bId = intval($bookmark);
$address = array_map('trim', $ADDRESS);
$title = array_map('trim', $TITLE);
$address = trim(POST_ADDRESS);
$title = trim(POST_TITLE);
$description = trim(POST_DESCRIPTION);
$privateNote = trim(POST_PRIVATENOTE);
$status = intval(POST_STATUS);
$tags = trim(POST_TAGS);
if (!$bookmarkservice->updateBookmark($bId, $address[0], $title[0], $description, $privateNote, $status, $tags)) {
if (!$bookmarkservice->updateBookmark($bId, $address, $title, $description, $privateNote, $status, $tags)) {
$tplvars['error'] = T_('Error while saving your bookmark');
} else {
if (POST_POPUP != '') {

View File

@ -20,13 +20,6 @@
***************************************************************************/
require_once 'www-header.php';
if ('@data_dir@' == '@' . 'data_dir@') {
//non pear-install
require_once dirname(__FILE__) . '/../src/SemanticScuttle/parse_netscape_bookmarks.php';
} else {
//pear installation; files are in include path
require_once 'SemanticScuttle/parse_netscape_bookmarks.php';
}
/* Service creation: only useful services are created */
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
@ -51,45 +44,78 @@ if ($userservice->isLoggedOn() && sizeof($_FILES) > 0 && $_FILES['userfile']['si
// File handle
$html = file_get_contents($_FILES['userfile']['tmp_name']);
// Create array
$matches = parse_netscape_bookmarks($html);
//var_dump($matches);
$size = count($matches);
// Create link array
//preg_match_all('/<a\s+(.*?)\s*\/*>([^<]*)/si', $html, $matches);
preg_match_all('/<a\s+(.*?)>([^<]*?)<\/a>.*?(<dd>([^<]*)|<dt>)/si', $html, $matches);
//var_dump($matches);die();
$links = $matches[1];
$titles = $matches[2];
$descriptions = $matches[4];
$size = count($links);
for ($i = 0; $i < $size; $i++) {
$bDatetime = gmdate('Y-m-d H:i:s', $matches[$i]['time']); //bDateTime optional
$bCategories = $matches[$i]['tags']; //bCategories optional
$bAddress = $matches[$i]['uri'];
$bDescription = $matches[$i]['note'];
$bTitle = $matches[$i]['title'];
$bPrivateNote = '';
// echo "<hr/>";
// echo $links[$i]."<br/>";
preg_match_all('/(\w*\s*=\s*"[^"]*")/', $links[$i], $attributes);
//$attributes = $attributes[0]; // we keep just one row
$bDatetime = ""; //bDateTime optional
$bCategories = ""; //bCategories optional
$bPrivateNote = ""; //bPrivateNote optional
$bPrivate = $status; //bPrivate set default
foreach ($attributes[0] as $attribute) {
$att = preg_split('/\s*=\s*/s', $attribute, 2);
$attrTitle = $att[0];
$attrVal = str_replace(
'&quot;', '"',
preg_replace('/([\'"]?)(.*)\1/', '$2', $att[1])
);
switch ($attrTitle) {
case "HREF":
$bAddress = $attrVal;
break;
case "ADD_DATE":
$bDatetime = gmdate('Y-m-d H:i:s', $attrVal);
break;
case "TAGS":
$bCategories = $attrVal;
break;
case "NOTE":
$bPrivateNote = $attrVal;
break;
case "PRIVATE":
if ($attrVal) {
$bPrivate = 2;//private
}
}
}
$bTitle = trim($titles[$i]);
$bDescription = trim($descriptions[$i]);
if ($bookmarkservice->bookmarkExists($bAddress, $userservice->getCurrentUserId())) {
//$tplVars['error'] = T_('You have already submitted some of these bookmarks.');
// If the bookmark exists already, edit the original
$bookmark = $bookmarkservice->getBookmarkByAddress($bAddress);
$bId = intval($bookmark['bId']);
$row = $bookmarkservice->getBookmark($bId, true);
$categories = array_unique(array_merge($row['tags'], $bCategories));
//var_dump('update', $bId, $bAddress, $row['bTitle'], $row['bDescription'], $row['bPrivateNote'], $row['bStatus'], $categories);
if ($bookmarkservice->updateBookmark($bId, $bAddress, $row['bTitle'], $row['bDescription'], $row['bPrivateNote'], $row['bStatus'], $categories)) {
$countImportedBookmarks++;
}
else {
$tplvars['error'] = T_('Error while saving this bookmark : ' + $bAddress);
}
$tplVars['error'] = T_('You have already submitted some of these bookmarks.');
} else {
// If bookmark is local (like javascript: or place: in Firefox3), do nothing
if(substr($bAddress, 0, 7) == "http://" || substr($bAddress, 0, 8) == "https://") {
// If bookmark claims to be from the future, set it to be now instead
if (strtotime($bDatetime) > time()) {
$bDatetime = gmdate('Y-m-d H:i:s');
}
//var_dump('add ', $bAddress, $bTitle, $bDescription, $bPrivateNote, $status, $bCategories, $bDatetime);
if ($bookmarkservice->addBookmark($bAddress, $bTitle, $bDescription, $bPrivateNote, $status, $bCategories, null, $bDatetime, false, true)) {
if ($bookmarkservice->addBookmark($bAddress, $bTitle, $bDescription, $bPrivateNote, $bPrivate, $bCategories, null, $bDatetime, false, true)) {
$countImportedBookmarks++;
} else {
$tplVars['error'] = T_('There was an error saving your bookmark : ' . $bAddress . ' Please try again or contact the administrator.');
$tplVars['error'] = T_('There was an error saving your bookmark. Please try again or contact the administrator.');
}
}
}
@ -107,5 +133,4 @@ if ($userservice->isLoggedOn() && sizeof($_FILES) > 0 && $_FILES['userfile']['si
$tplVars['formaction'] = createURL('importNetscape');
$templateservice->loadTemplate($templatename, $tplVars);
}
?>

View File

@ -1,117 +0,0 @@
/*!
* jQuery Cookie Plugin v1.4.1
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2013 Klaus Hartl
* Released under the MIT license
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var pluses = /\+/g;
function encode(s) {
return config.raw ? s : encodeURIComponent(s);
}
function decode(s) {
return config.raw ? s : decodeURIComponent(s);
}
function stringifyCookieValue(value) {
return encode(config.json ? JSON.stringify(value) : String(value));
}
function parseCookieValue(s) {
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}
try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, ' '));
return config.json ? JSON.parse(s) : s;
} catch(e) {}
}
function read(s, converter) {
var value = config.raw ? s : parseCookieValue(s);
return $.isFunction(converter) ? converter(value) : value;
}
var config = $.cookie = function (key, value, options) {
// Write
if (value !== undefined && !$.isFunction(value)) {
options = $.extend({}, config.defaults, options);
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setTime(+t + days * 864e+5);
}
return (document.cookie = [
encode(key), '=', stringifyCookieValue(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// Read
var result = key ? undefined : {};
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling $.cookie().
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0, l = cookies.length; i < l; i++) {
var parts = cookies[i].split('=');
var name = decode(parts.shift());
var cookie = parts.join('=');
if (key && key === name) {
// If second argument (value) is a function it's a converter...
result = read(cookie, value);
break;
}
// Prevent storing a cookie that we couldn't decode.
if (!key && (cookie = read(cookie)) !== undefined) {
result[name] = cookie;
}
}
return result;
};
config.defaults = {};
$.removeCookie = function (key, options) {
if ($.cookie(key) === undefined) {
return false;
}
// Must not alter options, thus extending a fresh object...
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
return !$.cookie(key);
};
}));

View File

@ -35,20 +35,50 @@ isset($_POST['query']) ? define('POST_QUERY', $_POST['query']): define('POST_QUE
$keeppass = (POST_KEEPPASS=='yes')?true:false;
@list($url, $method) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
$login = false;
if (POST_SUBMITTED!='' && POST_USERNAME!='' && POST_PASSWORD!='') {
if ($method == 'openidreturn'
|| (POST_SUBMITTED != ''
&& isset($_POST['openid_identifier']) && $_POST['openid_identifier'] != ''
)
) {
$oids = SemanticScuttle_Service_Factory::get('OpenId');
$returnUrl = addProtocolToUrl(createURL('login', 'openidreturn'));
try {
if ($method == 'openidreturn') {
//part 2: handle response
$ret = $oids->handleIdResponse($returnUrl);
if ($ret['userId'] === null) {
//FIXME: ask to register
$tplVars['error'] = T_('OpenID login error');
} else {
$userservice->setCurrentUserId($ret['userId'], true);
$login = true;
}
//FIXME POST_KEEPPASS
} else {
//part 1: send request
$oids->sendIdRequest($_POST['openid_identifier'], $returnUrl);
}
} catch (Exception $e) {
$tplVars['error'] = SemanticScuttle_Exception::getErrorMessage($e);
}
} else if (POST_SUBMITTED!='' && POST_USERNAME!='' && POST_PASSWORD!='') {
$posteduser = trim(utf8_strtolower(POST_USERNAME));
$login = $userservice->login($posteduser, POST_PASSWORD, $keeppass);
if ($login) {
if (POST_QUERY)
header('Location: '. createURL('bookmarks', $posteduser .'?'. POST_QUERY));
else
header('Location: '. createURL('bookmarks', $posteduser));
} else {
if (!$login) {
$tplVars['error'] = T_('The details you have entered are incorrect. Please try again.');
}
}
if (!$login) {
if ($login) {
if (POST_QUERY)
header('Location: '. createURL('bookmarks', $posteduser .'?'. POST_QUERY));
else
header('Location: '. createURL('bookmarks', $posteduser));
} else {
if ($userservice->isLoggedOn()) {
$cUser = $userservice->getCurrentObjectUser();
header('Location: '. createURL('bookmarks', strtolower($cUser->getUsername())));

View File

@ -42,27 +42,27 @@ isset($_SESSION['token']) ? define('SESSION_TOKEN', $_SESSION['token']): define(
isset($_SESSION['token_stamp']) ? define('SESSION_TOKENSTAMP', $_SESSION['token_stamp']): define('SESSION_TOKENSTAMP', '');
@list($url, $user) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
@list($url, $user, $method) = isset($_SERVER['PATH_INFO'])
? explode('/', $_SERVER['PATH_INFO']) : NULL;
if ($user) {
if (is_int($user)) {
$userid = intval($user);
} else {
$user = urldecode($user);
$userinfo = $userservice->getObjectUserByUsername($user);
if ($userinfo == NULL) {
$tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
$templateservice->loadTemplate('error.404.tpl', $tplVars);
exit();
} else {
$userid = $userinfo->getId();
}
}
if (!$user) {
$tplVars['error'] = T_('Username was not specified');
$templateservice->loadTemplate('error.404.tpl', $tplVars);
exit();
}
if (is_int($user)) {
$userid = intval($user);
} else {
$tplVars['error'] = T_('Username was not specified');
$templateservice->loadTemplate('error.404.tpl', $tplVars);
exit();
$user = urldecode($user);
$userinfo = $userservice->getObjectUserByUsername($user);
if ($userinfo == NULL) {
$tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
$templateservice->loadTemplate('error.404.tpl', $tplVars);
exit();
} else {
$userid = $userinfo->getId();
}
}
$tplVars['privateKeyIsEnabled'] = '';
@ -92,54 +92,54 @@ if (POST_SUBMITTEDPK!='' && $currentUser->getId() == $userid) {
}
if (POST_SUBMITTED!='' && $currentUser->getId() == $userid) {
$error = false;
$detPass = trim(POST_PASS);
$detPassConf = trim(POST_PASSCONF);
$detName = trim(POST_NAME);
$detPrivateKey = trim(POST_PRIVATEKEY);
$detEnablePrivateKey = trim(POST_ENABLEPRIVATEKEY);
$detMail = trim(POST_MAIL);
$detPage = trim(POST_PAGE);
$detDesc = filter(POST_DESC);
$error = false;
$detPass = trim(POST_PASS);
$detPassConf = trim(POST_PASSCONF);
$detName = trim(POST_NAME);
$detPrivateKey = trim(POST_PRIVATEKEY);
$detEnablePrivateKey = trim(POST_ENABLEPRIVATEKEY);
$detMail = trim(POST_MAIL);
$detPage = trim(POST_PAGE);
$detDesc = filter(POST_DESC);
// manage token preventing from CSRF vulnaribilities
if ( SESSION_TOKEN == ''
|| time() - SESSION_TOKENSTAMP > 600 //limit token lifetime, optionnal
|| SESSION_TOKEN != POST_TOKEN) {
$error = true;
$tplVars['error'] = T_('Invalid Token');
}
// manage token preventing from CSRF vulnaribilities
if ( SESSION_TOKEN == ''
|| time() - SESSION_TOKENSTAMP > 600 //limit token lifetime, optionnal
|| SESSION_TOKEN != POST_TOKEN) {
$error = true;
$tplVars['error'] = T_('Invalid Token');
}
if ($detPass != $detPassConf) {
$error = true;
$tplVars['error'] = T_('Password and confirmation do not match.');
}
if ($detPass != "" && strlen($detPass) < 6) {
$error = true;
$tplVars['error'] = T_('Password must be at least 6 characters long.');
}
if (!$userservice->isValidEmail($detMail)) {
$error = true;
$tplVars['error'] = T_('E-mail address is not valid.');
}
if (!$error) {
if (!$userservice->updateUser($userid, $detPass, $detName, $detMail, $detPage, $detDesc, $detPrivateKey, $detEnablePrivateKey)) {
$tplVars['error'] = T_('An error occurred while saving your changes.');
} else {
$tplVars['msg'] = T_('Changes saved.');
}
}
$userinfo = $userservice->getObjectUserByUsername($user);
$tplVars['privateKey'] = $userinfo->getPrivateKey(true);
if ($userservice->isPrivateKeyValid($userinfo->getPrivateKey())) {
$tplVars['privateKeyIsEnabled'] = 'checked="checked"';
} else {
$tplVars['privateKeyIsEnabled'] = '';
}
if ($detPass != $detPassConf) {
$error = true;
$tplVars['error'] = T_('Password and confirmation do not match.');
}
if ($detPass != "" && strlen($detPass) < 6) {
$error = true;
$tplVars['error'] = T_('Password must be at least 6 characters long.');
}
if (!$userservice->isValidEmail($detMail)) {
$error = true;
$tplVars['error'] = T_('E-mail address is not valid.');
}
if (!$error) {
if (!$userservice->updateUser($userid, $detPass, $detName, $detMail, $detPage, $detDesc, $detPrivateKey, $detEnablePrivateKey)) {
$tplVars['error'] = T_('An error occurred while saving your changes.');
} else {
$tplVars['msg'] = T_('Changes saved.');
}
}
$userinfo = $userservice->getObjectUserByUsername($user);
$tplVars['privateKey'] = $userinfo->getPrivateKey(true);
if ($userservice->isPrivateKeyValid($userinfo->getPrivateKey())) {
$tplVars['privateKeyIsEnabled'] = 'checked="checked"';
} else {
$tplVars['privateKeyIsEnabled'] = '';
}
}
if (!$userservice->isLoggedOn() || $currentUser->getId() != $userid) {
$templatename = 'profile.tpl.php';
$templatename = 'profile.tpl.php';
} else {
$scert = SemanticScuttle_Service_Factory::get('User_SslClientCert');
@ -170,17 +170,65 @@ if (!$userservice->isLoggedOn() || $currentUser->getId() != $userid) {
}
}
//Token Init
$_SESSION['token'] = md5(uniqid(rand(), true));
$_SESSION['token_stamp'] = time();
$oids = SemanticScuttle_Service_Factory::get('OpenId');
if (isset($_POST['action']) && $_POST['action'] == 'deleteOpenId'
&& isset($_POST['openIdUrl'])
) {
$identifier = $_POST['openIdUrl'];
$openId = $oids->getId($identifier);
if ($openId === null || $openId->uId != $currentUser->getId()
) {
$tplVars['error'] = T_('OpenID not found.');
} else if (false === $oids->delete($openId->id)) {
$tplVars['error'] = T_('Failed to delete OpenID.');
} else {
$tplVars['msg'] = T_('OpenID deleted.');
}
}
$templatename = 'editprofile.tpl.php';
$openIdAction = false;
$openIdReturn = false;
if (isset($_POST['action']) && $_POST['action'] == 'registerOpenId'
&& isset($_POST['openid_identifier'])
) {
$openIdAction = true;
} else if (isset($method) && $method == 'openidreturn') {
$openIdAction = true;
$openIdReturn = true;
}
if ($openIdAction) {
$returnUrl = addProtocolToUrl(createURL('profile', $user . '/openidreturn'));
$tplVars['formaction'] = createURL('profile', $user);
$tplVars['token'] = $_SESSION['token'];
try {
if (!$openIdReturn) {
//part 1 of OpenID registration
$oids->sendIdRequest($_POST['openid_identifier'], $returnUrl);
} else {
//part 2
$ret = $oids->handleIdResponse($returnUrl);
$oids->register(
$currentUser->getId(), $ret['identifier'], $ret['email']
);
$tplVars['msg'] = T_('OpenID registered.');
}
} catch (Exception $e) {
$tplVars['error'] = SemanticScuttle_Exception::getErrorMessage($e);
}
}
$tplVars['sslClientCerts'] = $scert->getUserCerts($currentUser->getId());
$tplVars['currentCert'] = null;
//Token Init
$_SESSION['token'] = md5(uniqid(rand(), true));
$_SESSION['token_stamp'] = time();
$templatename = 'editprofile.tpl.php';
$tplVars['formaction'] = createURL('profile', $user);
$tplVars['token'] = $_SESSION['token'];
$tplVars['sslClientCerts'] = $scert->getUserCerts($currentUser->getId());
$tplVars['openIds'] = $oids->getIds($currentUser->getId());
$tplVars['currentCert'] = null;
if ($scert->hasValidCert()) {
$tplVars['currentCert'] = SemanticScuttle_Model_User_SslClientCert::fromCurrentCert();
}

View File

@ -26,7 +26,7 @@ isset($_POST['terms']) ? define('POST_TERMS', $_POST['terms']): define('POST_TER
isset($_POST['range']) ? define('POST_RANGE', $_POST['range']): define('POST_RANGE', '');
isset($_GET['page']) ? define('GET_PAGE', $_GET['page']): define('GET_PAGE', 0);
isset($_GET['sort']) ? define('GET_SORT', $_GET['sort']): define('GET_SORT', '');
isset($_GET['batch']) ? define('GET_BATCH', $_GET['batch']): define('GET_BATCH', 0);
// POST
if (POST_TERMS != '') {
@ -115,41 +115,6 @@ if (is_null($terms)) {
}
}
if ($userservice->isLoggedOn() && GET_BATCH) {
$currentUsername = $currentUser->getUsername();
$completebookmarks = $bookmarkservice->getBookmarks(0, null, $s_user, null, $terms, getSortOrder(),
$s_watchlist, $s_start, $s_end);
$templatename = 'editbookmark.tpl';
$addresses2 = array();
$titles2 = array();
$tags2 = array();
foreach ($completebookmarks['bookmarks'] as $key => &$row) {
$addresses2[$row['bId']] = $row['bAddress'];
$titles2[$row['bId']] = $row['bTitle'];
$row = $bookmarkservice->getBookmark($row['bId'], true);
$tags2[] = $row['tags'];
}
$alltags2 = array_unique(call_user_func_array('array_merge', $tags2));
$commontags2 = call_user_func_array('array_intersect', $tags2);
$tplVars['row'] = array(
'bTitle' => $titles2,
'bAddress' => $addresses2,
'bDescription' => '',
'bPrivateNote' => '',
'tags' => array(),
'bStatus' => $GLOBALS['defaults']['privacy']
);
$tplVars['pagetitle'] = T_('Add a Bookmark');
$tplVars['subtitle'] = T_('Add a Bookmark');
$tplVars['btnsubmit'] = T_('Add Bookmark');
$tplVars['popup'] = null;
$tplVars['batch'] = '1';
$tplVars['alltags'] = implode(', ', $alltags2);
$tplVars['commontags'] = implode(', ', $commontags2);
$tplVars['formaction'] = createURL('bookmarks', $currentUsername);
$templateservice->loadTemplate($templatename, $tplVars);
}
else {
$bookmarks = $bookmarkservice->getBookmarks(
$start, $perpage, $s_user, NULL, $terms, getSortOrder(),
$s_watchlist, $s_start, $s_end
@ -187,5 +152,4 @@ $tplVars['cat_url'] = createURL('tags', '%2$s');
$tplVars['nav_url'] = createURL('search', $range .'/'. $terms .'/%3$s');
$templateservice->loadTemplate('bookmarks.tpl', $tplVars);
}
?>

View File

@ -63,7 +63,7 @@ if (POST_CONFIRM != '') {
}
$tplVars['links'] = $tag2tagservice->getLinks($currentUser->getId());
$tplVars['loadjs'] = true;
$tplVars['tag1'] = $tag1;
$tplVars['tag2'] = '';
$tplVars['subtitle'] = T_('Add Tag Link') .': '. $tag1;

View File

@ -75,7 +75,7 @@ if (POST_CONFIRM) {
}
$tplVars['links'] = $tag2tagservice->getLinks($currentUser->getId());
$tplVars['loadjs'] = true;
$tplVars['tag1'] = $tag1;
$tplVars['tag2'] = $tag2;
$tplVars['subtitle'] = T_('Delete Link Between Tags') .': '. $tag1.' > '.$tag2;

View File

@ -73,7 +73,6 @@ if (POST_CONFIRM) {
$tplVars['formaction'] = $_SERVER['SCRIPT_NAME'] .'/'. $tag;
$tplVars['referrer'] = $_SERVER['HTTP_REFERER'];
$tplVars['old'] = $tag;
$tplVars['loadjs'] = true;
}
$templateservice->loadTemplate($template, $tplVars);
?>

View File

@ -20,6 +20,7 @@
***************************************************************************/
require_once 'www-header.php';
/* Service creation: only useful services are created */
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
$cacheservice =SemanticScuttle_Service_Factory::get('Cache');
@ -27,7 +28,6 @@ $cacheservice =SemanticScuttle_Service_Factory::get('Cache');
/* Managing all possible inputs */
isset($_GET['page']) ? define('GET_PAGE', $_GET['page']): define('GET_PAGE', 0);
isset($_GET['sort']) ? define('GET_SORT', $_GET['sort']): define('GET_SORT', '');
isset($_GET['batch']) ? define('GET_BATCH', $_GET['batch']): define('GET_BATCH', 0);
/* Managing current logged user */
$currentUser = $userservice->getCurrentObjectUser();
@ -63,43 +63,6 @@ if ($usecache) {
$cacheservice->Start($hash, 1800);
}
// We need all bookmarks (without paging) for batch tagging.
if ($userservice->isLoggedOn() && GET_BATCH) {
$currentUsername = $currentUser->getUsername();
$completebookmarks = $bookmarkservice->getBookmarks(0, null, null, $cat, null, getSortOrder());
$templatename = 'editbookmark.tpl';
$addresses2 = array();
$titles2 = array();
$tags2 = array();
foreach ($completebookmarks['bookmarks'] as $key => &$row) {
$addresses2[$row['bId']] = $row['bAddress'];
$titles2[$row['bId']] = $row['bTitle'];
$row = $bookmarkservice->getBookmark($row['bId'], true);
$tags2[] = $row['tags'];
}
$alltags2 = array_unique(call_user_func_array('array_merge', $tags2));
$commontags2 = call_user_func_array('array_intersect', $tags2);
$tplVars['row'] = array(
'bTitle' => $titles2,
'bAddress' => $addresses2,
'bDescription' => '',
'bPrivateNote' => '',
'tags' => array(),
'bStatus' => $GLOBALS['defaults']['privacy']
);
$tplVars['pagetitle'] = T_('Add a Bookmark');
$tplVars['subtitle'] = T_('Add a Bookmark');
$tplVars['btnsubmit'] = T_('Add Bookmark');
$tplVars['popup'] = null;
$tplVars['batch'] = '1';
$tplVars['alltags'] = implode(', ', $alltags2);
$tplVars['commontags'] = implode(', ', $commontags2);
$tplVars['formaction'] = createURL('bookmarks', $currentUsername);
$tplVars['loadjs'] = true;
$templateservice->loadTemplate($templatename, $tplVars);
}
else {
// Header variables
$tplVars['pagetitle'] = T_('Tags') .': '. $cat;
$tplVars['loadjs'] = true;
@ -143,38 +106,7 @@ $tplVars['page'] = $page;
$tplVars['start'] = $start;
$tplVars['popCount'] = 25;
$tplVars['currenttag'] = $cat;
if ($userservice->isLoggedOn() && ! empty($GLOBALS['shoulderSurfingProtectedTag']) && ! isset($_COOKIE["noshoulderSurfingProtection"])) {
$tag2tagservice = SemanticScuttle_Service_Factory::get('Tag2Tag');
$b2tservice = SemanticScuttle_Service_Factory::get('Bookmark2Tag');
$currentUserID = $currentUser->getId();
$alltags = $b2tservice->getTags($currentUserID);
$shoulderSurfingProtectedTags = $tag2tagservice->getAllLinkedTags($GLOBALS['shoulderSurfingProtectedTag'], '>', $currentUserID, array());
$shoulderSurfingProtectedTags[] = $GLOBALS['shoulderSurfingProtectedTag'];
$flag = 0;
if (! in_array($cat, $shoulderSurfingProtectedTags, true)) {
foreach ($alltags as $tag) {
if ($tag['tag'] === $cat) {
$flag = 1;
break;
}
}
}
if ($flag) {
$tplVars['sidebar_blocks'][] = 'tagactions';
$tplVars['sidebar_blocks'][] = 'linked';
$tplVars['sidebar_blocks'][] = 'related';
$tplVars['sidebar_blocks'][] = 'menu2';
}
}
else {
$tplVars['sidebar_blocks'][] = 'tagactions';
$tplVars['sidebar_blocks'][] = 'linked';
$tplVars['sidebar_blocks'][] = 'related';
$tplVars['sidebar_blocks'][] = 'menu2';
}
$tplVars['sidebar_blocks'] = array('linked', 'related', 'menu2');//array('linked', 'related', 'popular');
$tplVars['subtitlehtml'] = $pagetitle;
$tplVars['bookmarkCount'] = $start + 1;
$bookmarks = $bookmarkservice->getBookmarks($start, $perpage, NULL, $cat, NULL, getSortOrder());
@ -184,7 +116,7 @@ $tplVars['cat_url'] = createURL('bookmarks', '%1$s/%2$s');
$tplVars['nav_url'] = createURL('tags', '%2$s%3$s');
$templateservice->loadTemplate('bookmarks.tpl', $tplVars);
}
if ($usecache) {
// Cache output if existing copy has expired
$cacheservice->End($hash);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -110,8 +110,7 @@ html > body h1 {
padding-left: 75px;
}
html > body div#header.popup h1 {
background: url('images/logo.png') no-repeat 10px;
background-size: 24px;
background: url('images/logo_24.gif') no-repeat 10px;
padding: 0.5em 0.5em 0.5em 50px;
}
/*html > body div#header #welcome {
@ -196,6 +195,7 @@ img.thumbnail {
padding: 1px;
margin-right: 6px;
margin-bottom:4px;
cursor:pointer;
border:1px solid #AAA;
}
div.link a {