Skip to content

Commit 119ec15

Browse files
committed
Move auth token generation to resto /auth/create API
1 parent 070d9ce commit 119ec15

File tree

8 files changed

+127
-632
lines changed

8 files changed

+127
-632
lines changed

app/resto/core/RestoContext.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,16 @@ public function getUrl($withparams = true)
209209
* Create a Json Web Token
210210
*
211211
* @param string $identifier
212+
* @param integer $duration
212213
* @param json $jsonData
213214
* @return string
214215
*/
215-
public function createJWT($identifier, $jsonData = null)
216+
public function createJWT($identifier, $duration, $jsonData = null)
216217
{
217218
$payload = array(
218219
'sub' => $identifier,
219220
'iat' => time(),
220-
'exp' => time() + $this->core['tokenDuration']
221+
'exp' => time() + $duration
221222
);
222223
if (isset($jsonData)) {
223224
$payload['data'] = $jsonData;
@@ -230,12 +231,13 @@ public function createJWT($identifier, $jsonData = null)
230231
* Create a rJWT "resto Json Web Token" i.e. a JWT without the header part
231232
*
232233
* @param string $identifier
234+
* @param integer $duration (in seconds)
233235
* @param json $jsonData
234236
* @return string
235237
*/
236-
public function createRJWT($identifier, $jsonData = null)
238+
public function createRJWT($identifier, $duration, $jsonData = null)
237239
{
238-
$splitJWT = explode('.', $this->createJWT($identifier, $jsonData));
240+
$splitJWT = explode('.', $this->createJWT($identifier, $duration, $jsonData));
239241
return $splitJWT[1] . '.' .$splitJWT[2];
240242
}
241243

app/resto/core/RestoRouter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ class RestoRouter
8585
array('PUT', RestoRouter::ROUTE_TO_FEATURE . '/properties/{property}', true, 'FeaturesAPI::updateFeatureProperty'), // Update feature :featureId single property
8686

8787
// API for authentication (token based)
88-
array('GET', RestoRouter::ROUTE_TO_AUTH, true, 'AuthAPI::getToken'), // Return a valid auth token
88+
array('GET', RestoRouter::ROUTE_TO_AUTH, true, 'AuthAPI::getToken'),
89+
array('GET', RestoRouter::ROUTE_TO_AUTH . '/create', true, 'AuthAPI::createToken'), // Return a valid auth token
8990
array('GET', RestoRouter::ROUTE_TO_AUTH . '/check/{token}', false, 'AuthAPI::checkToken'), // Check auth token validity
9091
array('DELETE', RestoRouter::ROUTE_TO_AUTH . '/revoke/{token}', true, 'AuthAPI::revokeToken'), // Revoke auth token
9192
array('PUT', RestoRouter::ROUTE_TO_AUTH . '/activate/{token}', false, 'AuthAPI::activateUser'), // Activate owner of the token

app/resto/core/api/AuthAPI.php

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,117 @@ public function getToken()
9898
}
9999

100100
return array(
101-
'token' => $this->context->createRJWT($this->user->profile['id']),
101+
'token' => $this->context->createRJWT($this->user->profile['id'], $this->context->core['tokenDuration']),
102102
'profile' => $this->user->profile
103103
);
104104
}
105105

