Skip to content

Commit

Permalink
Dispatch...
Browse files Browse the repository at this point in the history
  • Loading branch information
Ioannis committed May 2, 2025
1 parent 455110f commit c67fbd2
Show file tree
Hide file tree
Showing 12 changed files with 922 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@ msgstr "API Tier"

msgid "information.orcid_source.linked"
msgstr "Obtained ORCID {0} via authenticated OAuth flow"

msgid "information.orcid_source.identifier"
msgstr "ORCID Identifier"
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?php
/**
* COmanage Registry Orcid Source Collectors Controller
*
* Portions licensed to the University Corporation for Advanced Internet
* Development, Inc. ("UCAID") under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* UCAID licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @link https://www.internet2.edu/comanage COmanage Project
* @package registry-plugins
* @since COmanage Registry v5.2.0
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

declare(strict_types=1);

namespace OrcidSource\Controller;

use App\Controller\StandardEnrollerController;
use App\Lib\Enum\PetitionActionEnum;
use Cake\Datasource\EntityInterface;
use Cake\Event\EventInterface;
use Cake\Http\Response;
use Cake\ORM\TableRegistry;
use Cake\Routing\RouteBuilder;
use Cake\Routing\Router;
use OrcidSource\Lib\Enum\OrcidSourceScopeEnum;

class OrcidSourceCollectorsController extends StandardEnrollerController {
public $paginate = [
'order' => [
'OrcidSourceCollectors.id' => 'asc'
]
];

/**
* Callback run prior to the request render.
*
* @param EventInterface $event Cake Event
*
* @return Response|void
* @since COmanage Registry v5.2.0
*/

public function beforeRender(EventInterface $event) {
$link = $this->getPrimaryLink(true);

if(!empty($link->value)) {
$this->set('vv_bc_parent_obj', $this->OrcidSourceCollectors->EnrollmentFlowSteps->get($link->value));
$this->set('vv_bc_parent_displayfield', $this->OrcidSourceCollectors->EnrollmentFlowSteps->getDisplayField());
$this->set('vv_bc_parent_primarykey', $this->OrcidSourceCollectors->EnrollmentFlowSteps->getPrimaryKey());
}

return parent::beforeRender($event);
}

/**
* Dispatch an Enrollment Flow Step.
*
* @since COmanage Registry v5.2.0
* @param string $id Env Source Collector ID
*/

public function dispatch(string $id) {
$request = $this->getRequest();
$session = $request->getSession();
$username = $session->read('Auth.external.user');

$op = $this->requestParam('op');
$code = $this->getRequest()->getQuery('code') ?? null;
$petition = $this->getPetition();

$this->set('vv_op', $op);

$oricdSource = $this->OrcidSourceCollectors->get(
(int)$id,
[
'contain' => [
'ExternalIdentitySources' => ['OrcidSources' => ['Servers']]
]]
);

$ServerModel = $oricdSource->external_identity_source->orcid_source->server->plugin;
$PluginServers = $this->getTableLocator()->get($ServerModel);

$oauthServer = $this->Oauth2Servers->get($oricdSource->external_identity_source->orcid_source->server->id);

$this->set('vv_config', $oricdSource);
$this->set('controller', $this);


try {
// Let's authenticate first
$this->authenticate($id, $oricdSource, $code);

}
catch(\OverflowException $e) {
// The requested Source Key is already attached to an External Identity, so we throw
// an error now rather than wait until finalization

// Flag the Petition as a duplicate
$Petitions = TableRegistry::getTableLocator()->get("Petitions");
}
catch(\Exception $e) {
$this->Flash->error($e->getMessage());
}

// Fall through and let the form render

$this->render('/Standard/dispatch');
}


/**
* Authenticate using OAuth2 Authorization Code flow.
*
* This method handles the OAuth2 authentication process by:
* 1. Building callback URL for the OAuth2 redirect
* 2. Redirecting to authorization endpoint on first access
* 3. Exchanging authorization code for access token on callback
*
* @param string|int $id Orcid Source Collector ID
* @param EntityInterface $oscfg Configuration array containing OAuth2 settings and OrgIdentitySource details
* @param string|null $code Authorization code returned from OAuth2 server (optional)
* @return void
* @since COmanage Registry v5.2.0
*/
protected function authenticate(string|int $id, EntityInterface $oscfg, ?string $code): void
{
// We need a different callback URL than what the Oauth2Server config will
// use, since we're basically creating a runtime Authorization Code flow
// (while the main config uses a Client Credentials flow).

$callback = [
'plugin' => 'OrcidSource',
'controller' => 'OrcidSourcesCollectors',
'action' => 'dispatch',
$id,
'?' => ['osid' => $oscfg->id],
];

// Build the redirect URI
$redirectUri = Router::url($callback, true);

if (empty($code)) {
$scope = OrcidSourceScopeEnum::DEFAULT_SCOPE;
if (!empty($oscfg->scope_inherit)) {
$scope = $oscfg->scope_inherit;
}


// First time through, redirect to the "authorize" URL

$url = $oscfg->url . '/authorize?';
$url .= 'client_id=' . $oscfg->clientid;
$url .= '&response_type=code';
$url .= '&scope=' . str_replace(' ', '%20', $scope);
$url .= '&redirect_uri=' . urlencode($redirectUri);

$this->redirect($url);
}

// $response = $this->Oauth2Server->exchangeCode($cfg['Oauth2Server']['id'],
// $this->request->query['code'],
// $redirectUri,
// false);
}

/**
* Indicate whether this Controller will handle some or all authnz.
*
* @since COmanage Registry v5.2.0
* @param EventInterface $event Cake event, ie: from beforeFilter
* @return string "no", "open", "authz", or "yes"
*/

public function willHandleAuth(\Cake\Event\EventInterface $event): string {
$request = $this->getRequest();
$action = $request->getParam('action');

if($action == 'dispatch') {
// We need to perform special logic (vs StandardEnrollerController)
// to ensure that web server authentication is triggered.
// (This is the same logic as IdentifierCollectorsController.)
// XXX We could maybe move this into StandardEnrollerController with a flag like
// $this->alwaysAuthDispatch(true);

// To start, we trigger the parent logic. This will return
// notauth: Some error occurred, we don't want to override this
// authz: No token in use
// yes: Token validated

$auth = parent::willHandleAuth($event);

// The only status we need to override is 'yes', since we always want authentication
// to run in order to be able to grab $REMOTE_USER.

return ($auth == 'yes' ? 'authz' : $auth);
}

return parent::willHandleAuth($event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*
* @link https://www.internet2.edu/comanage COmanage Project
* @package registry-plugins
* @since COmanage Registry v5.1.0
* @since COmanage Registry v5.2.0
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

Expand Down Expand Up @@ -61,8 +61,4 @@ public function beforeRender(EventInterface $event) {

return parent::beforeRender($event);
}

public function callback() {
// dummy
}
}
Loading

0 comments on commit c67fbd2

Please sign in to comment.