Skip to content
This repository was archived by the owner on Feb 21, 2025. It is now read-only.

Commit 08d513d

Browse files
committed
Add service client
1 parent 1cc8895 commit 08d513d

File tree

11 files changed

+321
-1
lines changed

11 files changed

+321
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor
2+
composer.lock
3+
.phpunit.result.cache

.travis.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
language: php
2+
3+
php:
4+
- 7.3
5+
- nightly
6+
7+
matrix:
8+
allow_failures:
9+
- php: nightly
10+
11+
before_script: composer install

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,24 @@
1-
# ipintel
1+
# IpIntel
2+
3+
Small library to query the fraud ip detection service of https://getipintel.net/
4+
5+
# Requirements
6+
7+
- php 7.3
8+
- curl
9+
- an email address
10+
11+
# Installation
12+
13+
`composer require usox/ipintel`
14+
15+
# Usage
16+
17+
```php
18+
$client = new \Usox\InIntel(
19+
new \Curl\Curl(),
20+
'your_email@addr.ess
21+
);
22+
23+
$result = $client->validate('127.0.0.1');
24+
```

composer.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "usox/ipintel",
3+
"description": "Client for https://getipintel.net/",
4+
"type": "library",
5+
"autoload": {
6+
"psr-4": {
7+
"Usox\\IpIntel\\": ["src/IpIntel/", "tests/IpIntel/"]
8+
}
9+
},
10+
"require": {
11+
"ext-curl": "*",
12+
"php": ">=7.3",
13+
"php-curl-class/php-curl-class": "^8.6"
14+
},
15+
"require-dev": {
16+
"phpunit/phpunit": "^8.4",
17+
"mockery/mockery": "^1.2"
18+
},
19+
"license": "MIT",
20+
"authors": [
21+
{
22+
"name": "Daniel Jakob",
23+
"email": "github@usox.org"
24+
}
25+
],
26+
"scripts": {
27+
"test": "phpunit"
28+
}
29+
}

example/retrieve.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use Curl\Curl;
4+
use Usox\IpIntel\IpIntel;
5+
6+
require_once __DIR__ . '/../vendor/autoload.php';
7+
8+
$ip = '127.0.0.1';
9+
10+
$client = new IpIntel(
11+
new Curl(),
12+
'YOUR_EMAIL@ADDRESS.HERE'
13+
);
14+
15+
var_dump($client->validate($ip));

