From 62522fe5aaa2971835c76e8e9b0d4280fee1db32 Mon Sep 17 00:00:00 2001
From: Arnab Dutta <32794267+duttarnab@users.noreply.github.com>
Date: Mon, 30 May 2022 11:34:28 +0530
Subject: [PATCH] feat: endpoint to get details of connected FIDO devices
registered to users #1465 (#1466)
* feat: need endpoint to get details of connected FIDO devices registered to users #1465
* feat: need endpoint to get details of connected FIDO devices registered to users #1465
---
.../io/jans/configapi/util/ApiConstants.java | 1 +
.../docs/jans-config-api-swagger.yaml | 105 +++++++++++++++++
.../plugins/admin-ui-plugin/pom.xml | 2 +-
jans-config-api/plugins/fido2-plugin/pom.xml | 5 +
.../src/main/assembly/assembly.xml | 11 ++
.../plugin/fido2/rest/ApiApplication.java | 1 +
.../fido2/rest/Fido2RegistrationResource.java | 38 +++++++
.../service/Fido2RegistrationService.java | 106 ++++++++++++++++++
.../plugin/fido2/util/Constants.java | 4 +-
9 files changed, 271 insertions(+), 2 deletions(-)
create mode 100644 jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java
create mode 100644 jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java
diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java b/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java
index 3b3e4dc4f9a..c0561e45b36 100644
--- a/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java
+++ b/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java
@@ -73,6 +73,7 @@ private ApiConstants() {}
public static final String USER = "/user";
public static final String ORG = "/org";
public static final String SERVER_STAT = "/server-stat";
+ public static final String USERNAME_PATH = "{username}";
public static final String LIMIT = "limit";
public static final String START_INDEX = "startIndex";
diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml
index 4c454384deb..d5e3c0b2f7d 100644
--- a/jans-config-api/docs/jans-config-api-swagger.yaml
+++ b/jans-config-api/docs/jans-config-api-swagger.yaml
@@ -162,6 +162,30 @@ paths:
security:
- oauth2: [https://jans.io/oauth/config/fido2.write]
parameters: []
+ /jans-config-api/fido2/registration/entries/{username}:
+ get:
+ summary: Get details of connected FIDO2 devices registered to user.
+ description: Get details of connected FIDO2 devices registered to user.
+ operationId: get-registration-entries-fido2
+ tags:
+ - Fido2 - Configuration
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ title: FIDO2 registered devices
+ description: List of all FIDO2 registered devices.
+ type: array
+ items:
+ $ref: '#/components/schemas/Fido2RegistrationEntry'
+ '401':
+ $ref: '#/components/responses/Unauthorized'
+ '500':
+ $ref: '#/components/responses/InternalServerError'
+ security:
+ - oauth2: [ https://jans.io/oauth/config/fido2.readonly ]
/jans-config-api/api/v1/attributes:
get:
summary: Gets a list of Gluu attributes.
@@ -5752,6 +5776,87 @@ components:
description: Fido2Configuration.
$ref: '#/components/schemas/Fido2Configuration'
+ Fido2RegistrationEntry:
+ type: object
+ description: Fido2 registration entry
+ properties:
+ publicKeyId:
+ description: Public key id
+ type: string
+ displayName:
+ description: Dislay name
+ type: string
+ counter:
+ description: counter
+ type: integer
+ deviceNotificationConf:
+ description: Device notification configuration
+ type: string
+ challangeHash:
+ description: Challange hash
+ type: string
+ registrationData:
+ description: Fido2 registration data.
+ $ref: '#/components/schemas/Fido2RegistrationData'
+ registrationStatus:
+ description: registration status
+ type: string
+ enum:
+ - pending
+ - registered
+ - compromised
+
+ Fido2RegistrationData:
+ type: object
+ description: Fido2 registration data.
+ properties:
+ username:
+ description: Username
+ type: string
+ domain:
+ description: Domain
+ type: string
+ userId:
+ description: user id
+ type: string
+ challenge:
+ description: challenge
+ type: string
+ attenstationRequest:
+ description: Attenstation request
+ type: string
+ attenstationResponse:
+ description: Attenstation response
+ type: string
+ uncompressedECPoint:
+ description: uncompressed EC point
+ type: string
+ publicKeyId:
+ description: public key id
+ type: string
+ type:
+ description: type
+ type: string
+ counter:
+ description: counter
+ type: integer
+ attestationType:
+ description: attestation type
+ type: string
+ signatureAlgorithm:
+ description: signature algorithm
+ type: integer
+ applicationId:
+ description: application id
+ type: string
+ status:
+ description: status
+ type: string
+ enum:
+ - pending
+ - registered
+ - compromised
+
Fido2Configuration:
type: object
description: Fido2 configuration properties.
diff --git a/jans-config-api/plugins/admin-ui-plugin/pom.xml b/jans-config-api/plugins/admin-ui-plugin/pom.xml
index 664846ef554..50875c66a94 100644
--- a/jans-config-api/plugins/admin-ui-plugin/pom.xml
+++ b/jans-config-api/plugins/admin-ui-plugin/pom.xml
@@ -21,7 +21,7 @@
io.jans
- jans-config-api-server
+ jans-config-api-shared
compile
diff --git a/jans-config-api/plugins/fido2-plugin/pom.xml b/jans-config-api/plugins/fido2-plugin/pom.xml
index f93382b377f..7390bbd721a 100644
--- a/jans-config-api/plugins/fido2-plugin/pom.xml
+++ b/jans-config-api/plugins/fido2-plugin/pom.xml
@@ -22,6 +22,11 @@
jans-config-api-shared
${jans.version}
+
+ io.jans
+ jans-fido2-model
+ ${jans.version}
+
io.jans
jans-config-api-server
diff --git a/jans-config-api/plugins/fido2-plugin/src/main/assembly/assembly.xml b/jans-config-api/plugins/fido2-plugin/src/main/assembly/assembly.xml
index 4a93c3a8515..986c9836a7f 100644
--- a/jans-config-api/plugins/fido2-plugin/src/main/assembly/assembly.xml
+++ b/jans-config-api/plugins/fido2-plugin/src/main/assembly/assembly.xml
@@ -7,6 +7,17 @@
jar
false
+
+
+ true
+ /
+ false
+
+ io.jans:jans-fido2-model
+
+ runtime
+
+
${project.build.directory}/classes
diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java
index cc868cbfe10..e1588c80b6c 100644
--- a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java
+++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java
@@ -13,6 +13,7 @@ public Set> getClasses() {
HashSet> classes = new HashSet<>();
classes.add(Fido2ConfigResource.class);
+ classes.add(Fido2RegistrationResource.class);
return classes;
}
diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java
new file mode 100644
index 00000000000..c41936eda43
--- /dev/null
+++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java
@@ -0,0 +1,38 @@
+package io.jans.configapi.plugin.fido2.rest;
+
+import io.jans.configapi.core.rest.BaseResource;
+import io.jans.configapi.core.rest.ProtectedApi;
+import io.jans.configapi.plugin.fido2.service.Fido2RegistrationService;
+import io.jans.configapi.plugin.fido2.util.Constants;
+import io.jans.configapi.util.ApiAccessConstants;
+import io.jans.configapi.util.ApiConstants;
+import io.jans.fido2.model.entry.Fido2RegistrationEntry;
+import jakarta.inject.Inject;
+import jakarta.validation.constraints.NotNull;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+@Path(Constants.REGISTRATION)
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public class Fido2RegistrationResource extends BaseResource {
+
+ @Inject
+ Logger logger;
+
+ @Inject
+ Fido2RegistrationService fido2RegistrationService;
+
+ @GET
+ @Path(Constants.ENTRIES + ApiConstants.USERNAME_PATH)
+ @ProtectedApi(scopes = {ApiAccessConstants.FIDO2_CONFIG_READ_ACCESS})
+ public Response findAllRegisteredByUsername(@PathParam("username") @NotNull String username) {
+ logger.debug("FIDO2 registration entries by username.");
+ List entries = fido2RegistrationService.findAllRegisteredByUsername(username);
+ return Response.ok(entries).build();
+ }
+}
diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java
new file mode 100644
index 00000000000..44b89fa2b4c
--- /dev/null
+++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java
@@ -0,0 +1,106 @@
+/*
+ * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
+ *
+ * Copyright (c) 2020, Janssen Project
+ */
+
+package io.jans.configapi.plugin.fido2.service;
+
+import io.jans.as.common.service.common.UserService;
+import io.jans.as.model.config.StaticConfiguration;
+import io.jans.fido2.model.entry.Fido2RegistrationEntry;
+import io.jans.fido2.model.entry.Fido2RegistrationStatus;
+import io.jans.orm.PersistenceEntryManager;
+import io.jans.orm.model.base.SimpleBranch;
+import io.jans.orm.search.filter.Filter;
+import io.jans.util.StringHelper;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Yuriy Movchan
+ * @version May 08, 2020
+ */
+@ApplicationScoped
+public class Fido2RegistrationService {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private StaticConfiguration staticConfiguration;
+
+ @Inject
+ private UserService userService;
+
+ @Inject
+ private PersistenceEntryManager persistenceEntryManager;
+
+ public List findAllByUsername(String username) {
+ String userInum = userService.getUserInum(username);
+ if (userInum == null) {
+ return Collections.emptyList();
+ }
+
+ String baseDn = getBaseDnForFido2RegistrationEntries(userInum);
+ if (persistenceEntryManager.hasBranchesSupport(baseDn)) {
+ if (!containsBranch(baseDn)) {
+ return Collections.emptyList();
+ }
+ }
+
+ Filter userFilter = Filter.createEqualityFilter("personInum", userInum);
+
+ List fido2RegistrationnEntries = persistenceEntryManager.findEntries(baseDn, Fido2RegistrationEntry.class, userFilter);
+
+ return fido2RegistrationnEntries;
+ }
+
+ public List findAllRegisteredByUsername(String username) {
+ String userInum = userService.getUserInum(username);
+ if (userInum == null) {
+ return Collections.emptyList();
+ }
+
+ String baseDn = getBaseDnForFido2RegistrationEntries(userInum);
+ if (persistenceEntryManager.hasBranchesSupport(baseDn)) {
+ if (!containsBranch(baseDn)) {
+ return Collections.emptyList();
+ }
+ }
+
+ Filter userInumFilter = Filter.createEqualityFilter("personInum", userInum);
+ Filter registeredFilter = Filter.createEqualityFilter("jansStatus", Fido2RegistrationStatus.registered.getValue());
+ Filter filter = Filter.createANDFilter(userInumFilter, registeredFilter);
+
+ List fido2RegistrationnEntries = persistenceEntryManager.findEntries(baseDn, Fido2RegistrationEntry.class, filter);
+
+ return fido2RegistrationnEntries;
+ }
+
+ public String getBaseDnForFido2RegistrationEntries(String userInum) {
+ final String userBaseDn = getDnForUser(userInum); // "ou=fido2_register,inum=1234,ou=people,o=jans"
+ if (StringHelper.isEmpty(userInum)) {
+ return userBaseDn;
+ }
+
+ return String.format("ou=fido2_register,%s", userBaseDn);
+ }
+
+ public String getDnForUser(String userInum) {
+ String peopleDn = staticConfiguration.getBaseDn().getPeople();
+ if (StringHelper.isEmpty(userInum)) {
+ return peopleDn;
+ }
+
+ return String.format("inum=%s,%s", userInum, peopleDn);
+ }
+
+ public boolean containsBranch(final String baseDn) {
+ return persistenceEntryManager.contains(baseDn, SimpleBranch.class);
+ }
+}
diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java
index a55d0418ec3..453657c14da 100644
--- a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java
+++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java
@@ -10,5 +10,7 @@ public class Constants {
private Constants() {}
- public static final String CONFIG = "/config";
+ public static final String CONFIG = "/config";
+ public static final String REGISTRATION = "/registration";
+ public static final String ENTRIES = "/entries";
}
\ No newline at end of file