看板初始化提交
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkInterface;
|
||||
|
||||
/**
|
||||
* Attachment Link
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AttachmentLink extends BaseLink implements ExternalLinkInterface
|
||||
{
|
||||
/**
|
||||
* Get link title
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
$path = parse_url($this->url, PHP_URL_PATH);
|
||||
return basename($path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkProviderInterface;
|
||||
|
||||
/**
|
||||
* Attachment Link Provider
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AttachmentLinkProvider extends BaseLinkProvider implements ExternalLinkProviderInterface
|
||||
{
|
||||
/**
|
||||
* File extensions that are not attachments
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $extensions = array(
|
||||
'html',
|
||||
'htm',
|
||||
'xhtml',
|
||||
'php',
|
||||
'jsp',
|
||||
'do',
|
||||
'action',
|
||||
'asp',
|
||||
'aspx',
|
||||
'cgi',
|
||||
);
|
||||
|
||||
/**
|
||||
* Get provider name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return t('Attachment');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link type
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'attachment';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dictionary of supported dependency types by the provider
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
return array(
|
||||
'related' => t('Related'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the provider can parse correctly the user input
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function match()
|
||||
{
|
||||
if (preg_match('/^https?:\/\/.*\/.*\.([^\/]+)$/', $this->userInput, $matches)) {
|
||||
return $this->isValidExtension($matches[1]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link found with the properties
|
||||
*
|
||||
* @access public
|
||||
* @return \Kanboard\Core\ExternalLink\ExternalLinkInterface
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
$link = new AttachmentLink($this->container);
|
||||
$link->setUrl($this->userInput);
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check file extension
|
||||
*
|
||||
* @access protected
|
||||
* @param string $extension
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isValidExtension($extension)
|
||||
{
|
||||
$extension = strtolower($extension);
|
||||
|
||||
foreach ($this->extensions as $ext) {
|
||||
if ($extension === $ext) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Base Link
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class BaseLink extends Base
|
||||
{
|
||||
/**
|
||||
* URL
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $url = '';
|
||||
|
||||
/**
|
||||
* Get link URL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set link URL
|
||||
*
|
||||
* @access public
|
||||
* @param string $url
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Base Link Provider
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class BaseLinkProvider extends Base
|
||||
{
|
||||
/**
|
||||
* User input
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $userInput = '';
|
||||
|
||||
/**
|
||||
* Set text entered by the user
|
||||
*
|
||||
* @access public
|
||||
* @param string $input
|
||||
*/
|
||||
public function setUserTextInput($input)
|
||||
{
|
||||
$this->userInput = trim($input);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkInterface;
|
||||
|
||||
/**
|
||||
* File Link
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class FileLink extends BaseLink implements ExternalLinkInterface
|
||||
{
|
||||
/**
|
||||
* Get link title
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
$path = parse_url($this->url, PHP_URL_PATH);
|
||||
return basename(str_replace('\\', '/', $path));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkProviderInterface;
|
||||
|
||||
/**
|
||||
* File Link Provider
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class FileLinkProvider extends BaseLinkProvider implements ExternalLinkProviderInterface
|
||||
{
|
||||
protected $excludedPrefixes= array(
|
||||
'http',
|
||||
'ftp',
|
||||
);
|
||||
|
||||
/**
|
||||
* Get provider name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return t('Local File');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link type
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'file';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dictionary of supported dependency types by the provider
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
return array(
|
||||
'related' => t('Related'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the provider can parse correctly the user input
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function match()
|
||||
{
|
||||
if (strpos($this->userInput, '://') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->excludedPrefixes as $prefix) {
|
||||
if (strpos($this->userInput, $prefix) === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link found with the properties
|
||||
*
|
||||
* @access public
|
||||
* @return \Kanboard\Core\ExternalLink\ExternalLinkInterface
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
$link = new FileLink($this->container);
|
||||
$link->setUrl($this->userInput);
|
||||
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkInterface;
|
||||
|
||||
/**
|
||||
* Web Link
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class WebLink extends BaseLink implements ExternalLinkInterface
|
||||
{
|
||||
/**
|
||||
* Get link title
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
if (! EXTERNAL_LINK_ALLOW_PRIVATE_NETWORKS && $this->httpClient->isPrivateURL($this->url)) {
|
||||
$this->logger->info('Blocked attempt to fetch URL from private network: '.$this->url);
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
// Do not follow redirects to prevent SSRF bypasses through redirect chains.
|
||||
$html = $this->httpClient->get($this->url, [], false, false);
|
||||
|
||||
if (preg_match('/<title>(.*)<\/title>/siU', $html, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
$components = parse_url($this->url);
|
||||
|
||||
if (! empty($components['host']) && ! empty($components['path'])) {
|
||||
return $components['host'].$components['path'];
|
||||
}
|
||||
|
||||
return $this->url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\ExternalLink;
|
||||
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkProviderInterface;
|
||||
|
||||
/**
|
||||
* Web Link Provider
|
||||
*
|
||||
* @package externalLink
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class WebLinkProvider extends BaseLinkProvider implements ExternalLinkProviderInterface
|
||||
{
|
||||
/**
|
||||
* Get provider name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return t('Web Link');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link type
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'weblink';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dictionary of supported dependency types by the provider
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
return array(
|
||||
'related' => t('Related'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the provider can parse correctly the user input
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function match()
|
||||
{
|
||||
$startWithHttp = strpos($this->userInput, 'http://') === 0 || strpos($this->userInput, 'https://') === 0;
|
||||
$validUrl = filter_var($this->userInput, FILTER_VALIDATE_URL);
|
||||
|
||||
return $startWithHttp && $validUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link found with the properties
|
||||
*
|
||||
* @access public
|
||||
* @return \Kanboard\Core\ExternalLink\ExternalLinkInterface
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
$link = new WebLink($this->container);
|
||||
$link->setUrl($this->userInput);
|
||||
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user