phpunit.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false">
11+
<testsuites>
12+
<testsuite name="TestSuite">
13+
<directory suffix="Test.php">./tests</directory>
14+
</testsuite>
15+
</testsuites>
16+
<listeners>
17+
<listener class="\Mockery\Adapter\Phpunit\TestListener"/>
18+
</listeners>
19+
</phpunit>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Usox\IpIntel\Exception;
6+
7+
abstract class IpIntelException extends \Exception
8+
{
9+
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Usox\IpIntel\Exception;
6+
7+
final class ServiceException extends IpIntelException
8+
{
9+
10+
}

src/IpIntel/IpIntel.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Usox\IpIntel;
6+
7+
use Curl\Curl;
8+
9+
final class IpIntel implements IpIntelInterface
10+
{
11+
/**
12+
* @var Curl
13+
*/
14+
private $curl;
15+
16+
/**
17+
* @var string Service Url
18+
*/
19+
private $serviceUrl;
20+
21+
/**
22+
* @var int The connection timeout in seconds
23+
*/
24+
private $timeout;
25+
26+
/**
27+
* @var string Contact mail address
28+
*/
29+
private $contactEmailAddress;
30+
31+
/**
32+
* @var string|null Custom flag to append to the url
33+
*/
34+
private $customFlag;
35+
36+
public function __construct(
37+
Curl $curl,
38+
string $contactEmailAddress,
39+
?string $customFlag = null,
40+
int $timeout = 5,
41+
string $serviceUrl = 'https://check.getipintel.net'
42+
) {
43+
$this->curl = $curl;
44+
$this->contactEmailAddress = $contactEmailAddress;
45+
$this->customFlag = $customFlag;
46+
$this->timeout = $timeout;
47+
$this->serviceUrl = $serviceUrl;
48+
}
49+
50+
public function validate(string $ip, float $fraudProbability = 0.95): bool
51+
{
52+
$data = [
53+
'ip' => $ip,
54+
'contact' => $this->contactEmailAddress
55+
];
56+
57+
if ($this->customFlag !== null) {
58+
$data['flags'] = $this->customFlag;
59+
}
60+
61+
$this->curl->setTimeout($this->timeout);
62+
63+
$response = $this->curl->get(
64+
sprintf(
65+
'%s/check.php',
66+
$this->serviceUrl
67+
),
68+
$data
69+
);
70+
71+
if ($response < 0 || strcmp($response, "") == 0) {
72+
throw new Exception\ServiceException();
73+
}
74+
75+
return (float) $response < $fraudProbability;
76+
}
77+
}

src/IpIntel/IpIntelInterface.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Usox\IpIntel;
4+
5+
interface IpIntelInterface
6+
{
7+
8+
/**
9+
* @throws Exception\ServiceException
10+
*/
11+
public function validate(string $ip, float $fraudProbability = 0.95): bool;
12+
}

tests/IpIntel/IpIntelTest.php

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Usox\IpIntel;
6+
7+
use Curl\Curl;
8+
use Mockery;
9+
use Mockery\Adapter\Phpunit\MockeryTestCase;
10+
use Mockery\MockInterface;
11+
use Usox\IpIntel\Exception\ServiceException;
12+
13+
class IpIntelTest extends MockeryTestCase
14+
{
15+
/**
16+
* @var null|MockInterface|Curl
17+
*/
18+
private $curl;
19+
20+
/**
21+
* @var null|IpIntel
22+
*/
23+
private $ipIntel;
24+
25+
private $contactEmailAddress = 'foo@bar.baz';
26+
27+
public function setUp(): void
28+
{
29+
$this->curl = Mockery::mock(Curl::class);
30+
31+
$this->ipIntel = new IpIntel(
32+
$this->curl,
33+
$this->contactEmailAddress
34+
);
35+
}
36+
37+
public function testValidateReturnsFalseIfAbovePropability(): void
38+
{
39+
$ip = '666.42.33.21';
40+
41+
$this->curl->shouldReceive('setTimeout')
42+
->with(5)
43+
->once();
44+
$this->curl->shouldReceive('get')
45+
->with(
46+
'https://check.getipintel.net/check.php',
47+
[
48+
'ip' => $ip,
49+
'contact' => $this->contactEmailAddress
50+
]
51+
)
52+
->once()
53+
->andReturn('888');
54+
55+
$this->assertFalse(
56+
$this->ipIntel->validate($ip, 777)
57+
);
58+
}
59+
60+
public function testValidateAppendsCustomFlagAndReturnsTrueIfBelowPropability(): void
61+
{
62+
$ipIntel = new IpIntel(
63+
$this->curl,
64+
$this->contactEmailAddress,
65+
'm'
66+
);
67+
$ip = '666.42.33.21';
68+
69+
$this->curl->shouldReceive('setTimeout')
70+
->with(5)
71+
->once();
72+
$this->curl->shouldReceive('get')
73+
->with(
74+
'https://check.getipintel.net/check.php',
75+
[
76+
'ip' => $ip,
77+
'contact' => $this->contactEmailAddress,
78+
'flags' => 'm'
79+
]
80+
)
81+
->once()
82+
->andReturn('0.1');
83+
84+
$this->assertTrue(
85+
$ipIntel->validate($ip, 0.2)
86+
);
87+
}
88+
89+
public function testValidateThrowsExceptionOnServiceError(): void
90+
{
91+
$this->expectException(ServiceException::class);
92+
93+
$ip = '666.42.33.21';
94+
95+
$this->curl->shouldReceive('setTimeout')
96+
->with(5)
97+
->once();
98+
$this->curl->shouldReceive('get')
99+
->with(
100+
'https://check.getipintel.net/check.php',
101+
[
102+
'ip' => $ip,
103+
'contact' => $this->contactEmailAddress
104+
]
105+
)
106+
->once()
107+
->andReturn('');
108+
109+
$this->ipIntel->validate($ip, 0.2);
110+
}
111+
}

0 commit comments

Comments
 (0)