Skip to content

Commit

Permalink
Oauth2Server method to determine if access token expired (CO-2857)
Browse files Browse the repository at this point in the history
  • Loading branch information
skoranda committed Nov 5, 2024
1 parent a7cc4b2 commit e3d389d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
1 change: 1 addition & 0 deletions app/Config/Schema/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,7 @@
<field name="scope" type="C" size="256" />
<field name="refresh_token" type="C" size="160" />
<field name="access_token" type="C" size="160" />
<field name="access_token_exp" type="I" />
<field name="token_response" type="XL" />
<field name="proxy" type="C" size="512" />
<field name="created" type="T" />
Expand Down
60 changes: 58 additions & 2 deletions app/Model/Oauth2Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ class Oauth2Server extends AppModel {
'required' => false,
'allowEmpty' => true
),
'access_token_exp' => array(
'rule' => 'numeric',
'required' => false,
'allowEmpty' => true
)
);

/**
Expand Down Expand Up @@ -158,6 +163,47 @@ public function beforeSave($options = array()) {
public function exchangeCode($id, $code, $redirectUri, $store=true) {
return $this->obtainToken($id, 'authorization_code', $code, $redirectUri, $store);
}

/**
* Determine if the stored access token is expired now or will be
* at a time now + deltat in the future.
*
* @since COmanage Registry 4.5.0
* @param Integer $id Oauth2Server ID
* @param Integer $deltat Seconds from now to test expiration
* @return Boolean true if expired false if not or null if cannot be determined
* @throws RuntimeException
*/

public function isExpired($id, $deltat = 0) {
$args = array();
$args['conditions']['Oauth2Server.id'] = $id;
$args['contain'] = false;

$srvr = $this->find('first', $args);

if(!$srvr) {
throw new RuntimeException(_txt('er.notfound', array(_txt('ct.oauth2_servers.1'), $id)));
}

// The model is not required to store the access token and the
// OAuth2 server is not required to provide an expiration time
// when sending the access token, though it is RECOMMENDED in
// section 5.1 of RFC 6749.
if(!array_key_exists('access_token', $srvr['Oauth2Server']) ||
!array_key_exists('access_token_exp', $srvr['Oauth2Server'])) {
return null;
}

$accessTokenExp = $srvr['Oauth2Server']['access_token_exp'];
$now = time();

if($accessTokenExp + $deltat < $now) {
return true;
}

return false;
}

/**
* Obtain an OAuth token.
Expand Down Expand Up @@ -229,9 +275,19 @@ public function obtainToken($id, $grantType, $code=null, $redirectUri=null, $sto
);

// We shouldn't have a new refresh token on a refresh_token grant
// (which just gets us a new access token).
// (which just gets us a new access token). Additionally section
// 4.4.3 of RFC 6749 explains that the server should NOT return
// a refresh token for a client credentials grant.
if($grantType != 'refresh_token') {
$data['refresh_token'] = $json->refresh_token;
if(property_exists($json, 'refresh_token')) {
$data['refresh_token'] = $json->refresh_token;
}
}

// If the Oauth2 server returned expires_in use it to set the
// access token expiration time. See section 5.1 of RFC 6749.
if(property_exists($json, 'expires_in')) {
$data['access_token_exp'] = time() + $json->expires_in;
}

// We don't want to change any attributes not specified above
Expand Down

0 comments on commit e3d389d

Please sign in to comment.