Skip to content

Commit b1a0018

Browse files
committed
Initial commit
0 parents  commit b1a0018

File tree

10 files changed

+308
-0
lines changed

10 files changed

+308
-0
lines changed

.env.ci

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
DATABASE_DRIVER=mysql
2+
DATABASE_NAME=simple_auth_test
3+
DATABASE_USER=root
4+
DATABASE_PASSWORD=

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
DATABASE_DRIVER=mysql
2+
DATABASE_NAME=database_name
3+
DATABASE_USER=user
4+
DATABASE_PASSWORD=password

.gitignore

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

.travis.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
language: php
3+
4+
php:
5+
- 7.2
6+
- 7.3
7+
8+
services:
9+
- mysql
10+
11+
addons:
12+
apt:
13+
sources:
14+
- mysql-5.7-trusty
15+
packages:
16+
- mysql-server
17+
18+
dist: trusty
19+
20+
sudo: required
21+
22+
before_script:
23+
- mysql -e 'create database simple_auth_test;'
24+
- cp .env.ci .env
25+
- php -S localhost:5000 index.php &
26+
27+
script:
28+
- vendor/bin/phpunit

Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Install required packages
2+
FROM ubuntu:16.04
3+
RUN apt-get update
4+
RUN apt-get install -y software-properties-common
5+
RUN apt-get install -y python-software-properties
6+
RUN LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php
7+
RUN apt-get update
8+
RUN apt-get install -y apt-transport-https apt-utils curl php7.2-cli php7.2-mysql php7.2-curl
9+
RUN apt-get install -y php7.2-xml php7.2-dom php7.2-xsl php7.2-json php7.2-fpm php7.2-gd nginx
10+
RUN apt-get install -y libcurl3-openssl-dev vim
11+
12+
RUN mv /etc/localtime /etc/localtime.old
13+
RUN ln -s /usr/share/zoneinfo/Asia/Taipei /etc/localtime
14+
15+
RUN apt-get update && apt-get install -y locales wget
16+
RUN locale-gen "en_US.UTF-8"
17+
RUN echo 'LC_ALL="en_US.UTF-8"' > /etc/default/locale
18+
19+
# Install Simple Auth API service
20+
WORKDIR /var/www/html
21+
COPY ./config.ini ./
22+
COPY ./nginx-default.conf /etc/nginx/sites-available/default
23+
COPY ./*.php ./
24+
COPY ./.env.example ./
25+
RUN curl -sS https://getcomposer.org/installer | php
26+
RUN php composer.phar install -n
27+
28+
EXPOSE 80
29+
CMD ["bash", "-c", "service php7.2-fpm start && nginx -g 'daemon off;'"]

composer.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "lee/simple-auth-php",
3+
"description": "This is a simple auth API",
4+
"type": "project",
5+
"require": {
6+
"vlucas/phpdotenv": "^3.6",
7+
"carbondate/carbon": "^1.33"
8+
},
9+
"require-dev": {
10+
"phpunit/phpunit": "^8.3",
11+
"guzzlehttp/guzzle": "^6.2"
12+
},
13+
"license": "MIT",
14+
"authors": [
15+
{
16+
"name": "peter279k",
17+
"email": "[email protected]"
18+
}
19+
],
20+
"minimum-stability": "dev",
21+
"prefer-stable": true
22+
}

index.php

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
3+
require_once __DIR__ . '/vendor/autoload.php';
4+
5+
use Carbon\Carbon;
6+
use Dotenv\Dotenv;
7+
8+
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
9+
echo 'Sorry. This method is not accepted.';
10+
}
11+
12+
$dotEnv = Dotenv::create(__DIR__);
13+
$dotEnv->load();
14+
15+
$databaseDriver = getenv('DATABASE_DRIVER');
16+
$databaseName = getenv('DATABASE_NAME');
17+
$databaseUser = getenv('DATABASE_USER');
18+
$databasePassword = getenv('DATABASE_PASSWORD');
19+
20+
$action = $_POST['action'] ?? 'none';
21+
22+
if ($action === 'none') {
23+
echo json_encode(['result' => 'Sorry. The action is missing.']);
24+
exit(0);
25+
}
26+
27+
if ($action === 'login') {
28+
$user = $_POST['user'] ?? 'none';
29+
$password = $_POST['password'] ?? 'none';
30+
$sql = 'select count(account) from energy_solid_isc where account = :account AND password = :password';
31+
$dsn = sprintf("mysql:host=localhost;dbname=%s;charset=utf8mb4", $databaseName);
32+
$options = [
33+
PDO::ATTR_EMULATE_PREPARES => false,
34+
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
35+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
36+
];
37+
38+
try {
39+
$pdo = new PDO($dsn, $databaseUser, $databasePassword, $options);
40+
$stmt = $pdo->prepare($sql);
41+
$stmt->execute([':account' => $user, ':password' => $password]);
42+
$result = (array) $stmt->fetchAll(PDO::FETCH_ASSOC);
43+
44+
if (count($result) === 0) {
45+
echo json_encode(['result' => 'Auth is failed']);
46+
} else {
47+
$expired = new Carbon('Asia/Taipei');
48+
$expiredDate = $expired->addDays(1)->format('Y-m-d H:m:s');
49+
$sql = 'insert into tokens(token, expired) values(:token, :expired)';
50+
$stmt = $pdo->prepare($sql);
51+
$stmt->execute([':token' => $token, ':expired' => $expiredDate]);
52+
$result = (array) $stmt->fetchAll(PDO::FETCH_ASSOC);
53+
54+
$token = hash('sha512', $expiredDate);
55+
echo json_encode(['result' => 'Auth is successful.', 'token' => $token]);
56+
}
57+
58+
$stmt = null;
59+
$pdo = null;
60+
} catch (\Exception $e) {
61+
error_log($e->getMessage());
62+
echo 'Connection is failed.';
63+
}
64+
65+
if ($user === 'none' || $password === 'none') {
66+
echo 'The user or password is missing';
67+
}
68+
} else if ($action === 'logout') {
69+
$dsn = sprintf("mysql:host=localhost;dbname=%s;charset=utf8mb4", $databaseName);
70+
$options = [
71+
PDO::ATTR_EMULATE_PREPARES => false,
72+
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
73+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
74+
];
75+
$token = $_POST['token'] ?? 'none';
76+
77+
if ($token === 'none') {
78+
echo json_encode(['result' => 'Logout is done.']);
79+
}
80+
81+
try {
82+
$sql = 'select count(*) from tokens where token = :token';
83+
$pdo = new PDO($dsn, $databaseUser, $databasePassword, $options);
84+
$stmt = $pdo->prepare($sql);
85+
$stmt->execute([':token' => $token]);
86+
$result = (array) $stmt->fetchAll(PDO::FETCH_ASSOC);
87+
88+
if (count($result) === 0) {
89+
echo json_encode(['result' => 'Logout is done.']);
90+
} else {
91+
$sql = 'delete from tokens where token = :token';
92+
$stmt = $pdo->prepare($sql);
93+
$stmt->execute([':token' => $token]);
94+
echo json_encode(['result' => 'Logout is done.']);
95+
}
96+
97+
$stmt = null;
98+
$pdo = null;
99+
} catch (\Exception $e) {
100+
error_log($e->getMessage());
101+
echo json_encode(['result' => 'Connection is failed.']);
102+
}
103+
} else if ($action === 'status') {
104+
$dsn = sprintf("mysql:host=localhost;dbname=%s;charset=utf8mb4", $databaseName);
105+
$options = [
106+
PDO::ATTR_EMULATE_PREPARES => false,
107+
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
108+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
109+
];
110+
$token = $_POST['token'] ?? 'none';
111+
112+
if ($token === 'none') {
113+
echo json_encode(['result' => 'Logout is done.']);
114+
}
115+
116+
try {
117+
$sql = 'select count(*) from tokens where token = :token';
118+
$pdo = new PDO($dsn, $databaseUser, $databasePassword, $options);
119+
$stmt = $pdo->prepare($sql);
120+
$stmt->execute([':token' => $token]);
121+
$result = (array) $stmt->fetchAll(PDO::FETCH_ASSOC);
122+
123+
if (count($result) !== 1) {
124+
echo json_encode(['result' => 'It is not verified.']);
125+
} else {
126+
$expiredDate = $result[0]['expired'];
127+
$expiredTimestamp = Carbon::parse($expiredDate)->timestamp;
128+
$dateTimestamp = Carbon::now()->timestamp;
129+
130+
if ($expiredTimestamp - $dateTimestamp <= 0) {
131+
$sql = 'delete from tokens where token = :token';
132+
$stmt = $pdo->prepare($sql);
133+
$stmt->execute([':token' => $token]);
134+
echo json_encode(['result' => 'Token is expired. It should be logout.']);
135+
} else {
136+
echo json_encode(['result' => 'Token is live.']);
137+
}
138+
}
139+
140+
$stmt = null;
141+
$pdo = null;
142+
} catch (\Exception $e) {
143+
error_log($e->getMessage());
144+
echo json_encode(['result' => 'Connection is failed.']);
145+
}
146+
} else {
147+
echo json_encode(['result' => 'Invalid actions']);
148+
}

nginx-default.conf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
server {
2+
listen 80 default_server;
3+
listen [::]:80 default_server;
4+
5+
root /var/www/html;
6+
7+
# Add index.php to the list if you are using PHP
8+
index index.php index.html index.htm index.nginx-debian.html;
9+
10+
server_name _;
11+
12+
location / {
13+
try_files $uri $uri/ /index.php?$query_string;
14+
}
15+
16+
location ~ \.php$ {
17+
include snippets/fastcgi-php.conf;
18+
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
19+
}
20+
}

phpunit.xml.dist

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<phpunit
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
4+
backupGlobals="true"
5+
backupStaticAttributes="false"
6+
bootstrap="vendor/autoload.php"
7+
cacheTokens="false"
8+
colors="true"
9+
convertErrorsToExceptions="true"
10+
convertNoticesToExceptions="true"
11+
convertWarningsToExceptions="true"
12+
forceCoversAnnotation="false"
13+
>
14+
<testsuites>
15+
<testsuite name="Simple Auth Test Suite">
16+
<directory suffix="Test.php">tests/</directory>
17+
</testsuite>
18+
</testsuites>
19+
</phpunit>

tests/IndexTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use GuzzleHttp\Client;
4+
use PHPUnit\Framework\TestCase;
5+
6+
class IndexTest extends TestCase
7+
{
8+
public function testMethodIsNotAccepted()
9+
{
10+
$client = new Client();
11+
$response = $client->request('GET', 'http://localhost:5000');
12+
$response = (string) $response->getBody();
13+
$response = json_decode($response, true)['result'];
14+
15+
$this->assertSame('Sorry. This method is not accepted.', $response);
16+
}
17+
18+
public function testActionFieldIsMissing()
19+
{
20+
$client = new Client();
21+
$formParams = [
22+
'form_params' => [
23+
'field_name' => 'invalid',
24+
],
25+
];
26+
$response = $client->request('POST', 'http://localhost:5000', $formParams);
27+
$response = (string) $response->getBody();
28+
$response = json_decode($response, true)['result'];
29+
30+
$this->assertSame('', $response);
31+
}
32+
}

0 commit comments

Comments
 (0)