This commit is contained in:
Roland Gruber 2020-01-11 17:29:05 +01:00
parent 286e447553
commit 691055b83e
3 changed files with 59 additions and 16 deletions

View File

@ -100,14 +100,15 @@ class WebauthnManager {
*
* @param string $dn DN
* @param bool $isSelfService is executed in self service
* @param array $extraExcludedKeys credentialIds that should be added to excluded keys
* @return PublicKeyCredentialCreationOptions registration object
*/
public function getRegistrationObject($dn, $isSelfService) {
public function getRegistrationObject($dn, $isSelfService, $extraExcludedKeys = array()) {
$rpEntity = $this->createRpEntry($isSelfService);
$userEntity = $this->getUserEntity($dn);
$challenge = $this->createChallenge();
$credentialParameters = $this->getCredentialParameters();
$excludedKeys = $this->getExcludedKeys($userEntity);
$excludedKeys = $this->getExcludedKeys($userEntity, $extraExcludedKeys);
$timeout = $this->getTimeout();
$registrationObject = new PublicKeyCredentialCreationOptions(
$rpEntity,
@ -161,6 +162,18 @@ class WebauthnManager {
return false;
}
/**
* Returns a public key credential loader.
*
* @return PublicKeyCredentialLoader public key credential loader
*/
public function createPublicKeyCredentialLoader() {
$decoder = $this->getCborDecoder();
$attestationSupportManager = $this->getAttestationSupportManager($decoder);
$attestationObjectLoader = $this->getAttestationObjectLoader($attestationSupportManager, $decoder);
return $this->getPublicKeyCredentialLoader($attestationObjectLoader, $decoder);
}
/**
* Returns the user entity for the registration.
*
@ -214,15 +227,19 @@ class WebauthnManager {
* Returns a list of all credential ids that are already registered.
*
* @param PublicKeyCredentialUserEntity $user user data
* @param array $extraExcludedKeys credentialIds that should be added to excluded keys
* @return PublicKeyCredentialDescriptor[] credential ids
*/
private function getExcludedKeys($user) {
private function getExcludedKeys($user, $extraExcludedKeys = array()) {
$keys = array();
$repository = $this->getDatabase();
$credentialSources = $repository->findAllForUserEntity($user);
foreach ($credentialSources as $credentialSource) {
$keys[] = new PublicKeyCredentialDescriptor(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $credentialSource->getPublicKeyCredentialId());
}
foreach ($extraExcludedKeys as $extraExcludedKey) {
$keys[] = new PublicKeyCredentialDescriptor(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $extraExcludedKey);
}
return $keys;
}

View File

@ -1620,15 +1620,18 @@ window.lam.webauthn.removeDevice = function(event) {
window.lam.webauthn.removeOwnDevice = function(event, isSelfService) {
event.preventDefault();
const element = jQuery(event.currentTarget);
const successCallback = function () {
const form = jQuery("#webauthnform");
jQuery('<input>').attr({
type: 'hidden',
name: 'removed',
value: 'true'
}).appendTo(form);
form.submit();
};
let successCallback = null;
if (!isSelfService) {
successCallback = function () {
const form = jQuery("#webauthnform");
jQuery('<input>').attr({
type: 'hidden',
name: 'removed',
value: 'true'
}).appendTo(form);
form.submit();
};
}
let action = 'webauthnOwnDevices';
if (isSelfService) {
action = action + '&selfservice=true&module=webauthn&scope=user';
@ -1706,21 +1709,44 @@ window.lam.webauthn.sendRemoveDeviceRequest = function(element, action, successC
* Registers a user's own webauthn device.
*
* @param event click event
* @param isSelfService runs in self service context
*/
window.lam.webauthn.registerOwnDevice = function(event) {
window.lam.webauthn.registerOwnDevice = function(event, isSelfService) {
event.preventDefault();
const element = jQuery(event.target);
const dn = element.data('dn');
const tokenValue = element.data('sec_token_value');
const tokenName = element.data('sec_token_name');
const publicKey = element.data('publickey');
const successCallback = function (publicKeyCredential) {
let successCallback = function (publicKeyCredential) {
const form = jQuery("#webauthnform");
const response = btoa(JSON.stringify(publicKeyCredential));
const registrationData = jQuery('#registrationData');
registrationData.val(response);
form.submit();
};
if (isSelfService) {
successCallback = function (publicKeyCredential) {
const data = {
action: 'register',
jsonInput: '',
sec_token: tokenValue,
dn: dn,
credential: btoa(JSON.stringify(publicKeyCredential))
};
jQuery.ajax({
url: '../misc/ajax.php?selfservice=true&module=webauthn&scope=user',
method: 'POST',
data: data
})
.done(function(jsonData) {
const resultDiv = jQuery('#webauthn_results');
resultDiv.html(jsonData.content);
})
.fail(function() {
console.log('Webauthn device registration failed');
});
};
}
const errorCallback = function (error) {
let errorDiv = jQuery('#generic-webauthn-error');
let buttonLabel = errorDiv.data('button');

View File

@ -88,7 +88,7 @@ $registrationJson = json_encode($registration);
$_SESSION['webauthn_registration'] = $registrationJson;
$registerButton->addDataAttribute('publickey', $registrationJson);
$registerButton->setIconClass('createButton');
$registerButton->setOnClick('window.lam.webauthn.registerOwnDevice(event);');
$registerButton->setOnClick('window.lam.webauthn.registerOwnDevice(event, false);');
$buttonGroup->addElement($registerButton);
$buttonGroup->addElement(new htmlSpacer('1rem', null));
$reloadButton = new htmlButton('reload', _('Reload'));