Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
GNU Social Debian Packaging
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
4
Issues
4
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Bhuvan Krishna
GNU Social Debian Packaging
Commits
0703410b
Commit
0703410b
authored
Jul 04, 2017
by
Bhuvan Krishna
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'upstream' into dfsg
parents
59636169
5ad2f287
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
493 additions
and
98 deletions
+493
-98
classes/Notice.php
classes/Notice.php
+64
-2
classes/Notice_prefs.php
classes/Notice_prefs.php
+172
-0
db/core.php
db/core.php
+1
-0
lib/activity.php
lib/activity.php
+1
-1
lib/activityhandlerplugin.php
lib/activityhandlerplugin.php
+3
-0
lib/activityobject.php
lib/activityobject.php
+14
-0
lib/activityutils.php
lib/activityutils.php
+9
-3
lib/apiaction.php
lib/apiaction.php
+2
-1
lib/framework.php
lib/framework.php
+11
-0
lib/util.php
lib/util.php
+4
-0
plugins/Blacklist/BlacklistPlugin.php
plugins/Blacklist/BlacklistPlugin.php
+9
-0
plugins/LRDD/lib/discovery.php
plugins/LRDD/lib/discovery.php
+9
-0
plugins/LRDD/lib/lrddmethod.php
plugins/LRDD/lib/lrddmethod.php
+3
-0
plugins/OStatus/OStatusPlugin.php
plugins/OStatus/OStatusPlugin.php
+91
-62
plugins/OStatus/actions/ostatussub.php
plugins/OStatus/actions/ostatussub.php
+8
-3
plugins/OStatus/actions/pushhub.php
plugins/OStatus/actions/pushhub.php
+5
-4
plugins/OStatus/classes/Ostatus_profile.php
plugins/OStatus/classes/Ostatus_profile.php
+7
-3
plugins/OpenID/actions/openidsettings.php
plugins/OpenID/actions/openidsettings.php
+1
-1
plugins/OpenID/openid.php
plugins/OpenID/openid.php
+1
-0
plugins/StoreRemoteMedia/StoreRemoteMediaPlugin.php
plugins/StoreRemoteMedia/StoreRemoteMediaPlugin.php
+69
-14
plugins/TwitterBridge/twitter.php
plugins/TwitterBridge/twitter.php
+9
-4
No files found.
classes/Notice.php
View file @
0703410b
...
...
@@ -313,6 +313,21 @@ class Notice extends Managed_DataObject
}
}
public
function
getSelfLink
()
{
if
(
$this
->
isLocal
())
{
return
common_local_url
(
'ApiStatusesShow'
,
array
(
'id'
=>
$this
->
getID
(),
'format'
=>
'atom'
));
}
$selfLink
=
$this
->
getPref
(
'ostatus'
,
'self'
);
if
(
!
common_valid_http_url
(
$selfLink
))
{
throw
new
InvalidUrlException
(
$selfLink
);
}
return
$selfLink
;
}
public
function
getObjectType
(
$canonical
=
false
)
{
if
(
is_null
(
$this
->
object_type
)
||
$this
->
object_type
===
''
)
{
throw
new
NoObjectTypeException
(
$this
);
...
...
@@ -445,6 +460,7 @@ class Notice extends Managed_DataObject
static
function
saveNew
(
$profile_id
,
$content
,
$source
,
array
$options
=
null
)
{
$defaults
=
array
(
'uri'
=>
null
,
'url'
=>
null
,
'self'
=>
null
,
'conversation'
=>
null
,
// URI of conversation
'reply_to'
=>
null
,
// This will override convo URI if the parent is known
'repeat_of'
=>
null
,
// This will override convo URI if the repeated notice is known
...
...
@@ -717,6 +733,10 @@ class Notice extends Managed_DataObject
}
}
if
(
$self
&&
common_valid_http_url
(
$self
))
{
$notice
->
setPref
(
'ostatus'
,
'self'
,
$self
);
}
// Only save 'attention' and metadata stuff (URLs, tags...) stuff if
// the activityverb is a POST (since stuff like repeat, favorite etc.
// reasonably handle notifications themselves.
...
...
@@ -776,6 +796,9 @@ class Notice extends Managed_DataObject
// implied object
$options
[
'uri'
]
=
$act
->
id
;
$options
[
'url'
]
=
$act
->
link
;
if
(
$act
->
selfLink
)
{
$options
[
'self'
]
=
$act
->
selfLink
;
}
}
else
{
$actobj
=
count
(
$act
->
objects
)
===
1
?
$act
->
objects
[
0
]
:
null
;
if
(
!
is_null
(
$actobj
)
&&
!
empty
(
$actobj
->
id
))
{
...
...
@@ -786,6 +809,9 @@ class Notice extends Managed_DataObject
$options
[
'url'
]
=
$actobj
->
id
;
}
}
if
(
$actobj
->
selfLink
)
{
$options
[
'self'
]
=
$actobj
->
selfLink
;
}
}
$defaults
=
array
(
...
...
@@ -795,6 +821,7 @@ class Notice extends Managed_DataObject
'reply_to'
=>
null
,
'repeat_of'
=>
null
,
'scope'
=>
null
,
'self'
=>
null
,
'source'
=>
'unknown'
,
'tags'
=>
array
(),
'uri'
=>
null
,
...
...
@@ -999,6 +1026,10 @@ class Notice extends Managed_DataObject
throw
new
ServerException
(
'StartNoticeSave did not give back a Notice'
);
}
if
(
$self
&&
common_valid_http_url
(
$self
))
{
$stored
->
setPref
(
'ostatus'
,
'self'
,
$self
);
}
// Only save 'attention' and metadata stuff (URLs, tags...) stuff if
// the activityverb is a POST (since stuff like repeat, favorite etc.
// reasonably handle notifications themselves.
...
...
@@ -2048,9 +2079,12 @@ class Notice extends Managed_DataObject
}
}
try
{
$act
->
selfLink
=
$this
->
getSelfLink
();
}
catch
(
InvalidUrlException
$e
)
{
$act
->
selfLink
=
null
;
}
if
(
$this
->
isLocal
())
{
$act
->
selfLink
=
common_local_url
(
'ApiStatusesShow'
,
array
(
'id'
=>
$this
->
id
,
'format'
=>
'atom'
));
$act
->
editLink
=
$act
->
selfLink
;
}
...
...
@@ -2148,6 +2182,11 @@ class Notice extends Managed_DataObject
$object
->
title
=
sprintf
(
'New %1$s by %2$s'
,
ActivityObject
::
canonicalType
(
$object
->
type
),
$this
->
getProfile
()
->
getNickname
());
$object
->
content
=
$this
->
getRendered
();
$object
->
link
=
$this
->
getUrl
();
try
{
$object
->
selfLink
=
$this
->
getSelfLink
();
}
catch
(
InvalidUrlException
$e
)
{
$object
->
selfLink
=
null
;
}
$object
->
extra
[]
=
array
(
'status_net'
,
array
(
'notice_id'
=>
$this
->
id
));
...
...
@@ -3082,4 +3121,27 @@ class Notice extends Managed_DataObject
}
print
"
\n
"
;
}
public
function
delPref
(
$namespace
,
$topic
)
{
return
Notice_prefs
::
setData
(
$this
,
$namespace
,
$topic
,
null
);
}
public
function
getPref
(
$namespace
,
$topic
,
$default
=
null
)
{
// If you want an exception to be thrown, call Notice_prefs::getData directly
try
{
return
Notice_prefs
::
getData
(
$this
,
$namespace
,
$topic
,
$default
);
}
catch
(
NoResultException
$e
)
{
return
null
;
}
}
// The same as getPref but will fall back to common_config value for the same namespace/topic
public
function
getConfigPref
(
$namespace
,
$topic
)
{
return
Notice_prefs
::
getConfigData
(
$this
,
$namespace
,
$topic
);
}
public
function
setPref
(
$namespace
,
$topic
,
$data
)
{
return
Notice_prefs
::
setData
(
$this
,
$namespace
,
$topic
,
$data
);
}
}
classes/Notice_prefs.php
0 → 100644
View file @
0703410b
<?php
/**
* GNU social
*
* Data class for Notice preferences
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Data
* @package GNUsocial
* @author Mikael Nordfeldth <mmn@hethane.se>
* @copyright 2013 Free Software Foundation, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class
Notice_prefs
extends
Managed_DataObject
{
public
$__table
=
'notice_prefs'
;
// table name
public
$notice_id
;
// int(4) primary_key not_null
public
$namespace
;
// varchar(191) not_null
public
$topic
;
// varchar(191) not_null
public
$data
;
// text
public
$created
;
// datetime not_null default_0000-00-00%2000%3A00%3A00
public
$modified
;
// timestamp not_null default_CURRENT_TIMESTAMP
public
static
function
schemaDef
()
{
return
array
(
'fields'
=>
array
(
'notice_id'
=>
array
(
'type'
=>
'int'
,
'not null'
=>
true
,
'description'
=>
'user'
),
'namespace'
=>
array
(
'type'
=>
'varchar'
,
'length'
=>
191
,
'not null'
=>
true
,
'description'
=>
'namespace, like pluginname or category'
),
'topic'
=>
array
(
'type'
=>
'varchar'
,
'length'
=>
191
,
'not null'
=>
true
,
'description'
=>
'preference key, i.e. description, age...'
),
'data'
=>
array
(
'type'
=>
'blob'
,
'description'
=>
'topic data, may be anything'
),
'created'
=>
array
(
'type'
=>
'datetime'
,
'not null'
=>
true
,
'description'
=>
'date this record was created'
),
'modified'
=>
array
(
'type'
=>
'timestamp'
,
'not null'
=>
true
,
'description'
=>
'date this record was modified'
),
),
'primary key'
=>
array
(
'notice_id'
,
'namespace'
,
'topic'
),
'foreign keys'
=>
array
(
'notice_prefs_notice_id_fkey'
=>
array
(
'notice'
,
array
(
'notice_id'
=>
'id'
)),
),
'indexes'
=>
array
(
'notice_prefs_notice_id_idx'
=>
array
(
'notice_id'
),
),
);
}
static
function
getNamespacePrefs
(
Notice
$notice
,
$namespace
,
array
$topic
=
array
())
{
if
(
empty
(
$topic
))
{
$prefs
=
new
Notice_prefs
();
$prefs
->
notice_id
=
$notice
->
getID
();
$prefs
->
namespace
=
$namespace
;
$prefs
->
find
();
}
else
{
$prefs
=
self
::
pivotGet
(
'notice_id'
,
$notice
->
getID
(),
array
(
'namespace'
=>
$namespace
,
'topic'
=>
$topic
));
}
if
(
empty
(
$prefs
->
N
))
{
throw
new
NoResultException
(
$prefs
);
}
return
$prefs
;
}
static
function
getNamespace
(
Notice
$notice
,
$namespace
,
array
$topic
=
array
())
{
$prefs
=
self
::
getNamespacePrefs
(
$notice
,
$namespace
,
$topic
);
return
$prefs
->
fetchAll
();
}
static
function
getAll
(
Notice
$notice
)
{
try
{
$prefs
=
self
::
listFind
(
'notice_id'
,
array
(
$notice
->
getID
()));
}
catch
(
NoResultException
$e
)
{
return
array
();
}
$list
=
array
();
while
(
$prefs
->
fetch
())
{
if
(
!
isset
(
$list
[
$prefs
->
namespace
]))
{
$list
[
$prefs
->
namespace
]
=
array
();
}
$list
[
$prefs
->
namespace
][
$prefs
->
topic
]
=
$prefs
->
data
;
}
return
$list
;
}
static
function
getTopic
(
Notice
$notice
,
$namespace
,
$topic
)
{
return
self
::
getByPK
(
array
(
'notice_id'
=>
$notice
->
getID
(),
'namespace'
=>
$namespace
,
'topic'
=>
$topic
));
}
static
function
getData
(
Notice
$notice
,
$namespace
,
$topic
,
$def
=
null
)
{
try
{
$pref
=
self
::
getTopic
(
$notice
,
$namespace
,
$topic
);
}
catch
(
NoResultException
$e
)
{
if
(
$def
===
null
)
{
// If no default value was set, continue the exception.
throw
$e
;
}
// If there was a default value, return that.
return
$def
;
}
return
$pref
->
data
;
}
static
function
getConfigData
(
Notice
$notice
,
$namespace
,
$topic
)
{
try
{
$data
=
self
::
getData
(
$notice
,
$namespace
,
$topic
);
}
catch
(
NoResultException
$e
)
{
$data
=
common_config
(
$namespace
,
$topic
);
}
return
$data
;
}
/*
* Sets a notice preference based on Notice, namespace and topic
*
* @param Notice $notice Which notice this is for
* @param string $namespace Under which namespace (pluginname etc.)
* @param string $topic Preference name (think key in key-val store)
* @param string $data Data to be put into preference storage, null means delete
*
* @return true if changes are made, false if no action taken
* @throws ServerException if preference could not be saved
*/
static
function
setData
(
Notice
$notice
,
$namespace
,
$topic
,
$data
=
null
)
{
try
{
$pref
=
self
::
getTopic
(
$notice
,
$namespace
,
$topic
);
if
(
is_null
(
$data
))
{
$pref
->
delete
();
}
else
{
$orig
=
clone
(
$pref
);
$pref
->
data
=
$data
;
$pref
->
update
(
$orig
);
}
return
true
;
}
catch
(
NoResultException
$e
)
{
if
(
is_null
(
$data
))
{
return
false
;
// No action taken
}
}
$pref
=
new
Notice_prefs
();
$pref
->
notice_id
=
$notice
->
getID
();
$pref
->
namespace
=
$namespace
;
$pref
->
topic
=
$topic
;
$pref
->
data
=
$data
;
$pref
->
created
=
common_sql_now
();
if
(
$pref
->
insert
()
===
false
)
{
throw
new
ServerException
(
'Could not save notice preference.'
);
}
return
true
;
}
}
db/core.php
View file @
0703410b
...
...
@@ -41,6 +41,7 @@ $classes = array('Schema_version',
'Notice'
,
'Notice_location'
,
'Notice_source'
,
'Notice_prefs'
,
'Reply'
,
'Consumer'
,
'Token'
,
...
...
lib/activity.php
View file @
0703410b
...
...
@@ -267,7 +267,7 @@ class Activity
// From APP. Might be useful.
$this
->
selfLink
=
ActivityUtils
::
get
Link
(
$entry
,
'self'
,
'application/atom+xml'
);
$this
->
selfLink
=
ActivityUtils
::
get
SelfLink
(
$entry
);
$this
->
editLink
=
ActivityUtils
::
getLink
(
$entry
,
'edit'
,
'application/atom+xml'
);
}
...
...
lib/activityhandlerplugin.php
View file @
0703410b
...
...
@@ -340,6 +340,7 @@ abstract class ActivityHandlerPlugin extends Plugin
$options
=
array
(
'uri'
=>
$object
->
id
,
'url'
=>
$object
->
link
,
'self'
=>
$object
->
selfLink
,
'is_local'
=>
Notice
::
REMOTE
,
'source'
=>
'ostatus'
);
...
...
@@ -416,6 +417,7 @@ abstract class ActivityHandlerPlugin extends Plugin
$options
=
array
(
'uri'
=>
$object
->
id
,
'url'
=>
$object
->
link
,
'self'
=>
$object
->
selfLink
,
'is_local'
=>
Notice
::
REMOTE
,
'source'
=>
'ostatus'
);
...
...
@@ -467,6 +469,7 @@ abstract class ActivityHandlerPlugin extends Plugin
$options
=
array
(
'uri'
=>
$object
->
id
,
'url'
=>
$object
->
link
,
'self'
=>
$object
->
selfLink
,
'source'
=>
'restore'
);
// $user->getProfile() is a Profile
...
...
lib/activityobject.php
View file @
0703410b
...
...
@@ -102,6 +102,7 @@ class ActivityObject
public
$content
;
public
$owner
;
public
$link
;
public
$selfLink
;
// think APP (Atom Publishing Protocol)
public
$source
;
public
$avatarLinks
=
array
();
public
$geopoint
;
...
...
@@ -263,6 +264,7 @@ class ActivityObject
$this
->
source
=
$this
->
_getSource
(
$element
);
$this
->
link
=
ActivityUtils
::
getPermalink
(
$element
);
$this
->
selfLink
=
ActivityUtils
::
getSelfLink
(
$element
);
$this
->
id
=
$this
->
_childContent
(
$element
,
self
::
ID
);
...
...
@@ -651,6 +653,18 @@ class ActivityObject
);
}
if
(
!
empty
(
$this
->
selfLink
))
{
$xo
->
element
(
'link'
,
array
(
'rel'
=>
'self'
,
'type'
=>
'application/atom+xml'
,
'href'
=>
$this
->
selfLink
),
null
);
}
if
(
!
empty
(
$this
->
owner
))
{
$owner
=
$this
->
owner
->
asActivityNoun
(
self
::
AUTHOR
);
$xo
->
raw
(
$owner
);
...
...
lib/activityutils.php
View file @
0703410b
...
...
@@ -65,11 +65,16 @@ class ActivityUtils
*
* @return string related link, if any
*/
static
function
getPermalink
(
$element
)
static
function
getPermalink
(
DOMNode
$element
)
{
return
self
::
getLink
(
$element
,
'alternate'
,
'text/html'
);
}
static
function
getSelfLink
(
DOMNode
$element
)
{
return
self
::
getLink
(
$element
,
'self'
,
'application/atom+xml'
);
}
/**
* Get the permalink for an Activity object
*
...
...
@@ -90,8 +95,9 @@ class ActivityUtils
$linkRel
=
$link
->
getAttribute
(
self
::
REL
);
$linkType
=
$link
->
getAttribute
(
self
::
TYPE
);
// XXX: Am I allowed to do this according to specs? (matching using common_bare_mime)
if
(
$linkRel
==
$rel
&&
(
is_null
(
$type
)
||
$linkType
==
$type
))
{
(
is_null
(
$type
)
||
common_bare_mime
(
$linkType
)
==
common_bare_mime
(
$type
)
))
{
return
$link
->
getAttribute
(
self
::
HREF
);
}
}
...
...
@@ -294,7 +300,7 @@ class ActivityUtils
// Possibly an upstream bug; tag: URIs aren't validated properly
// unless you explicitly ask for them. All other schemes are accepted
// for basic URI validation without asking.
if
(
$validate
->
uri
(
$uri
,
array
(
'allowed_scheme'
=>
array
(
'tag'
))))
{
if
(
$validate
->
uri
(
$uri
,
array
(
'allowed_scheme
s
'
=>
array
(
'tag'
))))
{
return
true
;
}
...
...
lib/apiaction.php
View file @
0703410b
...
...
@@ -790,7 +790,8 @@ class ApiAction extends Action
function
showSingleAtomStatus
(
$notice
)
{
header
(
'Content-Type: application/atom+xml; charset=utf-8'
);
header
(
'Content-Type: application/atom+xml;type=entry;charset="utf-8"'
);
print
'<?xml version="1.0" encoding="UTF-8"?>'
.
"
\n
"
;
print
$notice
->
asAtomEntry
(
true
,
true
,
true
,
$this
->
scoped
);
}
...
...
lib/framework.php
View file @
0703410b
...
...
@@ -57,6 +57,17 @@ define('NOTICE_INBOX_SOURCE_FORWARD', 4);
define
(
'NOTICE_INBOX_SOURCE_PROFILE_TAG'
,
5
);
define
(
'NOTICE_INBOX_SOURCE_GATEWAY'
,
-
1
);
/**
* StatusNet had this string as valid path characters: '\pN\pL\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\'\@'
* Some of those characters can be troublesome when auto-linking plain text. Such as "http://some.com/)"
* URL encoding should be used whenever a weird character is used, the following strings are not definitive.
*/
define
(
'URL_REGEX_VALID_PATH_CHARS'
,
'\pN\pL\,\!\.\:\-\_\+\/\@\=\;\%\~\*'
);
define
(
'URL_REGEX_VALID_QSTRING_CHARS'
,
URL_REGEX_VALID_PATH_CHARS
.
'\&'
);
define
(
'URL_REGEX_VALID_FRAGMENT_CHARS'
,
URL_REGEX_VALID_QSTRING_CHARS
.
'\?\#'
);
define
(
'URL_REGEX_EXCLUDED_END_CHARS'
,
'\?\.\,\!\#\:\''
);
// don't include these if they are directly after a URL
define
(
'URL_REGEX_DOMAIN_NAME'
,
'(?:(?!-)[A-Za-z0-9\-]{1,63}(?<!-)\.)+[A-Za-z]{2,10}'
);
// append our extlib dir as the last-resort place to find libs
set_include_path
(
get_include_path
()
.
PATH_SEPARATOR
.
INSTALLDIR
.
'/extlib/'
);
...
...
lib/util.php
View file @
0703410b
...
...
@@ -1885,6 +1885,10 @@ function common_log_objstring(&$object)
function
common_valid_http_url
(
$url
,
$secure
=
false
)
{
if
(
empty
(
$url
))
{
return
false
;
}
// If $secure is true, only allow https URLs to pass
// (if false, we use '?' in 'https?' to say the 's' is optional)
$regex
=
$secure
?
'/^https$/'
:
'/^https?$/'
;
...
...
plugins/Blacklist/BlacklistPlugin.php
View file @
0703410b
...
...
@@ -249,6 +249,15 @@ class BlacklistPlugin extends Plugin
return
true
;
}
public
function
onUrlBlacklistTest
(
$url
)
{
common_debug
(
'Checking URL against blacklist: '
.
_ve
(
$url
));
if
(
!
$this
->
_checkUrl
(
$url
))
{
throw
new
ClientException
(
'Forbidden URL'
,
403
);
}
return
true
;
}
/**
* Helper for checking nicknames
*
...
...
plugins/LRDD/lib/discovery.php
View file @
0703410b
...
...
@@ -93,6 +93,8 @@ class Discovery
// Normalize the incoming $id to make sure we have a uri
$uri
=
self
::
normalize
(
$id
);
common_debug
(
sprintf
(
'Performing discovery for "%s" (normalized "%s")'
,
$id
,
$uri
));
foreach
(
$this
->
methods
as
$class
)
{
try
{
$xrd
=
new
XML_XRD
();
...
...
@@ -124,7 +126,14 @@ class Discovery
$xrd
->
loadString
(
$response
->
getBody
());
return
$xrd
;
}
catch
(
ClientException
$e
)
{
if
(
$e
->
getCode
()
===
403
)
{
common_log
(
LOG_INFO
,
sprintf
(
'%s: Aborting discovery on URL %s: %s'
,
_ve
(
$class
),
_ve
(
$uri
),
_ve
(
$e
->
getMessage
())));
break
;
}
}
catch
(
Exception
$e
)
{
common_log
(
LOG_INFO
,
sprintf
(
'%s: Failed for %s: %s'
,
_ve
(
$class
),
_ve
(
$uri
),
_ve
(
$e
->
getMessage
())));
continue
;
}
}
...
...
plugins/LRDD/lib/lrddmethod.php
View file @
0703410b
...
...
@@ -32,6 +32,9 @@ abstract class LRDDMethod
protected
function
fetchUrl
(
$url
,
$method
=
HTTPClient
::
METHOD_GET
)
{
// If we have a blacklist enabled, let's check against it
Event
::
handle
(
'UrlBlacklistTest'
,
array
(
$url
));
$client
=
new
HTTPClient
();
// GAAHHH, this method sucks! How about we make a better HTTPClient interface?
...
...
plugins/OStatus/OStatusPlugin.php
View file @
0703410b
...
...
@@ -272,6 +272,48 @@ class OStatusPlugin extends Plugin
return
true
;
}
/**
* Webfinger matches: @user@example.com or even @user--one.george_orwell@1984.biz
*
* @return array The matching IDs (without @ or acct:) and each respective position in the given string.
*/
static
function
extractWebfingerIds
(
$text
)
{
$wmatches
=
array
();
$result
=
preg_match_all
(
'/(?:^|\s+)@((?:\w+[\w\-\_\.]?)*(?:[\w\-\_\.]*\w+)@'
.
URL_REGEX_DOMAIN_NAME
.
')/'
,
$text
,
$wmatches
,
PREG_OFFSET_CAPTURE
);
if
(
$result
===
false
)
{
common_log
(
LOG_ERR
,
__METHOD__
.
': Error parsing webfinger IDs from text (preg_last_error=='
.
preg_last_error
()
.
').'
);
}
else
{
common_debug
(
sprintf
(
'Found %i matches for WebFinger IDs: %s'
,
count
(
$wmatches
),
_ve
(
$wmatches
)));
}
return
$wmatches
[
1
];
}
/**
* Profile URL matches: @example.com/mublog/user
*
* @return array The matching URLs (without @ or acct:) and each respective position in the given string.
*/
static
function
extractUrlMentions
(
$text
)
{
$wmatches
=
array
();
// In the regexp below we need to match / _before_ URL_REGEX_VALID_PATH_CHARS because it otherwise gets merged
// with the TLD before (but / is in URL_REGEX_VALID_PATH_CHARS anyway, it's just its positioning that is important)
$result
=
preg_match_all
(
'/(?:^|\s+)@('
.
URL_REGEX_DOMAIN_NAME
.
'(?:\/['
.
URL_REGEX_VALID_PATH_CHARS
.
']*)*)/'
,
$text
,
$wmatches
,
PREG_OFFSET_CAPTURE
);
if
(
$result
===
false
)
{
common_log
(
LOG_ERR
,
__METHOD__
.
': Error parsing profile URL mentions from text (preg_last_error=='
.
preg_last_error
()
.
').'
);
}
else
{
common_debug
(
sprintf
(
'Found %i matches for profile URL mentions: %s'
,
count
(
$wmatches
),
_ve
(
$wmatches
)));
}
return
$wmatches
[
1
];
}
/**
* Find any explicit remote mentions. Accepted forms:
* Webfinger: @user@example.com
...
...
@@ -285,76 +327,63 @@ class OStatusPlugin extends Plugin
{
$matches
=
array
();
$wmatches
=
array
();
// Webfinger matches: @user@example.com or even @user--one.george_orwell@1984.biz
if
(
preg_match_all
(
'!(?:^|\s+)@((?:\w+[\w\-\_\.]?)*(?:[\w\-\_\.]*\w+)@(?:\w+\-?\w+\.)*\w+(?:\w+\-\w+)*\.\w+)!'
,
$text
,
$wmatches
,
PREG_OFFSET_CAPTURE
))
{
foreach
(
$wmatches
[
1
]
as
$wmatch
)
{
list
(
$target
,
$pos
)
=
$wmatch
;
$this
->
log
(
LOG_INFO
,
"Checking webfinger '
$target
'"
);
$profile
=
null
;
try
{
$oprofile
=
Ostatus_profile
::
ensureWebfinger
(
$target
);
if
(
!
$oprofile
instanceof
Ostatus_profile
||
!
$oprofile
->
isPerson
())
{
continue
;
}
$profile
=
$oprofile
->
localProfile
();
}
catch
(
OStatusShadowException
$e
)
{
// This means we got a local user in the webfinger lookup
$profile
=
$e
->
profile
;
}
catch
(
Exception
$e
)
{
$this
->
log
(
LOG_ERR
,
"Webfinger check failed: "
.
$e
->
getMessage
());
foreach
(
self
::
extractWebfingerIds
(
$text
)
as
$wmatch
)
{
list
(
$target
,
$pos
)
=
$wmatch
;
$this
->
log
(
LOG_INFO
,
"Checking webfinger '
$target
'"
);
$profile
=
null
;
try
{
$oprofile
=
Ostatus_profile
::
ensureWebfinger
(
$target
);
if
(
!
$oprofile
instanceof
Ostatus_profile
||
!
$oprofile
->
isPerson
())
{
continue
;
}
$profile
=
$oprofile
->
localProfile
();
}
catch
(
OStatusShadowException
$e
)
{
// This means we got a local user in the webfinger lookup
$profile
=
$e
->
profile
;
}
catch
(
Exception
$e
)
{
$this
->
log
(
LOG_ERR
,
"Webfinger check failed: "
.
$e
->
getMessage
());
continue
;
}
assert
(
$profile
instanceof
Profile
);
assert
(
$profile
instanceof
Profile
);
$text
=
!
empty
(
$profile
->
nickname
)
&&
mb_strlen
(
$profile
->
nickname
)
<
mb_strlen
(
$target
)
?
$profile
->
getNickname
()
// TODO: we could do getFancyName() or getFullname() here
:
$target
;
$url
=
$profile
->
getUri
();
if
(
!
common_valid_http_url
(
$url
))
{
$url
=
$profile
->
getUrl
();
}
$matches
[
$pos
]
=
array
(
'mentioned'
=>
array
(
$profile
),
'type'
=>
'mention'
,
'text'
=>
$text
,
'position'
=>
$pos
,
'length'
=>
mb_strlen
(
$target
),
'url'
=>
$url
);
$text
=
!
empty
(
$profile
->
nickname
)
&&
mb_strlen
(
$profile
->
nickname
)
<
mb_strlen
(
$target
)
?
$profile
->
getNickname
()
// TODO: we could do getBestName() or getFullname() here
:
$target
;
$url
=
$profile
->
getUri
();
if
(
!
common_valid_http_url
(
$url
))
{
$url
=
$profile
->
getUrl
();
}
$matches
[
$pos
]
=
array
(
'mentioned'
=>
array
(
$profile
),
'type'
=>
'mention'
,
'text'
=>
$text
,
'position'
=>
$pos
,
'length'
=>
mb_strlen
(
$target
),
'url'
=>
$url
);
}
// Profile matches: @example.com/mublog/user
if
(
preg_match_all
(
'!(?:^|\s+)@((?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+(?:/\w+)*)!'
,
$text
,
$wmatches
,
PREG_OFFSET_CAPTURE
))
{
foreach
(
$wmatches
[
1
]
as
$wmatch
)
{
list
(
$target
,
$pos
)
=
$wmatch
;
$schemes
=
array
(
'http'
,
'https'
);
foreach
(
$schemes
as
$scheme
)
{
$url
=
"
$scheme
://
$target
"
;
$this
->
log
(
LOG_INFO
,
"Checking profile address '
$url
'"
);
try
{
$oprofile
=
Ostatus_profile
::
ensureProfileURL
(
$url
);
if
(
$oprofile
instanceof
Ostatus_profile
&&
!
$oprofile
->
isGroup
())
{
$profile
=
$oprofile
->
localProfile
();
$text
=
!
empty
(
$profile
->
nickname
)
&&
mb_strlen
(
$profile
->
nickname
)
<
mb_strlen
(
$target
)
?
$profile
->
nickname
:
$target
;
$matches
[
$pos
]
=
array
(
'mentioned'
=>
array
(
$profile
),
'type'
=>
'mention'
,
'text'
=>
$text
,
'position'
=>
$pos
,
'length'
=>
mb_strlen
(
$target
),
'url'
=>
$profile
->
getUrl
());
break
;
}
}
catch
(
Exception
$e
)
{
$this
->
log
(
LOG_ERR
,
"Profile check failed: "
.
$e
->
getMessage
());
foreach
(
self
::
extractUrlMentions
(
$text
)
as
$wmatch
)
{
list
(
$target
,
$pos
)
=
$wmatch
;
$schemes
=
array
(
'http'
,
'https'
);
foreach
(
$schemes
as
$scheme
)
{
$url
=
"
$scheme
://
$target
"
;
$this
->
log
(
LOG_INFO
,
"Checking profile address '
$url
'"
);
try
{
$oprofile
=
Ostatus_profile
::
ensureProfileURL
(
$url
);
if
(
$oprofile
instanceof
Ostatus_profile
&&
!
$oprofile
->
isGroup
())
{
$profile
=
$oprofile
->
localProfile
();
$text
=
!
empty
(
$profile
->
nickname
)
&&
mb_strlen
(
$profile
->
nickname
)
<
mb_strlen
(
$target
)
?
$profile
->
nickname
:
$target
;
$matches
[
$pos
]
=
array
(
'mentioned'
=>
array
(
$profile
),
'type'
=>
'mention'
,
'text'
=>
$text
,
'position'
=>
$pos
,
'length'
=>
mb_strlen
(
$target
),
'url'
=>
$profile
->
getUrl
());
break
;
}
}
catch
(
Exception
$e
)
{
$this
->
log
(
LOG_ERR
,
"Profile check failed: "
.
$e
->
getMessage
());
}
}
}
...
...
plugins/OStatus/actions/ostatussub.php
View file @
0703410b
...
...
@@ -242,9 +242,14 @@ class OStatusSubAction extends Action
function
pullRemoteProfile
()
{
$validate
=
new
Validate
();
$this
->
profile_uri
=
$this
->
trimmed
(
'profile'
);
try
{
if
(
$validate
->
email
(
$this
->
profile_uri
))
{
$this
->
profile_uri
=
Discovery
::
normalize
(
$this
->
trimmed
(
'profile'
));
}
catch
(
Exception
$e
)
{
return
false
;
}
try
{
if
(
Discovery
::
isAcct
(
$this
->
profile_uri
)
&&
$validate
->
email
(
mb_substr
(
$this
->
profile_uri
,
5
)))
{
$this
->
oprofile
=
Ostatus_profile
::
ensureWebfinger
(
$this
->
profile_uri
);
}
else
if
(
$validate
->
uri
(
$this
->
profile_uri
))
{
$this
->
oprofile
=
Ostatus_profile
::
ensureProfileURL
(
$this
->
profile_uri
);
...
...
@@ -387,7 +392,7 @@ class OStatusSubAction extends Action
function
title
()
{
// TRANS: Page title for OStatus remote subscription form.
return
_m
(
'Confirm
'
);
return
!
empty
(
$this
->
profile_uri
)
?
_m
(
'Confirm'
)
:
_m
(
'Remote subscription
'
);
}
/**
...
...
plugins/OStatus/actions/pushhub.php
View file @
0703410b
...
...
@@ -199,7 +199,7 @@ class PushHubAction extends Action
/**
* Grab and validate a URL from POST parameters.
* @throws ClientException for malformed or non-http/https URLs
* @throws ClientException for malformed or non-http/https
or blacklisted
URLs
*/
protected
function
argUrl
(
$arg
)
{
...
...
@@ -207,13 +207,14 @@ class PushHubAction extends Action