106+
/**
107+
* Create an authentication token
108+
*
109+
* @OA\Get(
110+
* path="/create",
111+
* summary="Create an authentication {token}",
112+
* description="Create an authentication token (aka rJWT) for user identified by {emailOrId}",
113+
* tags={"Authentication"},
114+
* @OA\Parameter(
115+
* name="emailOrId",
116+
* in="path",
117+
* required=true,
118+
* description="User email or id",
119+
* @OA\Schema(
120+
* type="string"
121+
* )
122+
* ),
123+
* @OA\Parameter(
124+
* name="duration",
125+
* in="path",
126+
* required=false,
127+
* description="Duration of token in days (default is 1 day)",
128+
* @OA\Schema(
129+
* type="string"
130+
* )
131+
* ),
132+
* @OA\Response(
133+
* response="200",
134+
* description="The token is created",
135+
* @OA\JsonContent(
136+
* @OA\Property(
137+
* property="userId",
138+
* type="string",
139+
* description="User id"
140+
* ),
141+
* @OA\Property(
142+
* property="duration",
143+
* type="integer",
144+
* description="Duration of token in days"
145+
* ),
146+
* @OA\Property(
147+
* property="valid_until",
148+
* type="string",
149+
* description="Token validity"
150+
* ),
151+
* @OA\Property(
152+
* property="token",
153+
* type="string",
154+
* description="Generated token"
155+
* ),
156+
* example={
157+
* "userId": 100,
158+
* "duration: 100,
159+
* "valid_until": "2023-05-03T11:20:13",
160+
* "token":"eyJzdWIiOiIxMDAiLCJpYXQiOjE2NzQ0NzI4MTMsImV4cCI6MTY4MzExMjgxM30.5fdRS1jr0fuF7HMu2oXb0sXViom39ExI2IR_FI5WK7k"
161+
* }
162+
* )
163+
* ),
164+
* @OA\Response(
165+
* response="401",
166+
* description="Unauthorized",
167+
* @OA\JsonContent(ref="#/components/schemas/UnauthorizedError")
168+
* ),
169+
* @OA\Response(
170+
* response="403",
171+
* description="Forbidden",
172+
* @OA\JsonContent(ref="#/components/schemas/ForbiddenError")
173+
* ),
174+
* security={
175+
* {"basicAuth":{}, "bearerAuth":{}, "queryAuth":{}}
176+
* }
177+
* )
178+
*
179+
* @param array $params
180+
*/
181+
public function createToken($params)
182+
{
183+
184+
// A token can be only be created by admin
185+
if ( !$this->user->hasGroup(RestoConstants::GROUP_ADMIN_ID) ) {
186+
return RestoLogUtil::httpError(403);
187+
}
188+
189+
if ( isset($params['duration']) && !ctype_digit($params['duration']) ) {
190+
return RestoLogUtil::httpError(400, 'Parameters duration must be a valid integer in days');
191+
}
192+
193+
if ( !isset($params['duration']) ) {
194+
$params['duration'] = (integer) ($this->context->core['tokenDuration'] / 86400);
195+
}
196+
197+
if ( !isset($params['userId']) || !ctype_digit($params['userId']) ) {
198+
return RestoLogUtil::httpError(400, 'Mandatory userId is not set or not valid');
199+
}
200+
201+
$days = isset($params['duration']) ? (integer) $params['duration'] : round($this->context->core['tokenDuration'] / 86400);
202+
$seconds = 86400 * $days;
203+
return array(
204+
'userId' => $params['userId'],
205+
'duration' => $days,
206+
'valid_until' => date('Y-m-d\TH:i:s', time() + $seconds),
207+
'token' => $this->context->createRJWT($params['userId'], $seconds)
208+
);
209+
210+
}
211+
106212
/**
107213
* Revoke authentication token
108214
*
@@ -319,7 +425,7 @@ public function activateUser($params)
319425
}
320426

321427
return array(
322-
'token' => $this->context->createRJWT($user->profile['id']),
428+
'token' => $this->context->createRJWT($user->profile['id'], $this->context->core['tokenDuration']),
323429
'profile' => $user->profile
324430
);
325431
}

app/resto/core/api/ServicesAPI.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ public function sendActivationLink($params, $body)
431431
// Send activation link
432432
if (isset($user->profile['id']) && $user->profile['activated'] === 0) {
433433
if (!((new RestoNotifier($this->context->servicesInfos, $this->context->lang))->sendMailForUserActivation($body['email'], $this->context->core['sendmail'], array(
434-
'token' => $this->context->createRJWT($user->profile['id'])
434+
'token' => $this->context->createRJWT($user->profile['id'], $this->context->core['tokenDuration'])
435435
)))) {
436436
RestoLogUtil::httpError(500, 'Cannot send activation link');
437437
}

app/resto/core/api/UsersAPI.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ private function storeProfile($profile, $storageInfo)
693693
}
694694

695695
if (!(new RestoNotifier($this->context->servicesInfos, $this->context->lang))->sendMailForUserActivation($profile['email'], $this->context->core['sendmail'], array(
696-
'token' => $this->context->createRJWT($userInfo['id'])
696+
'token' => $this->context->createRJWT($userInfo['id'], $this->context->core['tokenDuration'])
697697
))) {
698698
RestoLogUtil::httpError(500, 'Cannot send activation link');
699699
}

scripts/createUser.sh

Lines changed: 0 additions & 158 deletions
This file was deleted.

scripts/generateAuthToken

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ function showUsage {
3636
echo -e " -d | --duration Duration of token in days (default ${GREEN}${DAYS}${NC})"
3737
echo -e " -h | --help show this help"
3838
echo -e ""
39-
echo -e " !!! This script requires docker !!!"
4039
echo -e ""
4140
}
4241

@@ -91,18 +90,18 @@ do
9190
esac
9291
done
9392

94-
if ! command -v docker &> /dev/null
95-
then
96-
echo ""
97-
echo -e "${RED}[ERROR]${NC} The required \"docker\" command was not found. See https://docs.docker.com/get-docker/"
98-
echo ""
99-
exit 1
100-
fi
101-
10293
if [[ ! -f $(absolutePath ${ENV_FILE}) ]]; then
10394
echo ""
10495
echo -e "${RED}[ERROR]${NC} The file ${ENV_FILE} does not exists"
10596
echo ""
10697
exit 1
10798
fi
108-
docker run -it --rm -v ${ABS_ROOT_PATH}/php/generateAuthToken.php:/app/generateAuthToken.php -v $(absolutePath ${ENV_FILE}):/app/config.env php:7.2-alpine /app/generateAuthToken.php -e /app/config.env -i ${USER_ID} -d ${DAYS}
99+
100+
PUBLIC_ENDPOINT=$(grep ^PUBLIC_ENDPOINT= ${ENV_FILE} | awk -F= '{for (i=2; i<=NF; i++) print $i}'| xargs echo -n)
101+
ADMIN_USER_NAME=$(grep ^ADMIN_USER_NAME= ${ENV_FILE} | awk -F= '{for (i=2; i<=NF; i++) print $i}'| xargs echo -n)
102+
ADMIN_USER_PASSWORD=$(grep ^ADMIN_USER_PASSWORD= ${ENV_FILE} | awk -F= '{for (i=2; i<=NF; i++) print $i}'| xargs echo -n)
103+
104+
PUBLIC_ENDPOINT=${PUBLIC_ENDPOINT} \
105+
ADMIN_USER_NAME=${ADMIN_USER_NAME} \
106+
ADMIN_USER_PASSWORD=${ADMIN_USER_PASSWORD} \
107+
curl -u "${ADMIN_USER_NAME}:${ADMIN_USER_PASSWORD}" "{$PUBLIC_ENDPOINT}/auth/create?userId={$USER_ID}&duration=${DAYS}"

0 commit comments

Comments
 (0)