Skip to content

Commit

Permalink
Introduce link and rule for testing safe links
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaspaul committed Mar 1, 2018
1 parent 8b47036 commit 36cb0cc
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 1 deletion.
19 changes: 18 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
"email": "[email protected]"
}
],
"require": {},
"require": {
"google/apiclient": "^2.2",
"google/apiclient-services": "^0.48.0",
"guzzlehttp/guzzle": "^6.3",
"illuminate/config": "^5.6",
"illuminate/support": "^5.6",
"illuminate/translation": "^5.6"
},
"require-dev": {
"phpunit/phpunit": "^7.0",
"mockery/mockery": "^1.0",
Expand All @@ -26,5 +33,15 @@
"psr-4": {
"Tests\\": "tests/"
}
},
"config": {
"sort-packages": true
},
"extra": {
"laravel": {
"providers": [
"Jaspaul\\SafeLinkValidator\\ServiceProvider"
]
}
}
}
1 change: 1 addition & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
</whitelist>
</filter>
<php>
<env name="GOOGLE_SERVICE_API_KEY" value="your-key-goes-here-for-testing"/>
</php>
</phpunit>
8 changes: 8 additions & 0 deletions resources/config/safe-links.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

return [
'api-key' => env('GOOGLE_SERVICE_API_KEY', ''),
'types' => explode(',', env('SAFE_LINKS_THREAT_TYPES', 'THREAT_TYPE_UNSPECIFIED,MALWARE,SOCIAL_ENGINEERING,UNWANTED_SOFTWARE,POTENTIALLY_HARMFUL_APPLICATION')),
'platforms' => explode(',', env('SAFE_LINKS_PLATFORM_TYPES', 'PLATFORM_TYPE_UNSPECIFIED,WINDOWS,LINUX,ANDROID,OSX,IOS,ANY_PLATFORM,ALL_PLATFORMS,CHROME')),
'entry-types' => explode(',', env('SAFE_LINKS_ENTRY_TYPES', 'THREAT_ENTRY_TYPE_UNSPECIFIED,URL,EXECUTABLE')),
];
7 changes: 7 additions & 0 deletions resources/translations/safe-links.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

return [
'validation' => [
'link' => 'The :attribute field contained an unsafe link.',
]
];
70 changes: 70 additions & 0 deletions src/Link.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Jaspaul\SafeLinkValidator;

use Google_Client;
use GuzzleHttp\Psr7\Uri;
use Google_Service_Safebrowsing;
use Google_Service_Safebrowsing_ThreatInfo;
use Google_Service_Safebrowsing_ThreatEntry;
use Google_Service_Safebrowsing_FindThreatMatchesRequest;

class Link
{
/**
* The link to test
*
* @var \GuzzleHttp\Psr7\Uri
*/
private $uri;

/**
* Creates a new link from the provided url string.
*
* @param string $url
*
* @return \Jaspaul\SafeLinkValidator\Link
*/
public static function fromString(string $url): Link
{
return new Link(new Uri($url));
}

/**
* Creates a new link.
*
* @param \GuzzleHttp\Psr7\Uri $uri
*/
private function __construct(Uri $uri)
{
$this->uri = $uri;
}

/**
* Determines if the link is safe or not.
*
* @return boolean
*/
public function isSafe(): bool
{
$client = new Google_Client();
$client->setDeveloperKey(config('safe-links.api-key'));

$threatEntry = new Google_Service_Safebrowsing_ThreatEntry();
$threatEntry->setUrl((string) $this->uri);

$threatInfo = new Google_Service_Safebrowsing_ThreatInfo();
$threatInfo->setThreatTypes(config('safe-links.types'));
$threatInfo->setPlatformTypes(config('safe-links.platforms'));
$threatInfo->setThreatEntryTypes(config('safe-links.entry-types'));
$threatInfo->setThreatEntries([$threatEntry]);

$request = new Google_Service_Safebrowsing_FindThreatMatchesRequest();
$request->setThreatInfo($threatInfo);

$service = new Google_Service_Safebrowsing($client);
$matches = $service->threatMatches->find($request)->getMatches();

return empty($matches);
}
}
31 changes: 31 additions & 0 deletions src/SafeLinkRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Jaspaul\SafeLinkValidator;

use Illuminate\Contracts\Validation\Rule;

class SafeLinkRule implements Rule
{
/**
* Determines if the provided link value is safe.
*
* @param string $attribute
* @param string $value
*
* @return boolean
*/
public function passes($attribute, $value)
{
return Link::fromString($value)->isSafe();
}

/**
* The message to return when it failes.
*
* @return string
*/
public function message()
{
return trans('safe-links::validation.link');
}
}
45 changes: 45 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Jaspaul\SafeLinkValidator;

use Illuminate\Support\ServiceProvider as IlluminateServiceProvider;

class ServiceProvider extends IlluminateServiceProvider
{
/**
* Boot the service provider.
*
* @return void
*/
public function boot()
{
$this->publishConfigurations();
$this->loadTranslationsFrom(__DIR__ . '/../resources/translations', 'safe-links');
}

/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(__DIR__ . '/../resources/config/safe-links.php', 'safe-links');
}

/**
* Adds our configuration file to the publishes array.
*
* @return void
*/
protected function publishConfigurations()
{
$this->publishes([
__DIR__ . '/../resources/config/safe-links.php' => config_path('safe-links.php'),
]);

$this->publishes([
__DIR__ . '/../resources/translations' => resource_path('lang/vendor/safe-links'),
]);
}
}
26 changes: 26 additions & 0 deletions tests/LinkTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Tests;

use Jaspaul\SafeLinkValidator\Link;

class LinkTest extends TestCase
{
/**
* @test
*/
public function isSafe_returns_false_if_you_provide_an_unsafe_link()
{
$link = Link::fromString('http://malware.testing.google.test/testing/malware/');
$this->assertFalse($link->isSafe());
}

/**
* @test
*/
public function isSafe_returns_true_if_you_provide_a_safe_link()
{
$link = Link::fromString('http://www.google.com/');
$this->assertTrue($link->isSafe());
}
}
26 changes: 26 additions & 0 deletions tests/SafeLinkRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Tests;

use Jaspaul\SafeLinkValidator\SafeLinkRule;

class SafeLinkRuleTest extends TestCase
{
/**
* @test
*/
public function passes_returns_false_if_you_provide_an_unsafe_link()
{
$rule = new SafeLinkRule();
$this->assertFalse($rule->passes('attribute', 'http://malware.testing.google.test/testing/malware/'));
}

/**
* @test
*/
public function passes_returns_true_if_you_provide_a_safe_link()
{
$rule = new SafeLinkRule();
$this->assertTrue($rule->passes('attribute', 'http://www.google.com'));
}
}
13 changes: 13 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Mockery;
use Orchestra\Testbench\TestCase as Base;
use Jaspaul\SafeLinkValidator\ServiceProvider;

abstract class TestCase extends Base
{
Expand All @@ -15,4 +16,16 @@ protected function setUpMockery()
Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
Mockery::getConfiguration()->allowMockingMethodsUnnecessarily(false);
}

/**
* @param \Illuminate\Foundation\Application $app
*
* @return array
*/
protected function getPackageProviders($app)
{
return [
ServiceProvider::class,
];
}
}

0 comments on commit 36cb0cc

Please sign in to comment.