From 23441205af19edc00362633b4706caa4dd2fb14f Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 27 Sep 2023 10:43:25 +0200 Subject: [PATCH 01/66] First commit. --- kura/distrib/config/kura.build.properties | 1 + kura/distrib/pom.xml | 7 + .../src/main/ant/build_equinox_distrib.xml | 17 +- .../META-INF/MANIFEST.MF | 27 ++ .../OSGI-INF/IdentityRestService.xml | 54 ++++ .../about.html | 36 +++ .../about_files/epl-v20.html | 301 ++++++++++++++++++ .../build.properties | 19 ++ .../pom.xml | 36 +++ .../provider/IdentityRestService.java | 169 ++++++++++ .../identity/provider/IdentityService.java | 210 ++++++++++++ .../rest/identity/provider/dto/UserDTO.java | 66 ++++ .../validator/PasswordStrengthValidators.java | 117 +++++++ .../validator/PredicateValidator.java | 36 +++ .../provider/validator/RegexValidator.java | 21 ++ .../provider/validator/Validator.java | 8 + .../provider/validator/ValidatorOptions.java | 70 ++++ 17 files changed, 1189 insertions(+), 6 deletions(-) create mode 100644 kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF create mode 100644 kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml create mode 100644 kura/org.eclipse.kura.rest.identity.provider/about.html create mode 100644 kura/org.eclipse.kura.rest.identity.provider/about_files/epl-v20.html create mode 100644 kura/org.eclipse.kura.rest.identity.provider/build.properties create mode 100644 kura/org.eclipse.kura.rest.identity.provider/pom.xml create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PasswordStrengthValidators.java create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/RegexValidator.java create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java diff --git a/kura/distrib/config/kura.build.properties b/kura/distrib/config/kura.build.properties index e0b642dea84..b83dbb0ce11 100644 --- a/kura/distrib/config/kura.build.properties +++ b/kura/distrib/config/kura.build.properties @@ -117,6 +117,7 @@ org.eclipse.kura.rest.command.provider.version=1.0.0-SNAPSHOT org.eclipse.kura.rest.packages.provider.version=1.0.0-SNAPSHOT org.eclipse.kura.rest.position.provider.version=1.0.0-SNAPSHOT org.eclipse.kura.rest.security.provider.version=1.0.0-SNAPSHOT +org.eclipse.kura.rest.identity.provider.version=1.0.0-SNAPSHOT org.eclipse.kura.rest.service.listing.provider.version=1.0.0-SNAPSHOT org.eclipse.kura.rest.system.provider.version=1.0.0-SNAPSHOT org.eclipse.kura.request.handler.jaxrs.version=1.3.0-SNAPSHOT diff --git a/kura/distrib/pom.xml b/kura/distrib/pom.xml index cb1a0a61e16..cd1b576f6c3 100644 --- a/kura/distrib/pom.xml +++ b/kura/distrib/pom.xml @@ -623,6 +623,11 @@ org.eclipse.kura.rest.security.provider ${org.eclipse.kura.rest.security.provider.version} + + org.eclipse.kura + org.eclipse.kura.rest.identity.provider + ${org.eclipse.kura.rest.identity.provider.version} + org.eclipse.kura org.eclipse.kura.rest.service.listing.provider @@ -827,6 +832,7 @@ + @@ -2543,6 +2549,7 @@ + diff --git a/kura/distrib/src/main/ant/build_equinox_distrib.xml b/kura/distrib/src/main/ant/build_equinox_distrib.xml index 4a0980c14e5..67d4d3bd205 100644 --- a/kura/distrib/src/main/ant/build_equinox_distrib.xml +++ b/kura/distrib/src/main/ant/build_equinox_distrib.xml @@ -1320,9 +1320,11 @@ fi]]> - + value=", reference:file:${kura.install.dir}/${kura.symlink}/${plugins.folder}/org.eclipse.kura.rest.security.provider_${org.eclipse.kura.rest.security.provider.version}.jar@4:start" /> + + prefix="${build.output.name}/${plugins.folder}" /> + prefix="${build.output.name}/${plugins.folder}" /> + file="${project.build.directory}/plugins/org.eclipse.kura.rest.identity.provider_${org.eclipse.kura.rest.identity.provider.version}.jar" + prefix="${build.output.name}/${plugins.folder}" /> + diff --git a/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF b/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..295b8ba55b5 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF @@ -0,0 +1,27 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Identity REST Service +Bundle-SymbolicName: org.eclipse.kura.rest.identity.provider;singleton:=true +Bundle-Version: 1.0.0.qualifier +Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" +Bundle-ClassPath: . +Bundle-ActivationPolicy: lazy +Service-Component: OSGI-INF/*.xml +Import-Package: javax.annotation.security;version="1.2.0", + javax.ws.rs;version="2.0.1", + javax.ws.rs.core;version="2.0.1", + org.apache.commons.io;version="2.4.0", + org.eclipse.kura;version="[1.3,2.0)", + org.eclipse.kura.cloudconnection.request;version="[1.0,2.0)", + org.eclipse.kura.configuration;version="[1.2,2.0)", + org.eclipse.kura.crypto;version="[1.3,2.0)", + org.eclipse.kura.request.handler.jaxrs;version="[1.0,2.0)", + org.eclipse.kura.request.handler.jaxrs.annotation;version="[1.0,2.0)", + org.eclipse.kura.rest.configuration.api;version="[1.0,2.0)", + org.eclipse.kura.util.configuration;version="[1.0,2.0)", + org.eclipse.kura.util.useradmin;version="[1.0,2.0)", + org.osgi.framework;version="1.8.0", + org.osgi.service.cm;version="1.6.0", + org.osgi.service.component;version="[1.3,2.0)", + org.osgi.service.useradmin;version="1.1.0";resolution:=optional, + org.slf4j;version="1.7.25" diff --git a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml new file mode 100644 index 00000000000..3590e436fee --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml @@ -0,0 +1,54 @@ + + + + + + + + + + /> + + + + + + + + + + + + diff --git a/kura/org.eclipse.kura.rest.identity.provider/about.html b/kura/org.eclipse.kura.rest.identity.provider/about.html new file mode 100644 index 00000000000..ec5809fefb9 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/about.html @@ -0,0 +1,36 @@ + + + + + About + + +

About This Content

+ +

November 30, 2017

+

License

+ +

+ The Eclipse Foundation makes available all content in this plug-in + ("Content"). Unless otherwise indicated below, the Content + is provided to you under the terms and conditions of the Eclipse + Public License Version 2.0 ("EPL"). A copy of the EPL is + available at http://www.eclipse.org/legal/epl-2.0. + For purposes of the EPL, "Program" will mean the Content. +

+ +

+ If you did not receive this Content directly from the Eclipse + Foundation, the Content is being redistributed by another party + ("Redistributor") and different terms and conditions may + apply to your use of any object code in the Content. Check the + Redistributor's license that was provided with the Content. If no such + license exists, contact the Redistributor. Unless otherwise indicated + below, the terms and conditions of the EPL still apply to any source + code in the Content and such source code may be obtained at http://www.eclipse.org. +

+ + + \ No newline at end of file diff --git a/kura/org.eclipse.kura.rest.identity.provider/about_files/epl-v20.html b/kura/org.eclipse.kura.rest.identity.provider/about_files/epl-v20.html new file mode 100644 index 00000000000..cc699dea65b --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/about_files/epl-v20.html @@ -0,0 +1,301 @@ + + + + + + Eclipse Public License - Version 2.0 + + + +

Eclipse Public License - v 2.0

+

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE (“AGREEMENT”). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. +

+

1. DEFINITIONS

+

“Contribution” means:

+
    +
  • a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and +
  • +
  • + b) in the case of each subsequent Contributor: +
      +
    • i) changes to the Program, and
    • +
    • ii) additions to the Program;
    • +
    + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + “originates” from a Contributor if it was added to the Program by such + Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. +
  • +
+

“Contributor” means any person or entity that Distributes the Program.

+

“Licensed Patents” mean patent claims licensable by a Contributor which + are necessarily infringed by the use or sale of its Contribution alone + or when combined with the Program. +

+

“Program” means the Contributions Distributed in accordance with this + Agreement. +

+

“Recipient” means anyone who receives the Program under this Agreement + or any Secondary License (as applicable), including Contributors. +

+

“Derivative Works” shall mean any work, whether in Source Code or other + form, that is based on (or derived from) the Program and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. +

+

“Modified Works” shall mean any work in Source Code or other form that + results from an addition to, deletion from, or modification of the + contents of the Program, including, for purposes of clarity any new file + in Source Code form that contains any contents of the Program. Modified + Works shall not include works that contain only declarations, interfaces, + types, classes, structures, or files of the Program solely in each case + in order to link to, bind by name, or subclass the Program or Modified + Works thereof. +

+

“Distribute” means the acts of a) distributing or b) making available + in any manner that enables the transfer of a copy. +

+

“Source Code” means the form of a Program preferred for making + modifications, including but not limited to software source code, + documentation source, and configuration files. +

+

“Secondary License” means either the GNU General Public License, + Version 2.0, or any later versions of that license, including any + exceptions or additional permissions as identified by the initial + Contributor. +

+

2. GRANT OF RIGHTS

+
    +
  • a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. +
  • +
  • b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, + at the time the Contribution is added by the Contributor, such + addition of the Contribution causes such combination to be covered + by the Licensed Patents. The patent license shall not apply to any + other combinations which include the Contribution. No hardware per + se is licensed hereunder. +
  • +
  • c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the rights + and licenses granted hereunder, each Recipient hereby assumes sole + responsibility to secure any other intellectual property rights needed, + if any. For example, if a third party patent license is required to + allow Recipient to Distribute the Program, it is Recipient's + responsibility to acquire that license before distributing the Program. +
  • +
  • d) Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright + license set forth in this Agreement. +
  • +
  • e) Notwithstanding the terms of any Secondary License, no Contributor + makes additional grants to any Recipient (other than those set forth + in this Agreement) as a result of such Recipient's receipt of the + Program under the terms of a Secondary License (if permitted under + the terms of Section 3). +
  • +
+

3. REQUIREMENTS

+

3.1 If a Contributor Distributes the Program in any form, then:

+
    +
  • a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and +
  • +
  • + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: +
      +
    • i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including warranties + or conditions of title and non-infringement, and implied warranties + or conditions of merchantability and fitness for a particular purpose; +
    • +
    • ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, incidental + and consequential damages, such as lost profits; +
    • +
    • iii) does not attempt to limit or alter the recipients' rights in the + Source Code under section 3.2; and +
    • +
    • iv) requires any subsequent distribution of the Program by any party + to be under a license that satisfies the requirements of this section 3. +
    • +
    +
  • +
+

3.2 When the Program is Distributed as Source Code:

+
    +
  • a) it must be made available under this Agreement, or if the Program (i) + is combined with other material in a separate file or files made available + under a Secondary License, and (ii) the initial Contributor attached to + the Source Code the notice described in Exhibit A of this Agreement, + then the Program may be made available under the terms of such + Secondary Licenses, and +
  • +
  • b) a copy of this Agreement must be included with each copy of the Program.
  • +
+

3.3 Contributors may not remove or alter any copyright, patent, trademark, + attribution notices, disclaimers of warranty, or limitations of liability + (‘notices’) contained within the Program from any copy of the Program which + they Distribute, provided that Contributors may add their own appropriate + notices. +

+

4. COMMERCIAL DISTRIBUTION

+

Commercial distributors of software may accept certain responsibilities + with respect to end users, business partners and the like. While this + license is intended to facilitate the commercial use of the Program, the + Contributor who includes the Program in a commercial product offering should + do so in a manner which does not create potential liability for other + Contributors. Therefore, if a Contributor includes the Program in a + commercial product offering, such Contributor (“Commercial Contributor”) + hereby agrees to defend and indemnify every other Contributor + (“Indemnified Contributor”) against any losses, damages and costs + (collectively “Losses”) arising from claims, lawsuits and other legal actions + brought by a third party against the Indemnified Contributor to the extent + caused by the acts or omissions of such Commercial Contributor in connection + with its distribution of the Program in a commercial product offering. + The obligations in this section do not apply to any claims or Losses relating + to any actual or alleged intellectual property infringement. In order to + qualify, an Indemnified Contributor must: a) promptly notify the + Commercial Contributor in writing of such claim, and b) allow the Commercial + Contributor to control, and cooperate with the Commercial Contributor in, + the defense and any related settlement negotiations. The Indemnified + Contributor may participate in any such claim at its own expense. +

+

For example, a Contributor might include the Program + in a commercial product offering, Product X. That Contributor is then a + Commercial Contributor. If that Commercial Contributor then makes performance + claims, or offers warranties related to Product X, those performance claims + and warranties are such Commercial Contributor's responsibility alone. + Under this section, the Commercial Contributor would have to defend claims + against the other Contributors related to those performance claims and + warranties, and if a court requires any other Contributor to pay any damages + as a result, the Commercial Contributor must pay those damages. +

+

5. NO WARRANTY

+

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED + BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN “AS IS” BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, + WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + solely responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to the + risks and costs of program errors, compliance with applicable laws, damage + to or loss of data, programs or equipment, and unavailability or + interruption of operations. +

+

6. DISCLAIMER OF LIABILITY

+

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED + BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY + LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS + GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +

+

7. GENERAL

+

If any provision of this Agreement is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of the + remainder of the terms of this Agreement, and without further action by the + parties hereto, such provision shall be reformed to the minimum extent + necessary to make such provision valid and enforceable. +

+

If Recipient institutes patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Program itself + (excluding combinations of the Program with other software or hardware) + infringes such Recipient's patent(s), then such Recipient's rights granted + under Section 2(b) shall terminate as of the date such litigation is filed. +

+

All Recipient's rights under this Agreement shall terminate if it fails to + comply with any of the material terms or conditions of this Agreement and + does not cure such failure in a reasonable period of time after becoming + aware of such noncompliance. If all Recipient's rights under this Agreement + terminate, Recipient agrees to cease use and distribution of the Program + as soon as reasonably practicable. However, Recipient's obligations under + this Agreement and any licenses granted by Recipient relating to the + Program shall continue and survive. +

+

Everyone is permitted to copy and distribute copies of this Agreement, + but in order to avoid inconsistency the Agreement is copyrighted and may + only be modified in the following manner. The Agreement Steward reserves + the right to publish new versions (including revisions) of this Agreement + from time to time. No one other than the Agreement Steward has the right + to modify this Agreement. The Eclipse Foundation is the initial Agreement + Steward. The Eclipse Foundation may assign the responsibility to serve as + the Agreement Steward to a suitable separate entity. Each new version of + the Agreement will be given a distinguishing version number. The Program + (including Contributions) may always be Distributed subject to the version + of the Agreement under which it was received. In addition, after a new + version of the Agreement is published, Contributor may elect to Distribute + the Program (including its Contributions) under the new version. +

+

Except as expressly stated in Sections 2(a) and 2(b) above, Recipient + receives no rights or licenses to the intellectual property of any + Contributor under this Agreement, whether expressly, by implication, + estoppel or otherwise. All rights in the Program not expressly granted + under this Agreement are reserved. Nothing in this Agreement is intended + to be enforceable by any entity that is not a Contributor or Recipient. + No third-party beneficiary rights are created under this Agreement. +

+

Exhibit A – Form of Secondary Licenses Notice

+

“This Source Code may also be made available under the following + Secondary Licenses when the conditions for such availability set forth + in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), + version(s), and exceptions or additional permissions here}.” +

+
+

Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. +

+

If it is not possible or desirable to put the notice in a particular file, + then You may include the notice in a location (such as a LICENSE file in a + relevant directory) where a recipient would be likely to look for + such a notice. +

+

You may add additional accurate notices of copyright ownership.

+
+ + \ No newline at end of file diff --git a/kura/org.eclipse.kura.rest.identity.provider/build.properties b/kura/org.eclipse.kura.rest.identity.provider/build.properties new file mode 100644 index 00000000000..61baba2a407 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/build.properties @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Eurotech and/or its affiliates and others +# +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Eurotech +# +output.. = target/classes +bin.includes = .,\ + META-INF/,\ + OSGI-INF/,\ + about.html,\ + about_files/ +source.. = src/main/java/ diff --git a/kura/org.eclipse.kura.rest.identity.provider/pom.xml b/kura/org.eclipse.kura.rest.identity.provider/pom.xml new file mode 100644 index 00000000000..0db7f81734d --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/pom.xml @@ -0,0 +1,36 @@ + + + + 4.0.0 + + + org.eclipse.kura + kura + 5.4.0-SNAPSHOT + + + + ${project.basedir}/.. + + ${project.basedir}/../test/*/target/site/jacoco-aggregate/jacoco.xml + + + org.eclipse.kura.rest.identity.provider + eclipse-plugin + 1.0.0-SNAPSHOT + + diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java new file mode 100644 index 00000000000..ee10c016ddc --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + ******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider; + +import java.util.Set; + +import javax.annotation.security.RolesAllowed; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.kura.KuraException; +import org.eclipse.kura.cloudconnection.request.RequestHandler; +import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; +import org.eclipse.kura.configuration.ConfigurationService; +import org.eclipse.kura.crypto.CryptoService; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; +import org.eclipse.kura.request.handler.jaxrs.DefaultExceptionHandler; +import org.eclipse.kura.request.handler.jaxrs.JaxRsRequestHandlerProxy; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.UserAdmin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("identity/v1") +public class IdentityRestService { + + private static final Logger logger = LoggerFactory.getLogger(IdentityRestService.class); + private static final String DEBUG_MESSSAGE = "Processing request for method '{}'"; + + private static final String MQTT_APP_ID = "ID-V1"; + private static final String REST_ROLE_NAME = "identity"; + private static final String KURA_PERMISSION_REST_ROLE = "kura.permission.rest." + REST_ROLE_NAME; + + private final RequestHandler requestHandler = new JaxRsRequestHandlerProxy(this); + + private CryptoService cryptoService; + + private UserAdmin userAdmin; + private IdentityService identityService; + private ConfigurationService configurationService; + + public void bindCryptoService(CryptoService cryptoService) { + this.cryptoService = cryptoService; + } + + public void bindConfigurationService(ConfigurationService configurationService) { + this.configurationService = configurationService; + } + + public void bindUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + this.userAdmin.createRole(KURA_PERMISSION_REST_ROLE, Role.GROUP); + } + + public void bindRequestHandlerRegistry(RequestHandlerRegistry registry) { + try { + registry.registerRequestHandler(MQTT_APP_ID, this.requestHandler); + } catch (final Exception e) { + logger.warn("Failed to register {} request handler", MQTT_APP_ID, e); + } + } + + public void unbindRequestHandlerRegistry(RequestHandlerRegistry registry) { + try { + registry.unregister(MQTT_APP_ID); + } catch (final Exception e) { + logger.warn("Failed to unregister {} request handler", MQTT_APP_ID, e); + } + } + + public void activate() { + this.identityService = new IdentityService(this.cryptoService, this.userAdmin, this.configurationService); + } + + @POST + @RolesAllowed(REST_ROLE_NAME) + @Path("/users") + @Consumes(MediaType.APPLICATION_JSON) + public Response createUser(final UserDTO userName) { + try { + logger.debug(DEBUG_MESSSAGE, "createUser"); + this.identityService.createUser(userName.getUserName()); + } catch (Exception e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + + return Response.ok().build(); + } + + @DELETE + @RolesAllowed(REST_ROLE_NAME) + @Path("/users/{userName}") + public Response deleteUser(@PathParam("userName") final String userName) { + try { + logger.debug(DEBUG_MESSSAGE, "deleteUser"); + this.identityService.deleteUser(userName); + } catch (Exception e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + + return Response.ok().build(); + } + + @GET + @RolesAllowed(REST_ROLE_NAME) + @Path("/defined-permissions") + @Produces(MediaType.APPLICATION_JSON) + public Set getDefinedPermissions() { + try { + logger.debug(DEBUG_MESSSAGE, "getDefinedPermissions"); + return this.identityService.getDefinedPermissions(); + } catch (Exception e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + } + + @GET + @RolesAllowed(REST_ROLE_NAME) + @Path("/users/configs") + @Produces(MediaType.APPLICATION_JSON) + public Set getUserConfig() { + try { + logger.debug(DEBUG_MESSSAGE, "getUserConfig"); + return this.identityService.getUserConfig(); + } catch (Exception e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + } + + @POST + @RolesAllowed(REST_ROLE_NAME) + @Path("/users/configs") + @Consumes(MediaType.APPLICATION_JSON) + public Response setUserConfig(Set userConfig) { + try { + logger.debug(DEBUG_MESSSAGE, "setUserConfig"); + for (final UserDTO config : userConfig) { + final String newPassword = config.getPassword(); + + if (newPassword != null) { + this.identityService.validateUserPassword(newPassword); + } + } + this.identityService.setUserConfig(userConfig); + } catch (KuraException e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + + return Response.ok().build(); + } + +} diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java new file mode 100644 index 00000000000..9b19469e820 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import org.eclipse.kura.KuraErrorCode; +import org.eclipse.kura.KuraException; +import org.eclipse.kura.configuration.ComponentConfiguration; +import org.eclipse.kura.configuration.ConfigurationService; +import org.eclipse.kura.crypto.CryptoService; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; +import org.eclipse.kura.internal.rest.identity.provider.validator.PasswordStrengthValidators; +import org.eclipse.kura.internal.rest.identity.provider.validator.Validator; +import org.eclipse.kura.internal.rest.identity.provider.validator.ValidatorOptions; +import org.eclipse.kura.util.useradmin.UserAdminHelper; +import org.eclipse.kura.util.useradmin.UserAdminHelper.FallibleConsumer; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +@SuppressWarnings("restriction") +public class IdentityService { + + private static final String KURA_WEB_CONSOLE_SERVICE_PID = "org.eclipse.kura.web.Console"; + private static final String PERMISSION_ROLE_NAME_PREFIX = "kura.permission."; + private static final String USER_ROLE_NAME_PREFIX = "kura.user."; + + private static final String PASSWORD_PROPERTY = "kura.password"; + private static final String KURA_NEED_PASSWORD_CHANGE_PROPERTY = "kura.need.password.change"; + private static final String KURA_NEED_PASSWORD_CHANGE = "kura.need.password.change"; + + private UserAdminHelper userAdminHelper; + private ConfigurationService configurationService; + private CryptoService cryptoService; + + public IdentityService(CryptoService cryptoService, UserAdmin userAdmin, + ConfigurationService configurationService) { + + this.configurationService = configurationService; + this.cryptoService = cryptoService; + + this.userAdminHelper = new UserAdminHelper(userAdmin, cryptoService); + } + + public void createUser(String userName) { + this.userAdminHelper.createUser(userName); + } + + public void deleteUser(String userName) { + this.userAdminHelper.deleteUser(userName); + } + + public Set getDefinedPermissions() { + return this.userAdminHelper.getDefinedPermissions(); + } + + public Set getUserConfig() { + final Map result = new HashMap<>(); + + this.userAdminHelper.foreachUser((name, user) -> { + + final UserDTO userData = initUserConfig(user); + + result.put(user.getName(), userData); + }); + + fillPermissions(result); + + return new HashSet<>(result.values()); + } + + private UserDTO initUserConfig(final User user) { + + final boolean isPasswordEnabled = user.getCredentials().get(PASSWORD_PROPERTY) instanceof String; + final boolean isPasswordChangeRequired = Objects.equals("true", + user.getProperties().get(KURA_NEED_PASSWORD_CHANGE_PROPERTY)); + + return new UserDTO(getBaseName(user), new HashSet<>(), isPasswordEnabled, isPasswordChangeRequired); + } + + private static boolean isKuraUser(final Role role) { + return role.getName().startsWith(USER_ROLE_NAME_PREFIX); + } + + private static boolean isKuraPermission(final Role role) { + return role.getName().startsWith(PERMISSION_ROLE_NAME_PREFIX); + } + + private static String getBaseName(final Role role) { + final String name = role.getName(); + + if (isKuraUser(role)) { + return name.substring(USER_ROLE_NAME_PREFIX.length()); + } else if (isKuraPermission(role)) { + return name.substring(PERMISSION_ROLE_NAME_PREFIX.length()); + } else { + throw new IllegalArgumentException("not a Kura role"); + } + } + + private void fillPermissions(final Map userData) { + this.userAdminHelper.foreachPermission((permission, group) -> + + forEach(group.getMembers(), member -> { + final UserDTO data = userData.get(member.getName()); + + if (data != null) { + data.getPermissions().add(permission); + } + })); + } + + private static void forEach(final T[] items, final FallibleConsumer consumer) + throws E { + if (items != null) { + for (final T item : items) { + consumer.accept(item); + } + } + } + + public void setUserConfig(Set userData) throws KuraException { + this.userAdminHelper.foreachUser((name, user) -> { + if (userData.stream().noneMatch(data -> data.getUserName().equals(name))) { + deleteUser(name); + } + }); + + this.userAdminHelper.foreachPermission((permissionName, permissionGroup) -> { + for (final UserDTO data : userData) { + + final User user = this.userAdminHelper.getOrCreateUser(data.getUserName()); + + if (data.getPermissions().contains(permissionName)) { + permissionGroup.addMember(user); + } else { + permissionGroup.removeMember(user); + } + } + }); + + for (final UserDTO config : userData) { + final User user = this.userAdminHelper.getOrCreateUser(config.getUserName()); + + final Dictionary credentials = user.getCredentials(); + + if (config.isPasswordAuthEnabled()) { + final String password = config.getPassword(); + + if (password != null) { + try { + credentials.put(PASSWORD_PROPERTY, this.cryptoService.sha256Hash(password)); + } catch (final Exception e) { + throw new KuraException(KuraErrorCode.SERVICE_UNAVAILABLE, e); + } + } + } else { + credentials.remove(PASSWORD_PROPERTY); + } + + final Dictionary properties = user.getProperties(); + + if (config.isPasswordChangeNeeded()) { + properties.put(KURA_NEED_PASSWORD_CHANGE, "true"); + } else { + properties.remove(KURA_NEED_PASSWORD_CHANGE); + } + } + + } + + public void validateUserPassword(String password) throws KuraException { + + ComponentConfiguration consoleConfig = this.configurationService + .getComponentConfiguration(KURA_WEB_CONSOLE_SERVICE_PID); + + ValidatorOptions validatorOptions = new ValidatorOptions(consoleConfig.getConfigurationProperties()); + + final List> validators = PasswordStrengthValidators.fromConfig(validatorOptions); + + final List errors = new ArrayList<>(); + + for (final Validator validator : validators) { + validator.validate(password, errors::add); + } + + if (!errors.isEmpty()) { + throw new KuraException(KuraErrorCode.BAD_REQUEST, "password strenght requirements not satisfied", errors); + } + } + +} diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java new file mode 100644 index 00000000000..df1b5ae213e --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.dto; + +import java.util.Set; + +public class UserDTO { + + private final String userName; + private final boolean passwordAuthEnabled; + private final boolean passwordChangeNeeded; + private final Set permissions; + private String password; + + public UserDTO(final String userName, final Set permissions, final boolean passwordAuthEnabled, + final boolean passwordChangeNeeded, final String password) { + + this.userName = userName; + this.passwordAuthEnabled = passwordAuthEnabled; + this.passwordChangeNeeded = passwordChangeNeeded; + this.permissions = permissions; + this.password = password; + } + + public UserDTO(final String userName, final Set permissions, final boolean passwordAuthEnabled, + final boolean passwordChangeNeeded) { + + this(userName, permissions, passwordAuthEnabled, passwordChangeNeeded, null); + + } + + public String getUserName() { + return userName; + } + + public boolean isPasswordAuthEnabled() { + return passwordAuthEnabled; + } + + public boolean isPasswordChangeNeeded() { + return passwordChangeNeeded; + } + + public Set getPermissions() { + return permissions; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PasswordStrengthValidators.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PasswordStrengthValidators.java new file mode 100644 index 00000000000..a43c6371f90 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PasswordStrengthValidators.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2020, 2021 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.validator; + +import java.util.ArrayList; +import java.util.List; + +public class PasswordStrengthValidators { + + private static final String CONTAINS_DIGITS = ".*\\d.*"; + private static final String CONTAINS_NOT_ALPHANUMERIC = ".*[^a-zA-Z0-9].*"; + private static final String LOWERCASE = ".*[a-z].*"; + private static final String UPPERCASE = ".*[A-Z].*"; + + private PasswordStrengthValidators() { + } + + public static List> fromConfig(final ValidatorOptions userOptions) { + return fromConfig(userOptions, new DefaultMessages()); + } + + public static List> fromConfig(final ValidatorOptions userOptions, final Messages messages) { + final List> result = new ArrayList<>(); + + final int minPasswordLength = userOptions.getPasswordMinimumLength(); + + if (minPasswordLength > 0) { + result.add(passwordLengthValidator(minPasswordLength, messages)); + } + + if (userOptions.getPasswordRequireDigits()) { + result.add(containsDigitsValidator(messages)); + } + + if (userOptions.getPasswordRequireBothCases()) { + result.add(containsBothCases(messages)); + } + + if (userOptions.getPasswordRequireSpecialChars()) { + result.add(containsSpecialChars(messages)); + } + + return result; + } + + private static Validator passwordLengthValidator(final int minPasswordLength, final Messages messages) { + return new PredicateValidator(v -> { + final int passwordLength = v == null ? 0 : v.length(); + return passwordLength >= minPasswordLength; + }, messages.pwdStrengthMinLength(minPasswordLength)); + } + + private static Validator containsDigitsValidator(final Messages messages) { + return new RegexValidator(CONTAINS_DIGITS, messages.pwdStrengthDigitsRequired()) { + }; + } + + private static Validator containsSpecialChars(final Messages messages) { + return new RegexValidator(CONTAINS_NOT_ALPHANUMERIC, messages.pwdStrengthNonAlphanumericRequired()) { + }; + } + + private static Validator containsBothCases(final Messages messages) { + final RegexValidator containsLowercase = new RegexValidator(LOWERCASE, messages.pwdStrengthBothCasesRequired()); + final RegexValidator containsUppercase = new RegexValidator(UPPERCASE, messages.pwdStrengthBothCasesRequired()); + + return (v, c) -> { + containsLowercase.validate(v, c); + containsUppercase.validate(v, c); + }; + } + + public interface Messages { + + public String pwdStrengthDigitsRequired(); + + public String pwdStrengthNonAlphanumericRequired(); + + public String pwdStrengthBothCasesRequired(); + + public String pwdStrengthMinLength(final int value); + } + + private static class DefaultMessages implements Messages { + + @Override + public String pwdStrengthDigitsRequired() { + return "Password must contain at least one digit"; + } + + @Override + public String pwdStrengthNonAlphanumericRequired() { + return "Password must contain at least one non alphanumeric character"; + } + + @Override + public String pwdStrengthBothCasesRequired() { + return "Password must contain both uppercase and lowercase characters"; + } + + @Override + public String pwdStrengthMinLength(final int value) { + return "Password length must be at least " + value + " characters"; + } + } + +} diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java new file mode 100644 index 00000000000..33b57e2c4b4 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2019, 2021 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.validator; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class PredicateValidator implements Validator { + + private final Predicate predicate; + private final String message; + + public PredicateValidator(final Predicate predicate, final String message) { + this.predicate = predicate; + this.message = message; + } + + @Override + public void validate(final String value, final Consumer errorMessageConsumer) { + + if (!this.predicate.test(value)) { + errorMessageConsumer.accept(this.message); + } + } + +} \ No newline at end of file diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/RegexValidator.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/RegexValidator.java new file mode 100644 index 00000000000..04eaef0175f --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/RegexValidator.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2019, 2021 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.validator; + +public class RegexValidator extends PredicateValidator { + + public RegexValidator(final String pattern, final String message) { + super(v -> v.matches(pattern), message); + } + +} diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java new file mode 100644 index 00000000000..64571fc62ad --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java @@ -0,0 +1,8 @@ +package org.eclipse.kura.internal.rest.identity.provider.validator; + +import java.util.function.Consumer; + +public interface Validator { + + void validate(T value, Consumer errorMessageConsumer); +} diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java new file mode 100644 index 00000000000..5c898ae1b84 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.validator; + +import java.util.Map; + +import org.eclipse.kura.util.configuration.Property; + +public class ValidatorOptions { + + private int passwordMinimumLength = 8; + private boolean passwordRequireDigits = false; + private boolean passwordRequireBothCases = false; + private boolean passwordRequireSpecialChars = false; + + private static final String NEW_PASSW_MIN_LENGTH_PROP = "new.password.min.length"; + private static final String NEW_PASSW_REQUIRE_DIGITS = "new.password.require.digits"; + private static final String NEW_PASSW_REQUIRE_SPECIAL_CHARS = "new.password.require.special.characters"; + private static final String NEW_PASSW_REQUIRE_BOTH_CASES = "new.password.require.both.cases"; + + private final Property newPasswMinLenghthProperty = new Property<>(NEW_PASSW_MIN_LENGTH_PROP, 8); + private final Property newPassRequireDigits = new Property<>(NEW_PASSW_REQUIRE_DIGITS, false); + private final Property newPassRequireSpecialChars = new Property<>(NEW_PASSW_REQUIRE_SPECIAL_CHARS, false); + private final Property newPassRequireBothCases = new Property<>(NEW_PASSW_REQUIRE_BOTH_CASES, false); + + public ValidatorOptions(int passwordMinimumLength, boolean passwordRequireDigits, boolean passwordRequireBothCases, + boolean passwordRequireSpecialChars) { + + this.passwordMinimumLength = passwordMinimumLength; + this.passwordRequireDigits = passwordRequireDigits; + this.passwordRequireSpecialChars = passwordRequireSpecialChars; + this.passwordRequireBothCases = passwordRequireBothCases; + } + + public ValidatorOptions(Map configurationProperties) { + if (configurationProperties != null) { + this.passwordMinimumLength = newPasswMinLenghthProperty.get(configurationProperties); + this.passwordRequireDigits = newPassRequireDigits.get(configurationProperties); + this.passwordRequireSpecialChars = newPassRequireSpecialChars.get(configurationProperties); + this.passwordRequireBothCases = newPassRequireBothCases.get(configurationProperties); + } + } + + public int getPasswordMinimumLength() { + return this.passwordMinimumLength; + } + + public boolean getPasswordRequireDigits() { + return this.passwordRequireDigits; + } + + public boolean getPasswordRequireBothCases() { + return this.passwordRequireBothCases; + } + + public boolean getPasswordRequireSpecialChars() { + return this.passwordRequireSpecialChars; + } + +} From df726c840895b94e233524ea29cae2089ee2a430 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 2 Oct 2023 11:25:06 +0200 Subject: [PATCH 02/66] Some fixes and tests. --- .../META-INF/MANIFEST.MF | 4 +- .../provider/IdentityRestService.java | 10 +- .../identity/provider/IdentityService.java | 2 +- .../META-INF/MANIFEST.MF | 27 +++ .../build.properties | 16 ++ .../pom.xml | 71 ++++++ .../provider/test/IdentityEndpointsTest.java | 216 ++++++++++++++++++ .../main/resources/getUserConfigResponse.json | 20 ++ .../provider/test/IdentityServiceTest.java | 170 ++++++++++++++ kura/test/pom.xml | 1 + 10 files changed, 534 insertions(+), 3 deletions(-) create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/build.properties create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/pom.xml create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java diff --git a/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF b/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF index 295b8ba55b5..806f565a7e8 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF +++ b/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF @@ -7,7 +7,9 @@ Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" Bundle-ClassPath: . Bundle-ActivationPolicy: lazy Service-Component: OSGI-INF/*.xml -Import-Package: javax.annotation.security;version="1.2.0", +Import-Package: com.google.gson;version="2.9.0", + com.google.gson.reflect;version="2.9.0", + javax.annotation.security;version="1.2.0", javax.ws.rs;version="2.0.1", javax.ws.rs.core;version="2.0.1", org.apache.commons.io;version="2.4.0", diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index ee10c016ddc..e0c50068381 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -12,6 +12,7 @@ ******************************************************************************/ package org.eclipse.kura.internal.rest.identity.provider; +import java.util.HashSet; import java.util.Set; import javax.annotation.security.RolesAllowed; @@ -38,6 +39,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + @Path("identity/v1") public class IdentityRestService { @@ -55,6 +59,7 @@ public class IdentityRestService { private UserAdmin userAdmin; private IdentityService identityService; private ConfigurationService configurationService; + private Gson gson = new Gson(); public void bindCryptoService(CryptoService cryptoService) { this.cryptoService = cryptoService; @@ -148,9 +153,12 @@ public Set getUserConfig() { @RolesAllowed(REST_ROLE_NAME) @Path("/users/configs") @Consumes(MediaType.APPLICATION_JSON) - public Response setUserConfig(Set userConfig) { + public Response setUserConfig(String userConfigJson) { try { + Set userConfig = this.gson.fromJson(userConfigJson, new TypeToken>() { + }.getType()); logger.debug(DEBUG_MESSSAGE, "setUserConfig"); + for (final UserDTO config : userConfig) { final String newPassword = config.getPassword(); diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index 9b19469e820..5b03e75b10c 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -149,7 +149,7 @@ public void setUserConfig(Set userData) throws KuraException { final User user = this.userAdminHelper.getOrCreateUser(data.getUserName()); - if (data.getPermissions().contains(permissionName)) { + if (data.getPermissions() != null && data.getPermissions().contains(permissionName)) { permissionGroup.addMember(user); } else { permissionGroup.removeMember(user); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF b/kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..06d258ebf3a --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF @@ -0,0 +1,27 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.kura.rest.identity.provider.test +Bundle-SymbolicName: org.eclipse.kura.rest.identity.provider.test +Bundle-Version: 5.4.0.qualifier +Bundle-Vendor: Eclipse Kura +Bundle-License: Eclipse Public License v2.0 +Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" +Bundle-ActivationPolicy: lazy +Import-Package: javax.annotation;version="1.2.0", + org.eclipse.kura.core.testutil.requesthandler;version="1.1.0", + org.eclipse.kura.util.wire.test;version="1.1.0", + org.junit;version="[4.12.0,5.0.0)", + org.junit.runner;version="[4.12.0,5.0.0)", + org.junit.runners;version="[4.12.0,5.0.0)", + org.mockito;version="[4.0.0,5.0.0)", + org.mockito.invocation;version="[4.0.0,5.0.0)", + org.mockito.stubbing;version="[4.0.0,5.0.0)", + org.osgi.framework;version="1.10.0", + org.osgi.service.cm;version="1.6.0", + org.osgi.service.useradmin;version="1.1.0", + org.osgi.util.tracker;version="1.5.2", + org.slf4j;version="1.7.25" +Fragment-Host: org.eclipse.kura.rest.identity.provider +Require-Bundle: org.eclipse.kura.http.server.manager;bundle-version="1.1.0", + org.eclipse.kura.broker.artemis.core;bundle-version="1.2.0", + org.eclipse.kura.broker.artemis.simple.mqtt;bundle-version="1.1.0" diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/build.properties b/kura/test/org.eclipse.kura.rest.identity.provider.test/build.properties new file mode 100644 index 00000000000..d69abee4fb4 --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/build.properties @@ -0,0 +1,16 @@ +# +# Copyright (c) 2023 Eurotech and/or its affiliates and others +# +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Eurotech +# +source.. = src/main/java,\ + src/test/java +bin.includes = META-INF/,\ + . diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/pom.xml b/kura/test/org.eclipse.kura.rest.identity.provider.test/pom.xml new file mode 100644 index 00000000000..0cef6efd1dd --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + + + org.eclipse.kura + test + 5.4.0-SNAPSHOT + + + org.eclipse.kura.rest.identity.provider.test + eclipse-test-plugin + + + ${project.basedir}/../.. + ${project.build.directory}/site/jacoco-aggregate/jacoco.xml + + + + + + org.jacoco + jacoco-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + compiletests + test-compile + + testCompile + + + + + + org.eclipse.tycho + tycho-surefire-plugin + + classes + true + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.eclipse.tycho + target-platform-configuration + + + + diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java new file mode 100644 index 00000000000..b1e49441d04 --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Dictionary; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Optional; +import java.util.Scanner; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.eclipse.kura.KuraException; +import org.eclipse.kura.core.testutil.requesthandler.AbstractRequestHandlerTest; +import org.eclipse.kura.core.testutil.requesthandler.MqttTransport; +import org.eclipse.kura.core.testutil.requesthandler.RestTransport; +import org.eclipse.kura.core.testutil.requesthandler.Transport; +import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; +import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; +import org.eclipse.kura.internal.rest.identity.provider.IdentityService; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; +import org.eclipse.kura.util.wire.test.WireTestUtil; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.osgi.framework.FrameworkUtil; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +import com.google.gson.Gson; + +@RunWith(Parameterized.class) +public class IdentityEndpointsTest extends AbstractRequestHandlerTest { + + private static final String MQTT_APP_ID = "ID-V1"; + + private static final String METHOD_SPEC_GET = "GET"; + private static final String METHOD_SPEC_POST = "POST"; + private static final String METHOD_SPEC_DELETE = "DELETE"; + private static final String REST_APP_ID = "identity/v1"; + + private static IdentityService identityServiceMock = mock(IdentityService.class); + + private UserDTO user; + + private Gson gson = new Gson(); + + private static final String EXPECTED_GET_USER_RESPONSE = new Scanner( + IdentityEndpointsTest.class.getResourceAsStream("/getUserConfigResponse.json"), "UTF-8").useDelimiter("\\A") + .next().replace(" ", ""); + + private String username; + + private Set userConfigs; + + @Parameterized.Parameters + public static Collection transports() { + return Arrays.asList(new RestTransport(REST_APP_ID), new MqttTransport(MQTT_APP_ID)); + } + + public IdentityEndpointsTest(Transport transport) { + super(transport); + } + + @Test + public void shouldInvokeCreateUserSuccessfully() { + givenIdentityService(); + givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users", gson.toJson(this.user)); + + thenRequestSucceeds(); + thenResponseBodyIsEmpty(); + } + + @Test + public void shouldInvokeDeleteUserSuccessfully() { + givenIdentityService(); + givenUsername("testuser"); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users/" + this.username); + + thenRequestSucceeds(); + thenResponseBodyIsEmpty(); + } + + @Test + public void shouldReturnDefinedPermissions() { + givenIdentityService(); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); + + thenRequestSucceeds(); + thenResponseBodyEqualsJson("[\"kura.admin\"]"); + } + + @Test + public void shouldReturnUserConfig() { + givenIdentityService(); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); + + thenRequestSucceeds(); + thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); + } + + @Test + public void shouldInvokeSetUserConfigSuccessfully() { + givenIdentityService(); + givenUserConfigs(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( + "testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, "testpassw2")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs"); + + thenRequestSucceeds(); + } + + // @Test + // public void shouldRethrowWebApplicationExceptionOnReloadSecurityPolicyFingerprint() throws KuraException { + // givenFailingIdentityService(); + // + // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/security-policy-fingerprint/reload"); + // + // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); + // } + // + // @Test + // public void shouldRethrowWebApplicationExceptionOnReloadCommandLineFingerprint() throws KuraException { + // givenFailingIdentityService(); + // + // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/command-line-fingerprint/reload"); + // + // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); + // } + // + // @Test + // public void shouldRethrowWebApplicationExceptionOnGetDebugStatus() throws KuraException { + // givenFailingIdentityService(); + // + // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/debug-enabled"); + // + // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); + // } + + private void givenUser(UserDTO user) { + this.user = user; + } + + private void givenUsername(String username) { + this.username = username; + } + + private static void givenIdentityService() { + reset(identityServiceMock); + + when(identityServiceMock.getDefinedPermissions()).thenReturn(new HashSet<>(Arrays.asList("kura.admin"))); + } + + private static void givenFailingIdentityService() throws KuraException { + reset(identityServiceMock); + + } + + private void givenUserConfigs(UserDTO... userConfigs) { + this.userConfigs = new HashSet<>(Arrays.asList(userConfigs)); + } + + /* + * Utilities + */ + + @BeforeClass + public static void setUp() throws Exception { + createIdentityServiceMock(); + registerIdentityServiceMock(); + } + + private static void createIdentityServiceMock() { + givenIdentityService(); + + final Dictionary configurationServiceProperties = new Hashtable<>(); + configurationServiceProperties.put("service.ranking", Integer.MIN_VALUE); + configurationServiceProperties.put("kura.service.pid", "mockIdentityService"); + FrameworkUtil.getBundle(IdentityEndpointsTest.class).getBundleContext().registerService(IdentityService.class, + identityServiceMock, configurationServiceProperties); + } + + private static void registerIdentityServiceMock() throws Exception { + final Dictionary properties = new Hashtable<>(); + properties.put("IdentityService.target", "(kura.service.pid=mockIdentityService)"); + + final ConfigurationAdmin configurationAdmin = WireTestUtil + .trackService(ConfigurationAdmin.class, Optional.empty()).get(30, TimeUnit.SECONDS); + final Configuration config = configurationAdmin.getConfiguration(IdentityRestService.class.getName(), "?"); + config.update(properties); + } + +} diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json new file mode 100644 index 00000000000..5da570608ce --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json @@ -0,0 +1,20 @@ +[ + { + "userName": "admin", + "passwordAuthEnabled": true, + "passwordChangeNeeded": false, + "permissions": [ + "kura.admin" + ] + }, + { + "userName": "appadmin", + "passwordAuthEnabled": true, + "passwordChangeNeeded": true, + "permissions": [ + "kura.cloud.connection.admin", + "kura.packages.admin", + "kura.wires.admin" + ] + } +] \ No newline at end of file diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java new file mode 100644 index 00000000000..34e510df204 --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.test; + +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Objects; + +import org.eclipse.kura.KuraErrorCode; +import org.eclipse.kura.KuraException; +import org.eclipse.kura.cloudconnection.request.RequestHandler; +import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; +import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; +import org.junit.Test; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.UserAdmin; + +public class IdentityServiceTest { + + private static final String MQTT_APP_ID = "ID-V1"; + private static final String REST_ROLE_NAME = "identity"; + private static final String KURA_PERMISSION_REST_ROLE = "kura.permission.rest." + REST_ROLE_NAME; + + private IdentityRestService service = new IdentityRestService(); + private UserAdmin userAdmin; + + private RequestHandlerRegistry requestHandlerRegistry; + private Exception occurredException; + + /* + * Scenarios + */ + + @Test + public void shouldCreateRoleOnUserAdminBinding() { + givenMockUserAdmin(); + + whenBindUserAdmin(); + + thenRoleIsCreated(KURA_PERMISSION_REST_ROLE, Role.GROUP); + } + + @Test + public void shouldRegisterRequestHandler() throws KuraException { + givenMockRequestHandlerRegistry(); + + whenBindRequestHandlerRegistry(); + + thenRequestHandlerIsRegistered(MQTT_APP_ID); + } + + @Test + public void shouldUnregisterRequestHandler() throws KuraException { + givenMockRequestHandlerRegistry(); + + whenUnbindRequestHandlerRegistry(); + + thenRequestHandlerIsUnregistered(MQTT_APP_ID); + } + + @Test + public void shouldCatchExceptionsOnRequestHandlerBind() throws KuraException { + givenFailingMockRequestHandlerRegistry(); + + whenBindRequestHandlerRegistry(); + + thenNoExceptionOccurred(); + } + + @Test + public void shouldCatchExceptionsOnRequestHandlerUnbind() throws KuraException { + givenFailingMockRequestHandlerRegistry(); + + whenUnbindRequestHandlerRegistry(); + + thenNoExceptionOccurred(); + } + + /* + * Given + */ + + private void givenMockUserAdmin() { + this.userAdmin = mock(UserAdmin.class); + } + + private void givenMockRequestHandlerRegistry() { + this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); + } + + private void givenFailingMockRequestHandlerRegistry() throws KuraException { + this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); + doThrow(new KuraException(KuraErrorCode.BAD_REQUEST)).when(this.requestHandlerRegistry) + .registerRequestHandler(any(), any()); + doThrow(new KuraException(KuraErrorCode.BAD_REQUEST)).when(this.requestHandlerRegistry).unregister(any()); + } + + /* + * When + */ + + private void whenBindUserAdmin() { + this.service.bindUserAdmin(this.userAdmin); + } + + private void whenBindRequestHandlerRegistry() { + try { + this.service.bindRequestHandlerRegistry(this.requestHandlerRegistry); + } catch (Exception e) { + this.occurredException = e; + } + } + + private void whenUnbindRequestHandlerRegistry() { + try { + this.service.unbindRequestHandlerRegistry(this.requestHandlerRegistry); + } catch (Exception e) { + this.occurredException = e; + } + } + + /* + * Then + */ + + private void thenRoleIsCreated(String expectedKuraPermission, int expectedRole) { + verify(this.userAdmin, times(1)).createRole(expectedKuraPermission, expectedRole); + } + + private void thenRequestHandlerIsRegistered(String expectedMqttAppId) throws KuraException { + verify(this.requestHandlerRegistry, times(1)).registerRequestHandler(eq(expectedMqttAppId), + any(RequestHandler.class)); + } + + private void thenRequestHandlerIsUnregistered(String expectedMqttAppId) throws KuraException { + verify(this.requestHandlerRegistry, times(1)).unregister(expectedMqttAppId); + } + + private void thenNoExceptionOccurred() { + String errorMessage = "Empty message"; + if (Objects.nonNull(this.occurredException)) { + StringWriter sw = new StringWriter(); + this.occurredException.printStackTrace(new PrintWriter(sw)); + + errorMessage = String.format("No exception expected, \"%s\" found. Caused by: %s", + this.occurredException.getClass().getName(), sw.toString()); + } + + assertNull(errorMessage, this.occurredException); + } + +} diff --git a/kura/test/pom.xml b/kura/test/pom.xml index 1730aa1ff0c..d67ddd18ee1 100644 --- a/kura/test/pom.xml +++ b/kura/test/pom.xml @@ -931,6 +931,7 @@ org.eclipse.kura.rest.packages.provider.test org.eclipse.kura.rest.position.provider.test org.eclipse.kura.rest.security.provider.test + org.eclipse.kura.rest.security.provider.test org.eclipse.kura.rest.service.listing.provider.test org.eclipse.kura.rest.system.provider.test org.eclipse.kura.rest.wire.provider.test From b92ee60d2141cfa9d1951fa31619b65a31523724 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 2 Oct 2023 16:01:09 +0200 Subject: [PATCH 03/66] Added condition on shouldInvokeSetUserConfigSuccessfully --- .../identity/provider/test/IdentityEndpointsTest.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index b1e49441d04..a056e69591b 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -14,6 +14,8 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Arrays; @@ -123,7 +125,7 @@ public void shouldReturnUserConfig() { } @Test - public void shouldInvokeSetUserConfigSuccessfully() { + public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { givenIdentityService(); givenUserConfigs(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( "testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, "testpassw2")); @@ -131,6 +133,7 @@ public void shouldInvokeSetUserConfigSuccessfully() { whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs"); thenRequestSucceeds(); + thenIdentityServiceWasCalledWith(this.userConfigs); } // @Test @@ -183,6 +186,11 @@ private void givenUserConfigs(UserDTO... userConfigs) { this.userConfigs = new HashSet<>(Arrays.asList(userConfigs)); } + private void thenIdentityServiceWasCalledWith(Set userConfigs) throws KuraException { + verify(identityServiceMock, times(1)).setUserConfig(userConfigs); + + } + /* * Utilities */ From fd09ac0820fbd1931a77bf670d05dee8176b309a Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 2 Oct 2023 16:04:06 +0200 Subject: [PATCH 04/66] Added new module in the list --- kura/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/kura/pom.xml b/kura/pom.xml index 5b084074f5b..6298f233c43 100644 --- a/kura/pom.xml +++ b/kura/pom.xml @@ -126,6 +126,7 @@ org.eclipse.kura.wire.script.tools org.eclipse.kura.db.sqlite.provider org.eclipse.kura.rest.network.status.provider + org.eclipse.kura.rest.identity.provider emulator test-util From 7850fe808f77a51a788507fdf32b8b26ad6810bf Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 2 Oct 2023 17:13:43 +0200 Subject: [PATCH 05/66] fixed tests. --- .../provider/test/IdentityEndpointsTest.java | 77 +------------------ 1 file changed, 4 insertions(+), 73 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index a056e69591b..77674c7a848 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -12,22 +12,12 @@ *******************************************************************************/ package org.eclipse.kura.internal.rest.identity.provider.test; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Dictionary; import java.util.HashSet; -import java.util.Hashtable; -import java.util.Optional; import java.util.Scanner; import java.util.Set; -import java.util.concurrent.TimeUnit; import org.eclipse.kura.KuraException; import org.eclipse.kura.core.testutil.requesthandler.AbstractRequestHandlerTest; @@ -35,17 +25,10 @@ import org.eclipse.kura.core.testutil.requesthandler.RestTransport; import org.eclipse.kura.core.testutil.requesthandler.Transport; import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; -import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; -import org.eclipse.kura.internal.rest.identity.provider.IdentityService; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; -import org.eclipse.kura.util.wire.test.WireTestUtil; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import org.osgi.framework.FrameworkUtil; -import org.osgi.service.cm.Configuration; -import org.osgi.service.cm.ConfigurationAdmin; import com.google.gson.Gson; @@ -59,8 +42,6 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static final String METHOD_SPEC_DELETE = "DELETE"; private static final String REST_APP_ID = "identity/v1"; - private static IdentityService identityServiceMock = mock(IdentityService.class); - private UserDTO user; private Gson gson = new Gson(); @@ -84,7 +65,6 @@ public IdentityEndpointsTest(Transport transport) { @Test public void shouldInvokeCreateUserSuccessfully() { - givenIdentityService(); givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users", gson.toJson(this.user)); @@ -95,7 +75,7 @@ public void shouldInvokeCreateUserSuccessfully() { @Test public void shouldInvokeDeleteUserSuccessfully() { - givenIdentityService(); + givenUsername("testuser"); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users/" + this.username); @@ -106,17 +86,16 @@ public void shouldInvokeDeleteUserSuccessfully() { @Test public void shouldReturnDefinedPermissions() { - givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); thenRequestSucceeds(); - thenResponseBodyEqualsJson("[\"kura.admin\"]"); + thenResponseBodyEqualsJson( + "[\"kura.cloud.connection.admin\",\"kura.packages.admin\",\"kura.device\",\"kura.admin\",\"rest.keystores\",\"kura.network.admin\",\"kura.wires.admin\",\"rest.identity\"]"); } @Test public void shouldReturnUserConfig() { - givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); @@ -126,14 +105,12 @@ public void shouldReturnUserConfig() { @Test public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { - givenIdentityService(); givenUserConfigs(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( "testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, "testpassw2")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs"); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs", gson.toJson(this.userConfigs)); thenRequestSucceeds(); - thenIdentityServiceWasCalledWith(this.userConfigs); } // @Test @@ -171,54 +148,8 @@ private void givenUsername(String username) { this.username = username; } - private static void givenIdentityService() { - reset(identityServiceMock); - - when(identityServiceMock.getDefinedPermissions()).thenReturn(new HashSet<>(Arrays.asList("kura.admin"))); - } - - private static void givenFailingIdentityService() throws KuraException { - reset(identityServiceMock); - - } - private void givenUserConfigs(UserDTO... userConfigs) { this.userConfigs = new HashSet<>(Arrays.asList(userConfigs)); } - private void thenIdentityServiceWasCalledWith(Set userConfigs) throws KuraException { - verify(identityServiceMock, times(1)).setUserConfig(userConfigs); - - } - - /* - * Utilities - */ - - @BeforeClass - public static void setUp() throws Exception { - createIdentityServiceMock(); - registerIdentityServiceMock(); - } - - private static void createIdentityServiceMock() { - givenIdentityService(); - - final Dictionary configurationServiceProperties = new Hashtable<>(); - configurationServiceProperties.put("service.ranking", Integer.MIN_VALUE); - configurationServiceProperties.put("kura.service.pid", "mockIdentityService"); - FrameworkUtil.getBundle(IdentityEndpointsTest.class).getBundleContext().registerService(IdentityService.class, - identityServiceMock, configurationServiceProperties); - } - - private static void registerIdentityServiceMock() throws Exception { - final Dictionary properties = new Hashtable<>(); - properties.put("IdentityService.target", "(kura.service.pid=mockIdentityService)"); - - final ConfigurationAdmin configurationAdmin = WireTestUtil - .trackService(ConfigurationAdmin.class, Optional.empty()).get(30, TimeUnit.SECONDS); - final Configuration config = configurationAdmin.getConfiguration(IdentityRestService.class.getName(), "?"); - config.update(properties); - } - } From 53a0e1ca64e7fbfcf48ee1d17db46d117f956aa9 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 12:39:46 +0200 Subject: [PATCH 06/66] Added the possibility to inject the identityService (mainly for testing purposes) --- .../OSGI-INF/IdentityRestService.xml | 8 +-- .../provider/IdentityRestService.java | 10 +++- .../provider/test/IdentityEndpointsTest.java | 52 +++++++++++++++++++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml index 3590e436fee..72b77ce4d3b 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml +++ b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml @@ -37,10 +37,10 @@ name="UserAdmin" policy="static"/> - diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index e0c50068381..62028fb04b3 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -82,6 +82,11 @@ public void bindRequestHandlerRegistry(RequestHandlerRegistry registry) { } } + // Added mainly for testing purposes. Currently the service is created by this endpoint. + public void bindIdentityService(IdentityService identityService) { + this.identityService = identityService; + } + public void unbindRequestHandlerRegistry(RequestHandlerRegistry registry) { try { registry.unregister(MQTT_APP_ID); @@ -91,7 +96,10 @@ public void unbindRequestHandlerRegistry(RequestHandlerRegistry registry) { } public void activate() { - this.identityService = new IdentityService(this.cryptoService, this.userAdmin, this.configurationService); + // create only if not set externally. Added mainly for testing purposes. + if (this.identityService == null) { + this.identityService = new IdentityService(this.cryptoService, this.userAdmin, this.configurationService); + } } @POST diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 77674c7a848..e0faecd604a 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -12,12 +12,19 @@ *******************************************************************************/ package org.eclipse.kura.internal.rest.identity.provider.test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Dictionary; import java.util.HashSet; +import java.util.Hashtable; +import java.util.Optional; import java.util.Scanner; import java.util.Set; +import java.util.concurrent.TimeUnit; import org.eclipse.kura.KuraException; import org.eclipse.kura.core.testutil.requesthandler.AbstractRequestHandlerTest; @@ -25,10 +32,17 @@ import org.eclipse.kura.core.testutil.requesthandler.RestTransport; import org.eclipse.kura.core.testutil.requesthandler.Transport; import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; +import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; +import org.eclipse.kura.internal.rest.identity.provider.IdentityService; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; +import org.eclipse.kura.util.wire.test.WireTestUtil; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.osgi.framework.FrameworkUtil; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; import com.google.gson.Gson; @@ -42,6 +56,8 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static final String METHOD_SPEC_DELETE = "DELETE"; private static final String REST_APP_ID = "identity/v1"; + private static IdentityService identityServiceMock = mock(IdentityService.class); + private UserDTO user; private Gson gson = new Gson(); @@ -65,6 +81,8 @@ public IdentityEndpointsTest(Transport transport) { @Test public void shouldInvokeCreateUserSuccessfully() { + givenIdentityService(); + givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users", gson.toJson(this.user)); @@ -75,6 +93,7 @@ public void shouldInvokeCreateUserSuccessfully() { @Test public void shouldInvokeDeleteUserSuccessfully() { + givenIdentityService(); givenUsername("testuser"); @@ -86,6 +105,7 @@ public void shouldInvokeDeleteUserSuccessfully() { @Test public void shouldReturnDefinedPermissions() { + givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); @@ -96,6 +116,7 @@ public void shouldReturnDefinedPermissions() { @Test public void shouldReturnUserConfig() { + givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); @@ -113,6 +134,11 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { thenRequestSucceeds(); } + private static void givenIdentityService() { + reset(identityServiceMock); + + } + // @Test // public void shouldRethrowWebApplicationExceptionOnReloadSecurityPolicyFingerprint() throws KuraException { // givenFailingIdentityService(); @@ -140,6 +166,32 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); // } + @BeforeClass + public static void setUp() throws Exception { + createSecurityServiceMock(); + registerSecurityServiceMock(); + } + + private static void createSecurityServiceMock() { + givenIdentityService(); + + final Dictionary configurationServiceProperties = new Hashtable<>(); + configurationServiceProperties.put("service.ranking", Integer.MIN_VALUE); + configurationServiceProperties.put("kura.service.pid", "identityServiceMock"); + FrameworkUtil.getBundle(IdentityEndpointsTest.class).getBundleContext().registerService(IdentityService.class, + identityServiceMock, configurationServiceProperties); + } + + private static void registerSecurityServiceMock() throws Exception { + final Dictionary properties = new Hashtable<>(); + properties.put("IdentityService.target", "(kura.service.pid=identityServiceMock)"); + + final ConfigurationAdmin configurationAdmin = WireTestUtil + .trackService(ConfigurationAdmin.class, Optional.empty()).get(30, TimeUnit.SECONDS); + final Configuration config = configurationAdmin.getConfiguration(IdentityRestService.class.getName(), "?"); + config.update(properties); + } + private void givenUser(UserDTO user) { this.user = user; } From 1212a826078f372806736fda50f95bfdc07c769e Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 14:34:32 +0200 Subject: [PATCH 07/66] Fix tests --- .../provider/test/IdentityEndpointsTest.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index e0faecd604a..3ad59a10066 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -14,6 +14,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.Collection; @@ -68,7 +69,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private String username; - private Set userConfigs; + private static Set userConfigs; @Parameterized.Parameters public static Collection transports() { @@ -110,8 +111,7 @@ public void shouldReturnDefinedPermissions() { whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); thenRequestSucceeds(); - thenResponseBodyEqualsJson( - "[\"kura.cloud.connection.admin\",\"kura.packages.admin\",\"kura.device\",\"kura.admin\",\"rest.keystores\",\"kura.network.admin\",\"kura.wires.admin\",\"rest.identity\"]"); + thenResponseBodyEqualsJson("[\"perm1\",\"perm2\"]"); } @Test @@ -129,7 +129,7 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { givenUserConfigs(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( "testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, "testpassw2")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs", gson.toJson(this.userConfigs)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs", gson.toJson(userConfigs)); thenRequestSucceeds(); } @@ -137,6 +137,10 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { private static void givenIdentityService() { reset(identityServiceMock); + when(identityServiceMock.getDefinedPermissions()) + .thenReturn(new HashSet(Arrays.asList("perm1", "perm2"))); + + when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); } // @Test @@ -200,8 +204,8 @@ private void givenUsername(String username) { this.username = username; } - private void givenUserConfigs(UserDTO... userConfigs) { - this.userConfigs = new HashSet<>(Arrays.asList(userConfigs)); + private void givenUserConfigs(UserDTO... userConfigurations) { + userConfigs = new HashSet<>(Arrays.asList(userConfigurations)); } } From 7a94c71767d2d0dd7fdf7e1dd93ce260a8cbd917 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 14:49:41 +0200 Subject: [PATCH 08/66] Fixed data test --- .../main/resources/getUserConfigResponse.json | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json index 5da570608ce..6ea9e7e52e5 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json @@ -1,20 +1,19 @@ [ { - "userName": "admin", - "passwordAuthEnabled": true, - "passwordChangeNeeded": false, + "password": "testpassw2", + "passwordAuthEnabled": false, + "passwordChangeNeeded": true, "permissions": [ - "kura.admin" - ] + "perm1", + "perm2" + ], + "userName": "testuser2" }, { - "userName": "appadmin", + "password": "testpassw", "passwordAuthEnabled": true, - "passwordChangeNeeded": true, - "permissions": [ - "kura.cloud.connection.admin", - "kura.packages.admin", - "kura.wires.admin" - ] + "passwordChangeNeeded": false, + "permissions": [], + "userName": "testuser" } ] \ No newline at end of file From 4ad3261419e05de9e45e876c95547e679aee777f Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 14:57:44 +0200 Subject: [PATCH 09/66] fixed module name --- kura/test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/test/pom.xml b/kura/test/pom.xml index d67ddd18ee1..e939eaaddb0 100644 --- a/kura/test/pom.xml +++ b/kura/test/pom.xml @@ -931,7 +931,7 @@ org.eclipse.kura.rest.packages.provider.test org.eclipse.kura.rest.position.provider.test org.eclipse.kura.rest.security.provider.test - org.eclipse.kura.rest.security.provider.test + org.eclipse.kura.rest.identity.provider.test org.eclipse.kura.rest.service.listing.provider.test org.eclipse.kura.rest.system.provider.test org.eclipse.kura.rest.wire.provider.test From 4c70fd3115c5d7ef3b65f71bd0baf03714969c07 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 15:07:30 +0200 Subject: [PATCH 10/66] updated expected data --- .../src/main/resources/getUserConfigResponse.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json index 6ea9e7e52e5..b961ac7b03a 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json @@ -1,19 +1,19 @@ [ { - "password": "testpassw2", + "userName": "testuser2", "passwordAuthEnabled": false, "passwordChangeNeeded": true, "permissions": [ "perm1", "perm2" ], - "userName": "testuser2" + "password": "testpassw2" }, { - "password": "testpassw", + "userName": "testuser", "passwordAuthEnabled": true, "passwordChangeNeeded": false, "permissions": [], - "userName": "testuser" + "password": "testpassw" } ] \ No newline at end of file From 405f99402f81b13d9b0e2404143216ddf31d4c2e Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 15:16:43 +0200 Subject: [PATCH 11/66] Fix tests --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 2 ++ .../src/main/resources/getUserConfigResponse.json | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 3ad59a10066..f4c345d7187 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -116,6 +116,8 @@ public void shouldReturnDefinedPermissions() { @Test public void shouldReturnUserConfig() { + givenUserConfigs(new UserDTO("testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, + "testpassw2")); givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json index b961ac7b03a..bb786ce935b 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json @@ -8,12 +8,5 @@ "perm2" ], "password": "testpassw2" - }, - { - "userName": "testuser", - "passwordAuthEnabled": true, - "passwordChangeNeeded": false, - "permissions": [], - "password": "testpassw" } ] \ No newline at end of file From 3ce73745161ed71ee76f87dde3ae5400cbd7956e Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 15:52:33 +0200 Subject: [PATCH 12/66] fixed method names --- .../identity/provider/test/IdentityEndpointsTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index f4c345d7187..5ad928568da 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -174,11 +174,11 @@ private static void givenIdentityService() { @BeforeClass public static void setUp() throws Exception { - createSecurityServiceMock(); - registerSecurityServiceMock(); + createidentityServiceMock(); + registeridentityServiceMock(); } - private static void createSecurityServiceMock() { + private static void createidentityServiceMock() { givenIdentityService(); final Dictionary configurationServiceProperties = new Hashtable<>(); @@ -188,7 +188,7 @@ private static void createSecurityServiceMock() { identityServiceMock, configurationServiceProperties); } - private static void registerSecurityServiceMock() throws Exception { + private static void registeridentityServiceMock() throws Exception { final Dictionary properties = new Hashtable<>(); properties.put("IdentityService.target", "(kura.service.pid=identityServiceMock)"); From 470c08d17d8bc6dc7f3af2b8e0b3c0b6ec236cb2 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 3 Oct 2023 17:08:04 +0200 Subject: [PATCH 13/66] Changed API to meet `JaxRsRequest` handler behavior --- .../provider/IdentityRestService.java | 13 ++++---- .../provider/dto/UserConfigRequestDTO.java | 30 +++++++++++++++++++ .../provider/test/IdentityEndpointsTest.java | 21 +++++++------ 3 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigRequestDTO.java diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 62028fb04b3..edda1b0ac98 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -12,7 +12,6 @@ ******************************************************************************/ package org.eclipse.kura.internal.rest.identity.provider; -import java.util.HashSet; import java.util.Set; import javax.annotation.security.RolesAllowed; @@ -21,7 +20,6 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; -import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -31,6 +29,7 @@ import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; import org.eclipse.kura.configuration.ConfigurationService; import org.eclipse.kura.crypto.CryptoService; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigRequestDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; import org.eclipse.kura.request.handler.jaxrs.DefaultExceptionHandler; import org.eclipse.kura.request.handler.jaxrs.JaxRsRequestHandlerProxy; @@ -40,7 +39,6 @@ import org.slf4j.LoggerFactory; import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; @Path("identity/v1") public class IdentityRestService { @@ -120,10 +118,10 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) @Path("/users/{userName}") - public Response deleteUser(@PathParam("userName") final String userName) { + public Response deleteUser(final UserDTO userName) { try { logger.debug(DEBUG_MESSSAGE, "deleteUser"); - this.identityService.deleteUser(userName); + this.identityService.deleteUser(userName.getUserName()); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); } @@ -161,11 +159,10 @@ public Set getUserConfig() { @RolesAllowed(REST_ROLE_NAME) @Path("/users/configs") @Consumes(MediaType.APPLICATION_JSON) - public Response setUserConfig(String userConfigJson) { + public Response setUserConfig(UserConfigRequestDTO userConfigrRequest) { try { - Set userConfig = this.gson.fromJson(userConfigJson, new TypeToken>() { - }.getType()); logger.debug(DEBUG_MESSSAGE, "setUserConfig"); + Set userConfig = userConfigrRequest.getUserConfig(); for (final UserDTO config : userConfig) { final String newPassword = config.getPassword(); diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigRequestDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigRequestDTO.java new file mode 100644 index 00000000000..4f51beb93e9 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigRequestDTO.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.dto; + +import java.util.HashSet; +import java.util.Set; + +public class UserConfigRequestDTO { + + private Set userConfig = new HashSet<>(); + + public Set getUserConfig() { + return userConfig; + } + + public void setUserConfig(Set userConfig) { + this.userConfig = userConfig; + } + +} diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 5ad928568da..5076ceb90c2 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -35,6 +35,7 @@ import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; import org.eclipse.kura.internal.rest.identity.provider.IdentityService; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigRequestDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; import org.eclipse.kura.util.wire.test.WireTestUtil; import org.junit.BeforeClass; @@ -67,7 +68,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { IdentityEndpointsTest.class.getResourceAsStream("/getUserConfigResponse.json"), "UTF-8").useDelimiter("\\A") .next().replace(" ", ""); - private String username; + private UserConfigRequestDTO userConfigRequest; private static Set userConfigs; @@ -96,9 +97,9 @@ public void shouldInvokeCreateUserSuccessfully() { public void shouldInvokeDeleteUserSuccessfully() { givenIdentityService(); - givenUsername("testuser"); + givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users/" + this.username); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users/", gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); @@ -120,7 +121,7 @@ public void shouldReturnUserConfig() { "testpassw2")); givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs", gson.toJson(this.userConfigRequest)); thenRequestSucceeds(); thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); @@ -128,7 +129,7 @@ public void shouldReturnUserConfig() { @Test public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { - givenUserConfigs(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( + givenUserConfigRequest(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( "testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, "testpassw2")); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs", gson.toJson(userConfigs)); @@ -136,6 +137,12 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { thenRequestSucceeds(); } + private void givenUserConfigRequest(UserDTO... userDTO) { + this.userConfigRequest = new UserConfigRequestDTO(); + this.userConfigRequest.setUserConfig(new HashSet<>(Arrays.asList(userDTO))); + + } + private static void givenIdentityService() { reset(identityServiceMock); @@ -202,10 +209,6 @@ private void givenUser(UserDTO user) { this.user = user; } - private void givenUsername(String username) { - this.username = username; - } - private void givenUserConfigs(UserDTO... userConfigurations) { userConfigs = new HashSet<>(Arrays.asList(userConfigurations)); } From 11523bb03bcffaea727e61b8464db40da0c2e890 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 09:48:17 +0200 Subject: [PATCH 14/66] Fixed deleteUser path and tests. --- .../internal/rest/identity/provider/IdentityRestService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index edda1b0ac98..f430a4a87bb 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -117,7 +117,7 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) - @Path("/users/{userName}") + @Path("/users") public Response deleteUser(final UserDTO userName) { try { logger.debug(DEBUG_MESSSAGE, "deleteUser"); From 75654da48326253e2937ee5dee48617736b9756a Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 09:52:22 +0200 Subject: [PATCH 15/66] Fixed test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 5076ceb90c2..4a0ff7c641e 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -117,8 +117,6 @@ public void shouldReturnDefinedPermissions() { @Test public void shouldReturnUserConfig() { - givenUserConfigs(new UserDTO("testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, - "testpassw2")); givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs", gson.toJson(this.userConfigRequest)); @@ -132,7 +130,9 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { givenUserConfigRequest(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( "testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, "testpassw2")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs", gson.toJson(userConfigs)); + givenIdentityService(); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs", gson.toJson(this.userConfigRequest)); thenRequestSucceeds(); } From 534020328a61835f54509656a8ef5958c30ca3a0 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 09:57:44 +0200 Subject: [PATCH 16/66] Fixed test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 4a0ff7c641e..4a6846c131f 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -117,6 +117,12 @@ public void shouldReturnDefinedPermissions() { @Test public void shouldReturnUserConfig() { + givenUserConfigs(new UserDTO("testuser2", // + new HashSet(Arrays.asList("perm1", "perm2")), // + false, // + true, // + "testpassw2")); + givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs", gson.toJson(this.userConfigRequest)); From 7bd80966ebbc4435b29c1fcd7b25d9e456792949 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 10:15:00 +0200 Subject: [PATCH 17/66] Changed getUserConfig return type --- .../rest/identity/provider/IdentityRestService.java | 12 +++++++----- ...{UserConfigRequestDTO.java => UserConfigDTO.java} | 2 +- .../provider/test/IdentityEndpointsTest.java | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) rename kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/{UserConfigRequestDTO.java => UserConfigDTO.java} (95%) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index f430a4a87bb..5f7c9e2a119 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -29,7 +29,7 @@ import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; import org.eclipse.kura.configuration.ConfigurationService; import org.eclipse.kura.crypto.CryptoService; -import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigRequestDTO; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; import org.eclipse.kura.request.handler.jaxrs.DefaultExceptionHandler; import org.eclipse.kura.request.handler.jaxrs.JaxRsRequestHandlerProxy; @@ -146,10 +146,12 @@ public Set getDefinedPermissions() { @RolesAllowed(REST_ROLE_NAME) @Path("/users/configs") @Produces(MediaType.APPLICATION_JSON) - public Set getUserConfig() { + public UserConfigDTO getUserConfig() { try { logger.debug(DEBUG_MESSSAGE, "getUserConfig"); - return this.identityService.getUserConfig(); + UserConfigDTO userConfig = new UserConfigDTO(); + userConfig.setUserConfig(this.identityService.getUserConfig()); + return userConfig; } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); } @@ -159,10 +161,10 @@ public Set getUserConfig() { @RolesAllowed(REST_ROLE_NAME) @Path("/users/configs") @Consumes(MediaType.APPLICATION_JSON) - public Response setUserConfig(UserConfigRequestDTO userConfigrRequest) { + public Response setUserConfig(UserConfigDTO userConfigRequest) { try { logger.debug(DEBUG_MESSSAGE, "setUserConfig"); - Set userConfig = userConfigrRequest.getUserConfig(); + Set userConfig = userConfigRequest.getUserConfig(); for (final UserDTO config : userConfig) { final String newPassword = config.getPassword(); diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigRequestDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigDTO.java similarity index 95% rename from kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigRequestDTO.java rename to kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigDTO.java index 4f51beb93e9..9cec0b017d4 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigRequestDTO.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigDTO.java @@ -15,7 +15,7 @@ import java.util.HashSet; import java.util.Set; -public class UserConfigRequestDTO { +public class UserConfigDTO { private Set userConfig = new HashSet<>(); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 4a6846c131f..ae6187be7f1 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -35,7 +35,7 @@ import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; import org.eclipse.kura.internal.rest.identity.provider.IdentityService; -import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigRequestDTO; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; import org.eclipse.kura.util.wire.test.WireTestUtil; import org.junit.BeforeClass; @@ -68,7 +68,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { IdentityEndpointsTest.class.getResourceAsStream("/getUserConfigResponse.json"), "UTF-8").useDelimiter("\\A") .next().replace(" ", ""); - private UserConfigRequestDTO userConfigRequest; + private UserConfigDTO userConfigRequest; private static Set userConfigs; @@ -144,7 +144,7 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { } private void givenUserConfigRequest(UserDTO... userDTO) { - this.userConfigRequest = new UserConfigRequestDTO(); + this.userConfigRequest = new UserConfigDTO(); this.userConfigRequest.setUserConfig(new HashSet<>(Arrays.asList(userDTO))); } From 3ef267c96f90bbc1051e2e87f650876d25faf4d1 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 10:16:33 +0200 Subject: [PATCH 18/66] Removed Gson --- .../META-INF/MANIFEST.MF | 4 +--- .../internal/rest/identity/provider/IdentityRestService.java | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF b/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF index 806f565a7e8..295b8ba55b5 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF +++ b/kura/org.eclipse.kura.rest.identity.provider/META-INF/MANIFEST.MF @@ -7,9 +7,7 @@ Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" Bundle-ClassPath: . Bundle-ActivationPolicy: lazy Service-Component: OSGI-INF/*.xml -Import-Package: com.google.gson;version="2.9.0", - com.google.gson.reflect;version="2.9.0", - javax.annotation.security;version="1.2.0", +Import-Package: javax.annotation.security;version="1.2.0", javax.ws.rs;version="2.0.1", javax.ws.rs.core;version="2.0.1", org.apache.commons.io;version="2.4.0", diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 5f7c9e2a119..4fd0ff7f5b9 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -38,8 +38,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; - @Path("identity/v1") public class IdentityRestService { @@ -57,7 +55,6 @@ public class IdentityRestService { private UserAdmin userAdmin; private IdentityService identityService; private ConfigurationService configurationService; - private Gson gson = new Gson(); public void bindCryptoService(CryptoService cryptoService) { this.cryptoService = cryptoService; From 8786a9e4f4d332f8fbac9dedceeb93e1fedaec61 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 10:18:13 +0200 Subject: [PATCH 19/66] fixed test manifest.mf --- .../META-INF/MANIFEST.MF | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF b/kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF index 06d258ebf3a..c504d0cf628 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/META-INF/MANIFEST.MF @@ -7,7 +7,8 @@ Bundle-Vendor: Eclipse Kura Bundle-License: Eclipse Public License v2.0 Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" Bundle-ActivationPolicy: lazy -Import-Package: javax.annotation;version="1.2.0", +Import-Package: com.google.gson;version="2.9.0", + javax.annotation;version="1.2.0", org.eclipse.kura.core.testutil.requesthandler;version="1.1.0", org.eclipse.kura.util.wire.test;version="1.1.0", org.junit;version="[4.12.0,5.0.0)", From e4a669662d7c24e273fa9b26598e55e80b3dff01 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 10:24:49 +0200 Subject: [PATCH 20/66] Trying fix tests --- .../rest/identity/provider/dto/UserDTO.java | 28 ++++++++++++++++--- .../main/resources/getUserConfigResponse.json | 26 +++++++++-------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java index df1b5ae213e..b8fba33514b 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java @@ -16,12 +16,16 @@ public class UserDTO { - private final String userName; - private final boolean passwordAuthEnabled; - private final boolean passwordChangeNeeded; - private final Set permissions; + private String userName; + private boolean passwordAuthEnabled; + private boolean passwordChangeNeeded; + private Set permissions; private String password; + public UserDTO() { + + } + public UserDTO(final String userName, final Set permissions, final boolean passwordAuthEnabled, final boolean passwordChangeNeeded, final String password) { @@ -43,18 +47,34 @@ public String getUserName() { return userName; } + public void setUserName(String userName) { + this.userName = userName; + } + public boolean isPasswordAuthEnabled() { return passwordAuthEnabled; } + public void setPasswordAuthEnabled(boolean passwordAuthEnabled) { + this.passwordAuthEnabled = passwordAuthEnabled; + } + public boolean isPasswordChangeNeeded() { return passwordChangeNeeded; } + public void setPasswordChangeNeeded(boolean passwordChangeNeeded) { + this.passwordChangeNeeded = passwordChangeNeeded; + } + public Set getPermissions() { return permissions; } + public void setPermissions(Set permissions) { + this.permissions = permissions; + } + public String getPassword() { return password; } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json index bb786ce935b..77fd6271e97 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json @@ -1,12 +1,14 @@ -[ - { - "userName": "testuser2", - "passwordAuthEnabled": false, - "passwordChangeNeeded": true, - "permissions": [ - "perm1", - "perm2" - ], - "password": "testpassw2" - } -] \ No newline at end of file +{ + "userConfig": [ + { + "userName": "testuser2", + "passwordAuthEnabled": false, + "passwordChangeNeeded": true, + "permissions": [ + "perm1", + "perm2" + ], + "password": "testpassw2" + } + ] +} \ No newline at end of file From 4d2bb59cb97251794decbba29b2dceb7c4ce9172 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 10:33:54 +0200 Subject: [PATCH 21/66] fixed method path --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index ae6187be7f1..3fdbd637159 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -99,7 +99,7 @@ public void shouldInvokeDeleteUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users/", gson.toJson(this.user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users", gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); From f5b9f6e16a1b9a1c107fa53d53e7fb579ba409b0 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 10:36:56 +0200 Subject: [PATCH 22/66] removed wrong body --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 3fdbd637159..7a9b87ef600 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -125,7 +125,7 @@ public void shouldReturnUserConfig() { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs", gson.toJson(this.userConfigRequest)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); thenRequestSucceeds(); thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); From 54187890aba3d263bd6afe2697f5eb455d87c2b4 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 11:03:50 +0200 Subject: [PATCH 23/66] Test alternate delete --- .../internal/rest/identity/provider/IdentityRestService.java | 2 +- .../rest/identity/provider/test/IdentityEndpointsTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 4fd0ff7f5b9..3e4201b69c0 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -114,7 +114,7 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) - @Path("/users") + @Path("/users/delete") public Response deleteUser(final UserDTO userName) { try { logger.debug(DEBUG_MESSSAGE, "deleteUser"); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 7a9b87ef600..4bf67248498 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -99,7 +99,7 @@ public void shouldInvokeDeleteUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users", gson.toJson(this.user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users/delete", gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); From 91064d88a365b39ad93927ba07a22acb07d4c5be Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 11:06:14 +0200 Subject: [PATCH 24/66] Test alternate delete --- .../internal/rest/identity/provider/IdentityRestService.java | 4 ++-- .../rest/identity/provider/test/IdentityEndpointsTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 3e4201b69c0..30b8d36bfa9 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -114,10 +114,10 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) - @Path("/users/delete") + @Path("/users-delete") public Response deleteUser(final UserDTO userName) { try { - logger.debug(DEBUG_MESSSAGE, "deleteUser"); + logger.debug(DEBUG_MESSSAGE, "users-delete"); this.identityService.deleteUser(userName.getUserName()); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 4bf67248498..d11c4dc6cc2 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -99,7 +99,7 @@ public void shouldInvokeDeleteUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users/delete", gson.toJson(this.user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users-delete", gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); From 098cd6fa0d61654c87ac488a91c3e1bef9217975 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 11:12:38 +0200 Subject: [PATCH 25/66] Yet another fix --- .../identity/provider/IdentityRestService.java | 15 ++++++++------- .../provider/test/IdentityEndpointsTest.java | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 30b8d36bfa9..e39f9eaf657 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -42,7 +42,7 @@ public class IdentityRestService { private static final Logger logger = LoggerFactory.getLogger(IdentityRestService.class); - private static final String DEBUG_MESSSAGE = "Processing request for method '{}'"; + private static final String DEBUG_MESSAGE = "Processing request for method '{}'"; private static final String MQTT_APP_ID = "ID-V1"; private static final String REST_ROLE_NAME = "identity"; @@ -103,7 +103,7 @@ public void activate() { @Consumes(MediaType.APPLICATION_JSON) public Response createUser(final UserDTO userName) { try { - logger.debug(DEBUG_MESSSAGE, "createUser"); + logger.debug(DEBUG_MESSAGE, "createUser"); this.identityService.createUser(userName.getUserName()); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); @@ -114,10 +114,11 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) - @Path("/users-delete") + @Path("/users") + @Consumes(MediaType.APPLICATION_JSON) public Response deleteUser(final UserDTO userName) { try { - logger.debug(DEBUG_MESSSAGE, "users-delete"); + logger.debug(DEBUG_MESSAGE, "deleteUser"); this.identityService.deleteUser(userName.getUserName()); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); @@ -132,7 +133,7 @@ public Response deleteUser(final UserDTO userName) { @Produces(MediaType.APPLICATION_JSON) public Set getDefinedPermissions() { try { - logger.debug(DEBUG_MESSSAGE, "getDefinedPermissions"); + logger.debug(DEBUG_MESSAGE, "getDefinedPermissions"); return this.identityService.getDefinedPermissions(); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); @@ -145,7 +146,7 @@ public Set getDefinedPermissions() { @Produces(MediaType.APPLICATION_JSON) public UserConfigDTO getUserConfig() { try { - logger.debug(DEBUG_MESSSAGE, "getUserConfig"); + logger.debug(DEBUG_MESSAGE, "getUserConfig"); UserConfigDTO userConfig = new UserConfigDTO(); userConfig.setUserConfig(this.identityService.getUserConfig()); return userConfig; @@ -160,7 +161,7 @@ public UserConfigDTO getUserConfig() { @Consumes(MediaType.APPLICATION_JSON) public Response setUserConfig(UserConfigDTO userConfigRequest) { try { - logger.debug(DEBUG_MESSSAGE, "setUserConfig"); + logger.debug(DEBUG_MESSAGE, "setUserConfig"); Set userConfig = userConfigRequest.getUserConfig(); for (final UserDTO config : userConfig) { diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index d11c4dc6cc2..7a9b87ef600 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -99,7 +99,7 @@ public void shouldInvokeDeleteUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users-delete", gson.toJson(this.user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users", gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); From b48abca0ec7790526a26b93614df098cbb1dd5b1 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 11:39:42 +0200 Subject: [PATCH 26/66] Changed getDefinedPermissions returned object --- .../provider/IdentityRestService.java | 5 ++-- .../identity/provider/dto/PermissionDTO.java | 29 +++++++++++++++++++ .../provider/test/IdentityEndpointsTest.java | 2 +- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/PermissionDTO.java diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index e39f9eaf657..8c58a8a2ad5 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -29,6 +29,7 @@ import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; import org.eclipse.kura.configuration.ConfigurationService; import org.eclipse.kura.crypto.CryptoService; +import org.eclipse.kura.internal.rest.identity.provider.dto.PermissionDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; import org.eclipse.kura.request.handler.jaxrs.DefaultExceptionHandler; @@ -131,10 +132,10 @@ public Response deleteUser(final UserDTO userName) { @RolesAllowed(REST_ROLE_NAME) @Path("/defined-permissions") @Produces(MediaType.APPLICATION_JSON) - public Set getDefinedPermissions() { + public PermissionDTO getDefinedPermissions() { try { logger.debug(DEBUG_MESSAGE, "getDefinedPermissions"); - return this.identityService.getDefinedPermissions(); + return new PermissionDTO(this.identityService.getDefinedPermissions()); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/PermissionDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/PermissionDTO.java new file mode 100644 index 00000000000..de6a7c89207 --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/PermissionDTO.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.dto; + +import java.util.Set; + +public class PermissionDTO { + + private final Set permissions; + + public PermissionDTO(Set permissions) { + this.permissions = permissions; + } + + public Set getPermissions() { + return permissions; + } + +} diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 7a9b87ef600..fd2e4fbf61b 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -112,7 +112,7 @@ public void shouldReturnDefinedPermissions() { whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); thenRequestSucceeds(); - thenResponseBodyEqualsJson("[\"perm1\",\"perm2\"]"); + thenResponseBodyEqualsJson("{\"permissions\": [\"perm1\",\"perm2\"]}"); } @Test From d6b82adc8575a9ff94096c464e830be1cf102a6e Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 11:47:50 +0200 Subject: [PATCH 27/66] Fixed methods name. --- .../provider/test/IdentityEndpointsTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index fd2e4fbf61b..30af0fb27ac 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -143,6 +143,14 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { thenRequestSucceeds(); } + private void givenUser(UserDTO user) { + this.user = user; + } + + private void givenUserConfigs(UserDTO... userConfigurations) { + userConfigs = new HashSet<>(Arrays.asList(userConfigurations)); + } + private void givenUserConfigRequest(UserDTO... userDTO) { this.userConfigRequest = new UserConfigDTO(); this.userConfigRequest.setUserConfig(new HashSet<>(Arrays.asList(userDTO))); @@ -187,11 +195,11 @@ private static void givenIdentityService() { @BeforeClass public static void setUp() throws Exception { - createidentityServiceMock(); - registeridentityServiceMock(); + createIdentityServiceMock(); + registerIdentityServiceMock(); } - private static void createidentityServiceMock() { + private static void createIdentityServiceMock() { givenIdentityService(); final Dictionary configurationServiceProperties = new Hashtable<>(); @@ -201,7 +209,7 @@ private static void createidentityServiceMock() { identityServiceMock, configurationServiceProperties); } - private static void registeridentityServiceMock() throws Exception { + private static void registerIdentityServiceMock() throws Exception { final Dictionary properties = new Hashtable<>(); properties.put("IdentityService.target", "(kura.service.pid=identityServiceMock)"); @@ -211,12 +219,4 @@ private static void registeridentityServiceMock() throws Exception { config.update(properties); } - private void givenUser(UserDTO user) { - this.user = user; - } - - private void givenUserConfigs(UserDTO... userConfigurations) { - userConfigs = new HashSet<>(Arrays.asList(userConfigurations)); - } - } From 5468cf2d215284958c3d8d6ad639f2afc5476260 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 12:01:29 +0200 Subject: [PATCH 28/66] fixed test --- .../provider/test/IdentityServiceTest.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java index 34e510df204..331c61ae0c9 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java @@ -70,6 +70,7 @@ public void shouldRegisterRequestHandler() throws KuraException { @Test public void shouldUnregisterRequestHandler() throws KuraException { givenMockRequestHandlerRegistry(); + givenBoundRequestHandlerRegistry(); whenUnbindRequestHandlerRegistry(); @@ -122,11 +123,11 @@ private void whenBindUserAdmin() { } private void whenBindRequestHandlerRegistry() { - try { - this.service.bindRequestHandlerRegistry(this.requestHandlerRegistry); - } catch (Exception e) { - this.occurredException = e; - } + bindRequestHandlerRegistry(); + } + + private void givenBoundRequestHandlerRegistry() { + bindRequestHandlerRegistry(); } private void whenUnbindRequestHandlerRegistry() { @@ -167,4 +168,12 @@ private void thenNoExceptionOccurred() { assertNull(errorMessage, this.occurredException); } + private void bindRequestHandlerRegistry() { + try { + this.service.bindRequestHandlerRegistry(this.requestHandlerRegistry); + } catch (Exception e) { + this.occurredException = e; + } + } + } From 10ac595ff11bfbe13e971095738b3fa9c1b8c080 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 12:30:46 +0200 Subject: [PATCH 29/66] Fixed absurd bug in test. --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 30af0fb27ac..394a880bb6d 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -56,6 +56,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static final String METHOD_SPEC_GET = "GET"; private static final String METHOD_SPEC_POST = "POST"; private static final String METHOD_SPEC_DELETE = "DELETE"; + private static final String MQTT_METHOD_SPEC_DEL = "DEL"; private static final String REST_APP_ID = "identity/v1"; private static IdentityService identityServiceMock = mock(IdentityService.class); @@ -99,7 +100,8 @@ public void shouldInvokeDeleteUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE), "/users", gson.toJson(this.user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", + gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); From 59e6f8401a94fcd77bf2eb6979aded1dd4a1a6ef Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 14:26:12 +0200 Subject: [PATCH 30/66] fixed identity.provider pom.xml --- kura/org.eclipse.kura.rest.identity.provider/pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/pom.xml b/kura/org.eclipse.kura.rest.identity.provider/pom.xml index 0db7f81734d..8acdb56d518 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/pom.xml +++ b/kura/org.eclipse.kura.rest.identity.provider/pom.xml @@ -25,8 +25,7 @@ ${project.basedir}/.. - - ${project.basedir}/../test/*/target/site/jacoco-aggregate/jacoco.xml + ${project.basedir}/../test/*/target/site/jacoco-aggregate/jacoco.xml org.eclipse.kura.rest.identity.provider From d64505b8255878d4b2333f3cafe6012c33a57d01 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 15:05:32 +0200 Subject: [PATCH 31/66] deleteUser has again a path parameter --- .../rest/identity/provider/IdentityRestService.java | 7 ++++--- .../rest/identity/provider/test/IdentityEndpointsTest.java | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 8c58a8a2ad5..f61c0fccf78 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -20,6 +20,7 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -115,12 +116,12 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) - @Path("/users") + @Path("/users/{userName}") @Consumes(MediaType.APPLICATION_JSON) - public Response deleteUser(final UserDTO userName) { + public Response deleteUser(@PathParam("userName") final String userName) { try { logger.debug(DEBUG_MESSAGE, "deleteUser"); - this.identityService.deleteUser(userName.getUserName()); + this.identityService.deleteUser(userName); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 394a880bb6d..62e79809814 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -100,8 +100,8 @@ public void shouldInvokeDeleteUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", - gson.toJson(this.user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), + "/users/" + this.user.getUserName()); thenRequestSucceeds(); thenResponseBodyIsEmpty(); From 8e4e3cdbfdf26c8fb1a06db23dfd4c422704cd22 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 15:11:46 +0200 Subject: [PATCH 32/66] Fixed deleteUser --- .../provider/IdentityRestService.java | 1 - .../provider/test/IdentityEndpointsTest.java | 27 ------------------- 2 files changed, 28 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index f61c0fccf78..897bc854d4a 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -117,7 +117,6 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) @Path("/users/{userName}") - @Consumes(MediaType.APPLICATION_JSON) public Response deleteUser(@PathParam("userName") final String userName) { try { logger.debug(DEBUG_MESSAGE, "deleteUser"); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 62e79809814..72feec8aa4b 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -168,33 +168,6 @@ private static void givenIdentityService() { when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); } - // @Test - // public void shouldRethrowWebApplicationExceptionOnReloadSecurityPolicyFingerprint() throws KuraException { - // givenFailingIdentityService(); - // - // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/security-policy-fingerprint/reload"); - // - // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); - // } - // - // @Test - // public void shouldRethrowWebApplicationExceptionOnReloadCommandLineFingerprint() throws KuraException { - // givenFailingIdentityService(); - // - // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/command-line-fingerprint/reload"); - // - // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); - // } - // - // @Test - // public void shouldRethrowWebApplicationExceptionOnGetDebugStatus() throws KuraException { - // givenFailingIdentityService(); - // - // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/debug-enabled"); - // - // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); - // } - @BeforeClass public static void setUp() throws Exception { createIdentityServiceMock(); From e6302124f64be120c4a460b19a4fe418fd700ed8 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 15:27:24 +0200 Subject: [PATCH 33/66] Revert "deleteUser has again a path parameter" This reverts commit fa214e87cb2669f139b350764280af2fed0b7e31. --- .../provider/IdentityRestService.java | 8 ++--- .../provider/test/IdentityEndpointsTest.java | 31 +++++++++++++++++-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 897bc854d4a..8c58a8a2ad5 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -20,7 +20,6 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; -import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -116,11 +115,12 @@ public Response createUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) - @Path("/users/{userName}") - public Response deleteUser(@PathParam("userName") final String userName) { + @Path("/users") + @Consumes(MediaType.APPLICATION_JSON) + public Response deleteUser(final UserDTO userName) { try { logger.debug(DEBUG_MESSAGE, "deleteUser"); - this.identityService.deleteUser(userName); + this.identityService.deleteUser(userName.getUserName()); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 72feec8aa4b..394a880bb6d 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -100,8 +100,8 @@ public void shouldInvokeDeleteUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), - "/users/" + this.user.getUserName()); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", + gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); @@ -168,6 +168,33 @@ private static void givenIdentityService() { when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); } + // @Test + // public void shouldRethrowWebApplicationExceptionOnReloadSecurityPolicyFingerprint() throws KuraException { + // givenFailingIdentityService(); + // + // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/security-policy-fingerprint/reload"); + // + // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); + // } + // + // @Test + // public void shouldRethrowWebApplicationExceptionOnReloadCommandLineFingerprint() throws KuraException { + // givenFailingIdentityService(); + // + // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/command-line-fingerprint/reload"); + // + // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); + // } + // + // @Test + // public void shouldRethrowWebApplicationExceptionOnGetDebugStatus() throws KuraException { + // givenFailingIdentityService(); + // + // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/debug-enabled"); + // + // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); + // } + @BeforeClass public static void setUp() throws Exception { createIdentityServiceMock(); From d7f500e9091bae992db96b4cd429376c7907e807 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 4 Oct 2023 15:27:44 +0200 Subject: [PATCH 34/66] removed comment --- .../provider/test/IdentityEndpointsTest.java | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 394a880bb6d..14c955326fc 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -168,33 +168,6 @@ private static void givenIdentityService() { when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); } - // @Test - // public void shouldRethrowWebApplicationExceptionOnReloadSecurityPolicyFingerprint() throws KuraException { - // givenFailingIdentityService(); - // - // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/security-policy-fingerprint/reload"); - // - // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); - // } - // - // @Test - // public void shouldRethrowWebApplicationExceptionOnReloadCommandLineFingerprint() throws KuraException { - // givenFailingIdentityService(); - // - // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/command-line-fingerprint/reload"); - // - // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); - // } - // - // @Test - // public void shouldRethrowWebApplicationExceptionOnGetDebugStatus() throws KuraException { - // givenFailingIdentityService(); - // - // whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/debug-enabled"); - // - // thenResponseCodeIs(Status.INTERNAL_SERVER_ERROR.getStatusCode()); - // } - @BeforeClass public static void setUp() throws Exception { createIdentityServiceMock(); From 4b8f3d23216ad993fcd47664e84d00ebba3a2966 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Thu, 5 Oct 2023 12:36:26 +0200 Subject: [PATCH 35/66] Fixed error and copyright --- .../OSGI-INF/IdentityRestService.xml | 2 +- .../validator/PasswordStrengthValidators.java | 2 +- .../provider/validator/PredicateValidator.java | 2 +- .../identity/provider/validator/RegexValidator.java | 2 +- .../rest/identity/provider/validator/Validator.java | 13 +++++++++++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml index 72b77ce4d3b..133898f0050 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml +++ b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml @@ -29,7 +29,7 @@ bind="bindCryptoService" cardinality="1..1" name="CryptoService" - policy="static" />/> + policy="static" /> Date: Mon, 9 Oct 2023 12:42:24 +0200 Subject: [PATCH 36/66] Fixed bug in UserAdminHelper#createUser --- .../java/org/eclipse/kura/util/useradmin/UserAdminHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java b/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java index fe21f7e64f5..449cc4b3fe0 100644 --- a/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java +++ b/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java @@ -123,7 +123,7 @@ public boolean isPasswordChangeRequired(final String username) { } public void createUser(final String userName) { - getOrCreateUser(getUserRoleName(userName)); + getOrCreateUser(userName); } public void deleteUser(final String userName) { From bb9d7d8a105845928a3c03f1c1a910e3784d09b0 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 12:50:13 +0200 Subject: [PATCH 37/66] Added check on requestHandlerMethod --- .../core/testutil/requesthandler/Transport.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/kura/test/org.eclipse.kura.core.testutil/src/main/java/org/eclipse/kura/core/testutil/requesthandler/Transport.java b/kura/test/org.eclipse.kura.core.testutil/src/main/java/org/eclipse/kura/core/testutil/requesthandler/Transport.java index 4167532c5c6..6a66df98268 100644 --- a/kura/test/org.eclipse.kura.core.testutil/src/main/java/org/eclipse/kura/core/testutil/requesthandler/Transport.java +++ b/kura/test/org.eclipse.kura.core.testutil/src/main/java/org/eclipse/kura/core/testutil/requesthandler/Transport.java @@ -49,19 +49,29 @@ public class MethodSpec { public MethodSpec(final String method) { this.requestHandlerMethod = method; this.restMethod = method; + + if (this.requestHandlerMethod.equalsIgnoreCase("DELETE")) { + throw new IllegalArgumentException( + "Method " + this.requestHandlerMethod + " is not allowed for RequestHandler"); + } } public MethodSpec(final String restMethod, final String requestHandlerMethod) { this.restMethod = restMethod; this.requestHandlerMethod = requestHandlerMethod; + + if (this.requestHandlerMethod.equalsIgnoreCase("DELETE")) { + throw new IllegalArgumentException( + "Method " + this.requestHandlerMethod + " is not allowed for RequestHandler"); + } } public String getRestMethod() { - return restMethod; + return this.restMethod; } public String getRequestHandlerMethod() { - return requestHandlerMethod; + return this.requestHandlerMethod; } } } From 56cea4f5ff249160134d42d7d1001ef9c2331fcd Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 14:42:23 +0200 Subject: [PATCH 38/66] Added new getUser method --- .../provider/IdentityRestService.java | 14 +++++++++++++ .../identity/provider/IdentityService.java | 10 +++++++++ .../provider/test/IdentityEndpointsTest.java | 21 +++++++++++++++++-- .../src/main/resources/getUserResponse.json | 6 ++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 8c58a8a2ad5..b4557e902f9 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -113,6 +113,20 @@ public Response createUser(final UserDTO userName) { return Response.ok().build(); } + @GET + @RolesAllowed(REST_ROLE_NAME) + @Path("/users") + @Consumes(MediaType.APPLICATION_JSON) + public UserDTO getUser(final UserDTO userName) { + try { + logger.debug(DEBUG_MESSAGE, "getUser"); + return this.identityService.getUser(userName.getUserName()); + } catch (Exception e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + + } + @DELETE @RolesAllowed(REST_ROLE_NAME) @Path("/users") diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index 5b03e75b10c..978b4835b3e 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import org.eclipse.kura.KuraErrorCode; @@ -68,6 +69,15 @@ public void deleteUser(String userName) { this.userAdminHelper.deleteUser(userName); } + public UserDTO getUser(String userName) throws KuraException { + Optional user = this.userAdminHelper.getUser(userName); + if (user.isPresent()) { + return initUserConfig(user.get()); + } else { + throw new KuraException(KuraErrorCode.NOT_FOUND, "user " + userName + " not found"); + } + } + public Set getDefinedPermissions() { return this.userAdminHelper.getDefinedPermissions(); } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 14c955326fc..c04721b32bd 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -65,10 +65,14 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private Gson gson = new Gson(); - private static final String EXPECTED_GET_USER_RESPONSE = new Scanner( + private static final String EXPECTED_GET_USER_CONFIG_RESPONSE = new Scanner( IdentityEndpointsTest.class.getResourceAsStream("/getUserConfigResponse.json"), "UTF-8").useDelimiter("\\A") .next().replace(" ", ""); + private static final String EXPECTED_GET_USER_RESPONSE = new Scanner( + IdentityEndpointsTest.class.getResourceAsStream("/getUserResponse.json"), "UTF-8").useDelimiter("\\A") + .next().replace(" ", ""); + private UserConfigDTO userConfigRequest; private static Set userConfigs; @@ -107,6 +111,19 @@ public void shouldInvokeDeleteUserSuccessfully() { thenResponseBodyIsEmpty(); } + @Test + public void shouldReturnUserSuccessfully() { + givenIdentityService(); + + givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", + gson.toJson(this.user)); + + thenRequestSucceeds(); + thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); + } + @Test public void shouldReturnDefinedPermissions() { givenIdentityService(); @@ -130,7 +147,7 @@ public void shouldReturnUserConfig() { whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); thenRequestSucceeds(); - thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); + thenResponseBodyEqualsJson(EXPECTED_GET_USER_CONFIG_RESPONSE); } @Test diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json new file mode 100644 index 00000000000..f82b0625cf8 --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json @@ -0,0 +1,6 @@ +{ + "userName": "testuser", + "passwordAuthEnabled": true, + "passwordChangeNeeded": false, + "permissions": [] +} \ No newline at end of file From fd0a9fab8e9270db56240494ff02099eb075d008 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 14:50:02 +0200 Subject: [PATCH 39/66] Fixed test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index c04721b32bd..ac299a486c5 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -117,8 +117,7 @@ public void shouldReturnUserSuccessfully() { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", - gson.toJson(this.user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET, METHOD_SPEC_GET), "/users", gson.toJson(this.user)); thenRequestSucceeds(); thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); From fd939393fd93bade122e1e764d9d2399cbb81b23 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 14:54:14 +0200 Subject: [PATCH 40/66] added missing @Produces annotation. --- .../internal/rest/identity/provider/IdentityRestService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index b4557e902f9..347f30400eb 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -117,6 +117,7 @@ public Response createUser(final UserDTO userName) { @RolesAllowed(REST_ROLE_NAME) @Path("/users") @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) public UserDTO getUser(final UserDTO userName) { try { logger.debug(DEBUG_MESSAGE, "getUser"); From 716cc992914e4cbd3adfc41b4e72b8bc67b1a61d Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 15:32:04 +0200 Subject: [PATCH 41/66] fixed test --- .../kura/util/useradmin/UserAdminHelper.java | 3 +- .../provider/test/IdentityEndpointsTest.java | 42 +++++++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java b/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java index 449cc4b3fe0..d4463e2864d 100644 --- a/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java +++ b/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java @@ -89,7 +89,6 @@ public void requirePermissions(final String username, final String... permission } } - @SuppressWarnings("unchecked") public void changeUserPassword(final String username, final String userPassword) throws AuthenticationException { final User user = getUser(username) .orElseThrow(() -> new AuthenticationException(AuthenticationException.Reason.USER_NOT_FOUND)); @@ -290,6 +289,8 @@ public void foreachPermission(final PermissionConsumer public static class AuthenticationException extends Exception { + private static final long serialVersionUID = -8534499595655286448L; + public enum Reason { USER_NOT_FOUND, INCORRECT_PASSWORD, diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index ac299a486c5..536fb347949 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -61,7 +61,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static IdentityService identityServiceMock = mock(IdentityService.class); - private UserDTO user; + private static UserDTO user; private Gson gson = new Gson(); @@ -77,7 +77,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static Set userConfigs; - @Parameterized.Parameters + @Parameterized.Parameters(name = "transport={index}") public static Collection transports() { return Arrays.asList(new RestTransport(REST_APP_ID), new MqttTransport(MQTT_APP_ID)); } @@ -87,44 +87,43 @@ public IdentityEndpointsTest(Transport transport) { } @Test - public void shouldInvokeCreateUserSuccessfully() { - givenIdentityService(); - + public void shouldInvokeCreateUserSuccessfully() throws KuraException { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users", gson.toJson(this.user)); + givenIdentityService(); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users", gson.toJson(user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); } @Test - public void shouldInvokeDeleteUserSuccessfully() { - givenIdentityService(); - + public void shouldInvokeDeleteUserSuccessfully() throws KuraException { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", - gson.toJson(this.user)); + givenIdentityService(); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", gson.toJson(user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); } @Test - public void shouldReturnUserSuccessfully() { - givenIdentityService(); - + public void shouldReturnUserSuccessfully() throws KuraException { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET, METHOD_SPEC_GET), "/users", gson.toJson(this.user)); + givenIdentityService(); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET, METHOD_SPEC_GET), "/users", gson.toJson(user)); thenRequestSucceeds(); thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); } @Test - public void shouldReturnDefinedPermissions() { + public void shouldReturnDefinedPermissions() throws KuraException { givenIdentityService(); whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); @@ -134,7 +133,7 @@ public void shouldReturnDefinedPermissions() { } @Test - public void shouldReturnUserConfig() { + public void shouldReturnUserConfig() throws KuraException { givenUserConfigs(new UserDTO("testuser2", // new HashSet(Arrays.asList("perm1", "perm2")), // false, // @@ -161,8 +160,8 @@ public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { thenRequestSucceeds(); } - private void givenUser(UserDTO user) { - this.user = user; + private void givenUser(UserDTO userParam) { + user = userParam; } private void givenUserConfigs(UserDTO... userConfigurations) { @@ -175,13 +174,14 @@ private void givenUserConfigRequest(UserDTO... userDTO) { } - private static void givenIdentityService() { + private static void givenIdentityService() throws KuraException { reset(identityServiceMock); when(identityServiceMock.getDefinedPermissions()) .thenReturn(new HashSet(Arrays.asList("perm1", "perm2"))); when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); + when(identityServiceMock.getUser(user.getUserName())).thenReturn(user); } @BeforeClass @@ -190,7 +190,7 @@ public static void setUp() throws Exception { registerIdentityServiceMock(); } - private static void createIdentityServiceMock() { + private static void createIdentityServiceMock() throws KuraException { givenIdentityService(); final Dictionary configurationServiceProperties = new Hashtable<>(); From 13e4e3d0b612f4e6d8e0041b3edcb9fdf4fde5a5 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 15:36:02 +0200 Subject: [PATCH 42/66] Fix test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 536fb347949..16f71d56229 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -181,7 +181,10 @@ private static void givenIdentityService() throws KuraException { .thenReturn(new HashSet(Arrays.asList("perm1", "perm2"))); when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); - when(identityServiceMock.getUser(user.getUserName())).thenReturn(user); + + if (user != null) { + when(identityServiceMock.getUser(user.getUserName())).thenReturn(user); + } } @BeforeClass From d8e53efba86fdcc823bebd6cbd563fa80fef4007 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 15:38:22 +0200 Subject: [PATCH 43/66] Fix test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 16f71d56229..9ecb40cd140 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -183,7 +183,8 @@ private static void givenIdentityService() throws KuraException { when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); if (user != null) { - when(identityServiceMock.getUser(user.getUserName())).thenReturn(user); + when(identityServiceMock.getUser(user.getUserName())) + .thenReturn(new UserDTO("testuser", Collections.emptySet(), true, false)); } } From 02238df0bcf2f866131fd3254cb08194bfdd81e5 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 16:42:39 +0200 Subject: [PATCH 44/66] YA Fix test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 6 +++--- .../src/main/resources/getUserResponse.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 9ecb40cd140..34b9950ee28 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -77,7 +77,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static Set userConfigs; - @Parameterized.Parameters(name = "transport={index}") + @Parameterized.Parameters public static Collection transports() { return Arrays.asList(new RestTransport(REST_APP_ID), new MqttTransport(MQTT_APP_ID)); } @@ -100,7 +100,7 @@ public void shouldInvokeCreateUserSuccessfully() throws KuraException { @Test public void shouldInvokeDeleteUserSuccessfully() throws KuraException { - givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); + givenUser(new UserDTO("testuser3", Collections.emptySet(), true, false, "testpassw3")); givenIdentityService(); @@ -184,7 +184,7 @@ private static void givenIdentityService() throws KuraException { if (user != null) { when(identityServiceMock.getUser(user.getUserName())) - .thenReturn(new UserDTO("testuser", Collections.emptySet(), true, false)); + .thenReturn(new UserDTO("testuser3", Collections.emptySet(), true, false)); } } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json index f82b0625cf8..2c63abc6cb2 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserResponse.json @@ -1,5 +1,5 @@ { - "userName": "testuser", + "userName": "testuser3", "passwordAuthEnabled": true, "passwordChangeNeeded": false, "permissions": [] From 47398f764bbc7a9393be97a53b01f8a33d52d353 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 16:47:06 +0200 Subject: [PATCH 45/66] YA Fix test --- .../identity/provider/test/IdentityEndpointsTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 34b9950ee28..b6062ebf301 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -100,7 +100,7 @@ public void shouldInvokeCreateUserSuccessfully() throws KuraException { @Test public void shouldInvokeDeleteUserSuccessfully() throws KuraException { - givenUser(new UserDTO("testuser3", Collections.emptySet(), true, false, "testpassw3")); + givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); givenIdentityService(); @@ -112,7 +112,7 @@ public void shouldInvokeDeleteUserSuccessfully() throws KuraException { @Test public void shouldReturnUserSuccessfully() throws KuraException { - givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); + givenUser(new UserDTO("testuser3", Collections.emptySet(), true, false)); givenIdentityService(); @@ -183,8 +183,11 @@ private static void givenIdentityService() throws KuraException { when(identityServiceMock.getUserConfig()).thenReturn(userConfigs); if (user != null) { - when(identityServiceMock.getUser(user.getUserName())) + when(identityServiceMock.getUser("testuser3")) .thenReturn(new UserDTO("testuser3", Collections.emptySet(), true, false)); + + when(identityServiceMock.getUser("testuser")) + .thenReturn(new UserDTO("testuser", Collections.emptySet(), true, false)); } } From 1a8a55e2f501a525ad784fa03ace2bbb3500c26c Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 17:14:14 +0200 Subject: [PATCH 46/66] added tearDown with @AfterClass --- .../provider/test/IdentityEndpointsTest.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index b6062ebf301..9d18638c36b 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -38,11 +38,13 @@ import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; import org.eclipse.kura.util.wire.test.WireTestUtil; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceRegistration; import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; @@ -77,6 +79,8 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static Set userConfigs; + private static ServiceRegistration identityServiceRegistration; + @Parameterized.Parameters public static Collection transports() { return Arrays.asList(new RestTransport(REST_APP_ID), new MqttTransport(MQTT_APP_ID)); @@ -197,14 +201,19 @@ public static void setUp() throws Exception { registerIdentityServiceMock(); } + @AfterClass + public static void tearDown() throws Exception { + unregisterIdentityServiceMock(); + } + private static void createIdentityServiceMock() throws KuraException { givenIdentityService(); final Dictionary configurationServiceProperties = new Hashtable<>(); configurationServiceProperties.put("service.ranking", Integer.MIN_VALUE); configurationServiceProperties.put("kura.service.pid", "identityServiceMock"); - FrameworkUtil.getBundle(IdentityEndpointsTest.class).getBundleContext().registerService(IdentityService.class, - identityServiceMock, configurationServiceProperties); + identityServiceRegistration = FrameworkUtil.getBundle(IdentityEndpointsTest.class).getBundleContext() + .registerService(IdentityService.class, identityServiceMock, configurationServiceProperties); } private static void registerIdentityServiceMock() throws Exception { @@ -217,4 +226,9 @@ private static void registerIdentityServiceMock() throws Exception { config.update(properties); } + private static void unregisterIdentityServiceMock() { + identityServiceRegistration.unregister(); + + } + } From d46c70cabafaa2eeeebd6192b7ccec304f032604 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 17:17:15 +0200 Subject: [PATCH 47/66] attempt to fix test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 6 ++---- .../src/main/resources/getUserConfigResponse.json | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 9d18638c36b..ccf1e98aa12 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -30,7 +30,6 @@ import org.eclipse.kura.KuraException; import org.eclipse.kura.core.testutil.requesthandler.AbstractRequestHandlerTest; import org.eclipse.kura.core.testutil.requesthandler.MqttTransport; -import org.eclipse.kura.core.testutil.requesthandler.RestTransport; import org.eclipse.kura.core.testutil.requesthandler.Transport; import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; @@ -83,7 +82,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { @Parameterized.Parameters public static Collection transports() { - return Arrays.asList(new RestTransport(REST_APP_ID), new MqttTransport(MQTT_APP_ID)); + return Arrays.asList(new MqttTransport(MQTT_APP_ID)); } public IdentityEndpointsTest(Transport transport) { @@ -141,8 +140,7 @@ public void shouldReturnUserConfig() throws KuraException { givenUserConfigs(new UserDTO("testuser2", // new HashSet(Arrays.asList("perm1", "perm2")), // false, // - true, // - "testpassw2")); + true)); givenIdentityService(); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json index 77fd6271e97..310d11e1349 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json @@ -8,7 +8,6 @@ "perm1", "perm2" ], - "password": "testpassw2" } ] } \ No newline at end of file From 4491b05809f7a2059d84921f7521c820c4ce4af8 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 17:18:50 +0200 Subject: [PATCH 48/66] fix getUserConfigResponse --- .../src/main/resources/getUserConfigResponse.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json index 310d11e1349..7393a1f4d66 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getUserConfigResponse.json @@ -7,7 +7,7 @@ "permissions": [ "perm1", "perm2" - ], + ] } ] } \ No newline at end of file From db64f390c9d0674ce4ea7a0ca280775fe4f494e1 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 17:21:13 +0200 Subject: [PATCH 49/66] changed tests order --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index ccf1e98aa12..c1eb660f336 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -30,6 +30,7 @@ import org.eclipse.kura.KuraException; import org.eclipse.kura.core.testutil.requesthandler.AbstractRequestHandlerTest; import org.eclipse.kura.core.testutil.requesthandler.MqttTransport; +import org.eclipse.kura.core.testutil.requesthandler.RestTransport; import org.eclipse.kura.core.testutil.requesthandler.Transport; import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; @@ -82,7 +83,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { @Parameterized.Parameters public static Collection transports() { - return Arrays.asList(new MqttTransport(MQTT_APP_ID)); + return Arrays.asList(new MqttTransport(MQTT_APP_ID), new RestTransport(REST_APP_ID)); } public IdentityEndpointsTest(Transport transport) { From e8370bb30c92d63fa23777a5afb507b1ca0b321c Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 9 Oct 2023 17:32:02 +0200 Subject: [PATCH 50/66] Added policy greedy --- .../OSGI-INF/IdentityRestService.xml | 3 ++- .../rest/identity/provider/test/IdentityEndpointsTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml index 133898f0050..65aa81044e9 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml +++ b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml @@ -41,7 +41,8 @@ bind="bindIdentityService" cardinality="0..1" name="IdentityService" - policy="static"/> + policy="static" + policy-option="greedy" /> diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index c1eb660f336..d8230dd2fca 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -81,7 +81,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static ServiceRegistration identityServiceRegistration; - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") public static Collection transports() { return Arrays.asList(new MqttTransport(MQTT_APP_ID), new RestTransport(REST_APP_ID)); } From 4c3369a223a15240e5c0ba1a141a87279fdbb44f Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 10 Oct 2023 18:01:07 +0200 Subject: [PATCH 51/66] Refactored API --- .../OSGI-INF/IdentityRestService.xml | 27 +++++---- .../provider/IdentityRestService.java | 55 ++++++++----------- .../identity/provider/IdentityService.java | 47 ++++++++-------- .../provider/test/IdentityEndpointsTest.java | 2 +- 4 files changed, 62 insertions(+), 69 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml index 65aa81044e9..10887b7fce0 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml +++ b/kura/org.eclipse.kura.rest.identity.provider/OSGI-INF/IdentityRestService.xml @@ -23,26 +23,31 @@ unbind="unbindRequestHandlerRegistry" cardinality="0..n" name="RequestHandlerRegistry" - policy="dynamic"/> + policy="dynamic" /> - + + + + policy="static" /> - + policy="static" /> @@ -50,6 +55,6 @@ + value="org.eclipse.kura.internal.rest.identity.provider.IdentityRestService" /> diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 347f30400eb..694d22d2d6f 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -12,19 +12,17 @@ ******************************************************************************/ package org.eclipse.kura.internal.rest.identity.provider; -import java.util.Set; - import javax.annotation.security.RolesAllowed; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.eclipse.kura.KuraException; import org.eclipse.kura.cloudconnection.request.RequestHandler; import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; import org.eclipse.kura.configuration.ConfigurationService; @@ -100,12 +98,12 @@ public void activate() { @POST @RolesAllowed(REST_ROLE_NAME) - @Path("/users") + @Path("/identities") @Consumes(MediaType.APPLICATION_JSON) public Response createUser(final UserDTO userName) { try { logger.debug(DEBUG_MESSAGE, "createUser"); - this.identityService.createUser(userName.getUserName()); + this.identityService.createUser(userName); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); } @@ -113,9 +111,24 @@ public Response createUser(final UserDTO userName) { return Response.ok().build(); } - @GET + @PUT @RolesAllowed(REST_ROLE_NAME) - @Path("/users") + @Path("/identities") + @Consumes(MediaType.APPLICATION_JSON) + public Response updateUser(final UserDTO user) { + try { + logger.debug(DEBUG_MESSAGE, "updateUser"); + this.identityService.updateUser(user); + } catch (Exception e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + + return Response.ok().build(); + } + + @POST + @RolesAllowed(REST_ROLE_NAME) + @Path("/identities/byName") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public UserDTO getUser(final UserDTO userName) { @@ -130,7 +143,7 @@ public UserDTO getUser(final UserDTO userName) { @DELETE @RolesAllowed(REST_ROLE_NAME) - @Path("/users") + @Path("/identities") @Consumes(MediaType.APPLICATION_JSON) public Response deleteUser(final UserDTO userName) { try { @@ -158,7 +171,7 @@ public PermissionDTO getDefinedPermissions() { @GET @RolesAllowed(REST_ROLE_NAME) - @Path("/users/configs") + @Path("/identities") @Produces(MediaType.APPLICATION_JSON) public UserConfigDTO getUserConfig() { try { @@ -171,28 +184,4 @@ public UserConfigDTO getUserConfig() { } } - @POST - @RolesAllowed(REST_ROLE_NAME) - @Path("/users/configs") - @Consumes(MediaType.APPLICATION_JSON) - public Response setUserConfig(UserConfigDTO userConfigRequest) { - try { - logger.debug(DEBUG_MESSAGE, "setUserConfig"); - Set userConfig = userConfigRequest.getUserConfig(); - - for (final UserDTO config : userConfig) { - final String newPassword = config.getPassword(); - - if (newPassword != null) { - this.identityService.validateUserPassword(newPassword); - } - } - this.identityService.setUserConfig(userConfig); - } catch (KuraException e) { - throw DefaultExceptionHandler.toWebApplicationException(e); - } - - return Response.ok().build(); - } - } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index 978b4835b3e..fb0a101d819 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -61,8 +61,13 @@ public IdentityService(CryptoService cryptoService, UserAdmin userAdmin, this.userAdminHelper = new UserAdminHelper(userAdmin, cryptoService); } - public void createUser(String userName) { - this.userAdminHelper.createUser(userName); + public void createUser(UserDTO user) throws KuraException { + if (!this.userAdminHelper.getUser(user.getUserName()).isPresent()) { + this.userAdminHelper.createUser(user.getUserName()); + this.updateUser(user); + } else { + throw new KuraException(KuraErrorCode.BAD_REQUEST, "user " + user.getUserName() + " already exists"); + } } public void deleteUser(String userName) { @@ -147,35 +152,27 @@ private static void forEach(final T[] items, final Fall } } - public void setUserConfig(Set userData) throws KuraException { - this.userAdminHelper.foreachUser((name, user) -> { - if (userData.stream().noneMatch(data -> data.getUserName().equals(name))) { - deleteUser(name); - } - }); + public void updateUser(UserDTO userDTO) throws KuraException { - this.userAdminHelper.foreachPermission((permissionName, permissionGroup) -> { - for (final UserDTO data : userData) { + final Optional user = this.userAdminHelper.getUser(userDTO.getUserName()); - final User user = this.userAdminHelper.getOrCreateUser(data.getUserName()); + if (user.isPresent()) { + this.userAdminHelper.foreachPermission((permissionName, permissionGroup) -> { - if (data.getPermissions() != null && data.getPermissions().contains(permissionName)) { - permissionGroup.addMember(user); + if (userDTO.getPermissions() != null && userDTO.getPermissions().contains(permissionName)) { + permissionGroup.addMember(user.get()); } else { - permissionGroup.removeMember(user); + permissionGroup.removeMember(user.get()); } - } - }); + }); - for (final UserDTO config : userData) { - final User user = this.userAdminHelper.getOrCreateUser(config.getUserName()); + final Dictionary credentials = user.get().getCredentials(); - final Dictionary credentials = user.getCredentials(); - - if (config.isPasswordAuthEnabled()) { - final String password = config.getPassword(); + if (userDTO.isPasswordAuthEnabled()) { + final String password = userDTO.getPassword(); if (password != null) { + this.validateUserPassword(password); try { credentials.put(PASSWORD_PROPERTY, this.cryptoService.sha256Hash(password)); } catch (final Exception e) { @@ -186,13 +183,15 @@ public void setUserConfig(Set userData) throws KuraException { credentials.remove(PASSWORD_PROPERTY); } - final Dictionary properties = user.getProperties(); + final Dictionary properties = user.get().getProperties(); - if (config.isPasswordChangeNeeded()) { + if (userDTO.isPasswordChangeNeeded()) { properties.put(KURA_NEED_PASSWORD_CHANGE, "true"); } else { properties.remove(KURA_NEED_PASSWORD_CHANGE); } + } else { + throw new KuraException(KuraErrorCode.NOT_FOUND, "user " + userDTO.getUserName() + " not found"); } } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index d8230dd2fca..60b0ad85203 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -120,7 +120,7 @@ public void shouldReturnUserSuccessfully() throws KuraException { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET, METHOD_SPEC_GET), "/users", gson.toJson(user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users-get", gson.toJson(user)); thenRequestSucceeds(); thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); From 9ab4e3c9d5ae6072a941579075b4ae88bb2e6c9c Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 17 Oct 2023 11:32:56 +0200 Subject: [PATCH 52/66] Test updated. --- .../provider/test/IdentityEndpointsTest.java | 40 +++++++++---------- .../provider/test/IdentityServiceTest.java | 36 +++++++++++++++-- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 60b0ad85203..a5fe5b9776c 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -59,6 +59,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static final String METHOD_SPEC_POST = "POST"; private static final String METHOD_SPEC_DELETE = "DELETE"; private static final String MQTT_METHOD_SPEC_DEL = "DEL"; + private static final String METHOD_SPEC_UPDATE = "UPDATE"; private static final String REST_APP_ID = "identity/v1"; private static IdentityService identityServiceMock = mock(IdentityService.class); @@ -96,44 +97,47 @@ public void shouldInvokeCreateUserSuccessfully() throws KuraException { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users", gson.toJson(user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/identities", gson.toJson(user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); } @Test - public void shouldInvokeDeleteUserSuccessfully() throws KuraException { + public void shouldInvokeUpdateUserSuccessfully() throws KuraException { givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/users", gson.toJson(user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_UPDATE), "/identities", gson.toJson(user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); } @Test - public void shouldReturnUserSuccessfully() throws KuraException { - givenUser(new UserDTO("testuser3", Collections.emptySet(), true, false)); + public void shouldInvokeDeleteUserSuccessfully() throws KuraException { + givenUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users-get", gson.toJson(user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, MQTT_METHOD_SPEC_DEL), "/identities", + gson.toJson(user)); thenRequestSucceeds(); - thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); + thenResponseBodyIsEmpty(); } @Test - public void shouldReturnDefinedPermissions() throws KuraException { + public void shouldReturnUserSuccessfully() throws KuraException { + givenUser(new UserDTO("testuser3", Collections.emptySet(), true, false)); + givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/identities/byName", gson.toJson(user)); thenRequestSucceeds(); - thenResponseBodyEqualsJson("{\"permissions\": [\"perm1\",\"perm2\"]}"); + thenResponseBodyEqualsJson(EXPECTED_GET_USER_RESPONSE); } @Test @@ -145,22 +149,20 @@ public void shouldReturnUserConfig() throws KuraException { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/users/configs"); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/identities"); thenRequestSucceeds(); thenResponseBodyEqualsJson(EXPECTED_GET_USER_CONFIG_RESPONSE); } @Test - public void shouldInvokeSetUserConfigSuccessfully() throws KuraException { - givenUserConfigRequest(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw"), new UserDTO( - "testuser2", new HashSet(Arrays.asList("perm1", "perm2")), false, true, "testpassw2")); - + public void shouldReturnDefinedPermissions() throws KuraException { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/users/configs", gson.toJson(this.userConfigRequest)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); thenRequestSucceeds(); + thenResponseBodyEqualsJson("{\"permissions\": [\"perm1\",\"perm2\"]}"); } private void givenUser(UserDTO userParam) { @@ -171,12 +173,6 @@ private void givenUserConfigs(UserDTO... userConfigurations) { userConfigs = new HashSet<>(Arrays.asList(userConfigurations)); } - private void givenUserConfigRequest(UserDTO... userDTO) { - this.userConfigRequest = new UserConfigDTO(); - this.userConfigRequest.setUserConfig(new HashSet<>(Arrays.asList(userDTO))); - - } - private static void givenIdentityService() throws KuraException { reset(identityServiceMock); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java index 331c61ae0c9..f8615fd2126 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java @@ -28,6 +28,8 @@ import org.eclipse.kura.KuraException; import org.eclipse.kura.cloudconnection.request.RequestHandler; import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; +import org.eclipse.kura.configuration.ConfigurationService; +import org.eclipse.kura.crypto.CryptoService; import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; import org.junit.Test; import org.osgi.service.useradmin.Role; @@ -41,6 +43,8 @@ public class IdentityServiceTest { private IdentityRestService service = new IdentityRestService(); private UserAdmin userAdmin; + private CryptoService cryptoService; + private ConfigurationService configurationService; private RequestHandlerRegistry requestHandlerRegistry; private Exception occurredException; @@ -95,10 +99,29 @@ public void shouldCatchExceptionsOnRequestHandlerUnbind() throws KuraException { thenNoExceptionOccurred(); } + @Test + public void shouldCreateIdentityService() throws KuraException { + givenMockUserAdmin(); + givenMockCryptoService(); + givenMockConfigurationService(); + + whenActivate(); + + thenNoExceptionOccurred(); + } + /* * Given */ + private void givenMockCryptoService() { + this.cryptoService = mock(CryptoService.class); + } + + private void givenMockConfigurationService() { + this.configurationService = mock(ConfigurationService.class); + } + private void givenMockUserAdmin() { this.userAdmin = mock(UserAdmin.class); } @@ -107,6 +130,10 @@ private void givenMockRequestHandlerRegistry() { this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); } + private void givenBoundRequestHandlerRegistry() { + bindRequestHandlerRegistry(); + } + private void givenFailingMockRequestHandlerRegistry() throws KuraException { this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); doThrow(new KuraException(KuraErrorCode.BAD_REQUEST)).when(this.requestHandlerRegistry) @@ -126,10 +153,6 @@ private void whenBindRequestHandlerRegistry() { bindRequestHandlerRegistry(); } - private void givenBoundRequestHandlerRegistry() { - bindRequestHandlerRegistry(); - } - private void whenUnbindRequestHandlerRegistry() { try { this.service.unbindRequestHandlerRegistry(this.requestHandlerRegistry); @@ -138,6 +161,11 @@ private void whenUnbindRequestHandlerRegistry() { } } + private void whenActivate() { + // TODO Auto-generated method stub + + } + /* * Then */ From 560eed4f13ee84ece2385b3bfacb9d3a971b6079 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Tue, 17 Oct 2023 11:50:25 +0200 Subject: [PATCH 53/66] Fixed test --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index a5fe5b9776c..7050ce569b6 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -35,7 +35,6 @@ import org.eclipse.kura.core.testutil.requesthandler.Transport.MethodSpec; import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; import org.eclipse.kura.internal.rest.identity.provider.IdentityService; -import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; import org.eclipse.kura.util.wire.test.WireTestUtil; import org.junit.AfterClass; @@ -59,7 +58,7 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { private static final String METHOD_SPEC_POST = "POST"; private static final String METHOD_SPEC_DELETE = "DELETE"; private static final String MQTT_METHOD_SPEC_DEL = "DEL"; - private static final String METHOD_SPEC_UPDATE = "UPDATE"; + private static final String METHOD_SPEC_PUT = "PUT"; private static final String REST_APP_ID = "identity/v1"; private static IdentityService identityServiceMock = mock(IdentityService.class); @@ -76,8 +75,6 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { IdentityEndpointsTest.class.getResourceAsStream("/getUserResponse.json"), "UTF-8").useDelimiter("\\A") .next().replace(" ", ""); - private UserConfigDTO userConfigRequest; - private static Set userConfigs; private static ServiceRegistration identityServiceRegistration; @@ -109,7 +106,7 @@ public void shouldInvokeUpdateUserSuccessfully() throws KuraException { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_UPDATE), "/identities", gson.toJson(user)); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_PUT), "/identities", gson.toJson(user)); thenRequestSucceeds(); thenResponseBodyIsEmpty(); From c53688d2faa23289d9619ddc815a2c32abd79cf6 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 25 Oct 2023 09:54:58 +0200 Subject: [PATCH 54/66] Added password validation before user creation. --- .../internal/rest/identity/provider/IdentityService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index fb0a101d819..d381f837cc1 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -63,6 +63,12 @@ public IdentityService(CryptoService cryptoService, UserAdmin userAdmin, public void createUser(UserDTO user) throws KuraException { if (!this.userAdminHelper.getUser(user.getUserName()).isPresent()) { + + final String password = user.getPassword(); + if (password != null) { + this.validateUserPassword(password); + } + this.userAdminHelper.createUser(user.getUserName()); this.updateUser(user); } else { From a2170628edb74a81ca32c634e97bd959f176fc99 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 25 Oct 2023 10:34:43 +0200 Subject: [PATCH 55/66] Fixed some bugs. Added new `/password-requirements` method. --- .../provider/IdentityRestService.java | 20 ++++++++ .../identity/provider/IdentityService.java | 17 +++++-- .../provider/dto/ValidatorOptionsDTO.java | 47 +++++++++++++++++++ .../provider/test/IdentityEndpointsTest.java | 14 ++++++ .../getPasswordRequirementsResponse.json | 6 +++ 5 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/ValidatorOptionsDTO.java create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 694d22d2d6f..582ebd32f6d 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -30,6 +30,8 @@ import org.eclipse.kura.internal.rest.identity.provider.dto.PermissionDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserConfigDTO; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; +import org.eclipse.kura.internal.rest.identity.provider.dto.ValidatorOptionsDTO; +import org.eclipse.kura.internal.rest.identity.provider.validator.ValidatorOptions; import org.eclipse.kura.request.handler.jaxrs.DefaultExceptionHandler; import org.eclipse.kura.request.handler.jaxrs.JaxRsRequestHandlerProxy; import org.osgi.service.useradmin.Role; @@ -184,4 +186,22 @@ public UserConfigDTO getUserConfig() { } } + @GET + @RolesAllowed(REST_ROLE_NAME) + @Path("/password-requirements") + @Produces(MediaType.APPLICATION_JSON) + public ValidatorOptionsDTO getValidatorOptions() { + try { + logger.debug(DEBUG_MESSAGE, "getValidatorOptions"); + ValidatorOptions validatorOptions = this.identityService.getValidatorOptions(); + return new ValidatorOptionsDTO(// + validatorOptions.getPasswordMinimumLength(), // + validatorOptions.getPasswordRequireDigits(), // + validatorOptions.getPasswordRequireBothCases(), // + validatorOptions.getPasswordRequireSpecialChars()); + } catch (Exception e) { + throw DefaultExceptionHandler.toWebApplicationException(e); + } + } + } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index d381f837cc1..07a65a27093 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -13,6 +13,7 @@ package org.eclipse.kura.internal.rest.identity.provider; import java.util.ArrayList; +import java.util.Collections; import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; @@ -83,7 +84,9 @@ public void deleteUser(String userName) { public UserDTO getUser(String userName) throws KuraException { Optional user = this.userAdminHelper.getUser(userName); if (user.isPresent()) { - return initUserConfig(user.get()); + UserDTO userFound = initUserConfig(user.get()); + fillPermissions(Collections.singletonMap(user.get().getName(), userFound)); + return userFound; } else { throw new KuraException(KuraErrorCode.NOT_FOUND, "user " + userName + " not found"); } @@ -204,10 +207,7 @@ public void updateUser(UserDTO userDTO) throws KuraException { public void validateUserPassword(String password) throws KuraException { - ComponentConfiguration consoleConfig = this.configurationService - .getComponentConfiguration(KURA_WEB_CONSOLE_SERVICE_PID); - - ValidatorOptions validatorOptions = new ValidatorOptions(consoleConfig.getConfigurationProperties()); + ValidatorOptions validatorOptions = getValidatorOptions(); final List> validators = PasswordStrengthValidators.fromConfig(validatorOptions); @@ -222,4 +222,11 @@ public void validateUserPassword(String password) throws KuraException { } } + public ValidatorOptions getValidatorOptions() throws KuraException { + ComponentConfiguration consoleConfig = this.configurationService + .getComponentConfiguration(KURA_WEB_CONSOLE_SERVICE_PID); + + return new ValidatorOptions(consoleConfig.getConfigurationProperties()); + + } } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/ValidatorOptionsDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/ValidatorOptionsDTO.java new file mode 100644 index 00000000000..2161dee9ceb --- /dev/null +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/ValidatorOptionsDTO.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.dto; + +public class ValidatorOptionsDTO { + + private final int passwordMinimumLength; + private final boolean passwordRequireDigits; + private final boolean passwordRequireSpecialChars; + private final boolean passwordRequireBothCases; + + public ValidatorOptionsDTO(int passwordMinimumLength, boolean passwordRequireDigits, + boolean passwordRequireBothCases, boolean passwordRequireSpecialChars) { + + this.passwordMinimumLength = passwordMinimumLength; + this.passwordRequireDigits = passwordRequireDigits; + this.passwordRequireSpecialChars = passwordRequireSpecialChars; + this.passwordRequireBothCases = passwordRequireBothCases; + } + + public int getPasswordMinimumLength() { + return this.passwordMinimumLength; + } + + public boolean isPasswordRequireDigits() { + return this.passwordRequireDigits; + } + + public boolean isPasswordRequireSpecialChars() { + return this.passwordRequireSpecialChars; + } + + public boolean isPasswordRequireBothCases() { + return this.passwordRequireBothCases; + } + +} diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 7050ce569b6..99dc667f257 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -75,6 +75,10 @@ public class IdentityEndpointsTest extends AbstractRequestHandlerTest { IdentityEndpointsTest.class.getResourceAsStream("/getUserResponse.json"), "UTF-8").useDelimiter("\\A") .next().replace(" ", ""); + private static final String EXPECTED_GET_PASSWORD_REQUIREMENTS_RESPONSE = new Scanner( + IdentityEndpointsTest.class.getResourceAsStream("/getPasswordRequirementsResponse.json"), "UTF-8") + .useDelimiter("\\A").next().replace(" ", ""); + private static Set userConfigs; private static ServiceRegistration identityServiceRegistration; @@ -162,6 +166,16 @@ public void shouldReturnDefinedPermissions() throws KuraException { thenResponseBodyEqualsJson("{\"permissions\": [\"perm1\",\"perm2\"]}"); } + @Test + public void shouldReturnPasswordRequirements() throws KuraException { + givenIdentityService(); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/password-requirements"); + + thenRequestSucceeds(); + thenResponseBodyEqualsJson(EXPECTED_GET_PASSWORD_REQUIREMENTS_RESPONSE); + } + private void givenUser(UserDTO userParam) { user = userParam; } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json new file mode 100644 index 00000000000..321605ff7a0 --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json @@ -0,0 +1,6 @@ +{ + "passwordMinimumLength": 8, + "passwordRequireDigits": false, + "passwordRequireBothCases": false, + "passwordRequireSpecialChars": false +} \ No newline at end of file From c954e92cfa4abbd4c24bd9f5789f20cb753e9cf7 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 25 Oct 2023 10:50:52 +0200 Subject: [PATCH 56/66] Added missing method to mock. --- .../rest/identity/provider/test/IdentityEndpointsTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 99dc667f257..32534d0f67f 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -36,6 +36,7 @@ import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; import org.eclipse.kura.internal.rest.identity.provider.IdentityService; import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; +import org.eclipse.kura.internal.rest.identity.provider.validator.ValidatorOptions; import org.eclipse.kura.util.wire.test.WireTestUtil; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -199,6 +200,8 @@ private static void givenIdentityService() throws KuraException { when(identityServiceMock.getUser("testuser")) .thenReturn(new UserDTO("testuser", Collections.emptySet(), true, false)); } + + when(identityServiceMock.getValidatorOptions()).thenReturn(new ValidatorOptions(8, false, false, false)); } @BeforeClass From 330afc58290077faf8a6914e0c9c73fdde3d3204 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 25 Oct 2023 10:54:26 +0200 Subject: [PATCH 57/66] Fixed expected json --- .../src/main/resources/getPasswordRequirementsResponse.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json index 321605ff7a0..2568733c6e1 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/resources/getPasswordRequirementsResponse.json @@ -1,6 +1,6 @@ { "passwordMinimumLength": 8, "passwordRequireDigits": false, - "passwordRequireBothCases": false, - "passwordRequireSpecialChars": false + "passwordRequireSpecialChars": false, + "passwordRequireBothCases": false } \ No newline at end of file From 434d93aa761e6c63110e061f9a7808a821b2c2fc Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Wed, 25 Oct 2023 11:55:05 +0200 Subject: [PATCH 58/66] Refactored updateUser to reduce complexity. --- .../identity/provider/IdentityService.java | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index 07a65a27093..03c709ab895 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -161,48 +161,50 @@ private static void forEach(final T[] items, final Fall } } - public void updateUser(UserDTO userDTO) throws KuraException { + public void updateUser(UserDTO userDTOToUpdate) throws KuraException { - final Optional user = this.userAdminHelper.getUser(userDTO.getUserName()); + final Optional user = this.userAdminHelper.getUser(userDTOToUpdate.getUserName()); if (user.isPresent()) { this.userAdminHelper.foreachPermission((permissionName, permissionGroup) -> { - if (userDTO.getPermissions() != null && userDTO.getPermissions().contains(permissionName)) { + if (userDTOToUpdate.getPermissions() != null && userDTOToUpdate.getPermissions().contains(permissionName)) { permissionGroup.addMember(user.get()); } else { permissionGroup.removeMember(user.get()); } }); - final Dictionary credentials = user.get().getCredentials(); + updatePasswordOptions(userDTOToUpdate, user.get().getCredentials(), user.get().getProperties()); + } else { + throw new KuraException(KuraErrorCode.NOT_FOUND, "user " + userDTOToUpdate.getUserName() + " not found"); + } - if (userDTO.isPasswordAuthEnabled()) { - final String password = userDTO.getPassword(); + } - if (password != null) { - this.validateUserPassword(password); - try { - credentials.put(PASSWORD_PROPERTY, this.cryptoService.sha256Hash(password)); - } catch (final Exception e) { - throw new KuraException(KuraErrorCode.SERVICE_UNAVAILABLE, e); - } - } - } else { - credentials.remove(PASSWORD_PROPERTY); - } + private void updatePasswordOptions(UserDTO userDTO, final Dictionary credentials, + final Dictionary properties) throws KuraException { - final Dictionary properties = user.get().getProperties(); + if (userDTO.isPasswordAuthEnabled()) { + final String password = userDTO.getPassword(); - if (userDTO.isPasswordChangeNeeded()) { - properties.put(KURA_NEED_PASSWORD_CHANGE, "true"); - } else { - properties.remove(KURA_NEED_PASSWORD_CHANGE); + if (password != null) { + this.validateUserPassword(password); + try { + credentials.put(PASSWORD_PROPERTY, this.cryptoService.sha256Hash(password)); + } catch (final Exception e) { + throw new KuraException(KuraErrorCode.SERVICE_UNAVAILABLE, e); + } } } else { - throw new KuraException(KuraErrorCode.NOT_FOUND, "user " + userDTO.getUserName() + " not found"); + credentials.remove(PASSWORD_PROPERTY); } + if (userDTO.isPasswordChangeNeeded()) { + properties.put(KURA_NEED_PASSWORD_CHANGE, "true"); + } else { + properties.remove(KURA_NEED_PASSWORD_CHANGE); + } } public void validateUserPassword(String password) throws KuraException { From 8aedff824b4cf1bb29d4064fde0b4366636dab44 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola <83589980+salvatore-coppola@users.noreply.github.com> Date: Fri, 27 Oct 2023 11:02:50 +0200 Subject: [PATCH 59/66] fixed test --- .../rest/packages/provider/test/PackagesRestServiceTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kura/test/org.eclipse.kura.rest.packages.provider.test/src/main/java/org/eclipse/kura/rest/packages/provider/test/PackagesRestServiceTest.java b/kura/test/org.eclipse.kura.rest.packages.provider.test/src/main/java/org/eclipse/kura/rest/packages/provider/test/PackagesRestServiceTest.java index d78199d2c76..b3fb272e261 100644 --- a/kura/test/org.eclipse.kura.rest.packages.provider.test/src/main/java/org/eclipse/kura/rest/packages/provider/test/PackagesRestServiceTest.java +++ b/kura/test/org.eclipse.kura.rest.packages.provider.test/src/main/java/org/eclipse/kura/rest/packages/provider/test/PackagesRestServiceTest.java @@ -145,7 +145,7 @@ public void installShouldWorkWithValidURLWhenARequestWasAlreadyIssued() { @Test public void uninstallShouldWorkWithValidPackageName() { - whenRequestIsPerformed(new MethodSpec("DELETE"), "/testPackage"); + whenRequestIsPerformed(new MethodSpec("DELETE", "DEL"), "/testPackage"); thenRequestSucceeds(); @@ -158,7 +158,7 @@ public void uninstallShouldWorkWithValidPackageName() { public void uninstallShouldWorkWithValidPackageNameWhenARequestWasAlreadyIssued() { givenAnUninstallationRequestWasAlreadyIssuedFor("testPackage"); - whenRequestIsPerformed(new MethodSpec("DELETE"), "/testPackage"); + whenRequestIsPerformed(new MethodSpec("DELETE", "DEL"), "/testPackage"); thenRequestSucceeds(); From ad4558c4276aceef132948836fe6d1e82d4f3a8b Mon Sep 17 00:00:00 2001 From: Nicola Timeus Date: Mon, 30 Oct 2023 15:44:58 +0100 Subject: [PATCH 60/66] Keep original identity field values if they are not specified Signed-off-by: Nicola Timeus --- .../identity/provider/IdentityService.java | 59 ++++++++++++------- .../rest/identity/provider/dto/UserDTO.java | 13 ++-- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index 03c709ab895..e95d9103dbf 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -166,14 +166,20 @@ public void updateUser(UserDTO userDTOToUpdate) throws KuraException { final Optional user = this.userAdminHelper.getUser(userDTOToUpdate.getUserName()); if (user.isPresent()) { - this.userAdminHelper.foreachPermission((permissionName, permissionGroup) -> { + final Set permissions = userDTOToUpdate.getPermissions(); - if (userDTOToUpdate.getPermissions() != null && userDTOToUpdate.getPermissions().contains(permissionName)) { - permissionGroup.addMember(user.get()); - } else { - permissionGroup.removeMember(user.get()); - } - }); + if (permissions != null) { + + this.userAdminHelper.foreachPermission((permissionName, permissionGroup) -> { + + if (permissions.contains(permissionName)) { + permissionGroup.addMember(user.get()); + } else { + permissionGroup.removeMember(user.get()); + } + }); + + } updatePasswordOptions(userDTOToUpdate, user.get().getCredentials(), user.get().getProperties()); } else { @@ -185,26 +191,37 @@ public void updateUser(UserDTO userDTOToUpdate) throws KuraException { private void updatePasswordOptions(UserDTO userDTO, final Dictionary credentials, final Dictionary properties) throws KuraException { - if (userDTO.isPasswordAuthEnabled()) { - final String password = userDTO.getPassword(); + final Optional isPasswordAuthEnabledParam = userDTO.isPasswordAuthEnabled(); - if (password != null) { - this.validateUserPassword(password); - try { - credentials.put(PASSWORD_PROPERTY, this.cryptoService.sha256Hash(password)); - } catch (final Exception e) { - throw new KuraException(KuraErrorCode.SERVICE_UNAVAILABLE, e); + if (isPasswordAuthEnabledParam.isPresent()) { + + if (Boolean.TRUE.equals(isPasswordAuthEnabledParam.get())) { + final String password = userDTO.getPassword(); + + if (password != null) { + this.validateUserPassword(password); + try { + credentials.put(PASSWORD_PROPERTY, this.cryptoService.sha256Hash(password)); + } catch (final Exception e) { + throw new KuraException(KuraErrorCode.SERVICE_UNAVAILABLE, e); + } } + } else { + credentials.remove(PASSWORD_PROPERTY); } - } else { - credentials.remove(PASSWORD_PROPERTY); } - if (userDTO.isPasswordChangeNeeded()) { - properties.put(KURA_NEED_PASSWORD_CHANGE, "true"); - } else { - properties.remove(KURA_NEED_PASSWORD_CHANGE); + final Optional isPasswordChangeNeededParam = userDTO.isPasswordChangeNeeded(); + + if (isPasswordChangeNeededParam.isPresent()) { + + if (Boolean.TRUE.equals(isPasswordChangeNeededParam.get())) { + properties.put(KURA_NEED_PASSWORD_CHANGE, "true"); + } else { + properties.remove(KURA_NEED_PASSWORD_CHANGE); + } } + } public void validateUserPassword(String password) throws KuraException { diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java index b8fba33514b..73295d61ee0 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java @@ -12,13 +12,14 @@ *******************************************************************************/ package org.eclipse.kura.internal.rest.identity.provider.dto; +import java.util.Optional; import java.util.Set; public class UserDTO { private String userName; - private boolean passwordAuthEnabled; - private boolean passwordChangeNeeded; + private Boolean passwordAuthEnabled; + private Boolean passwordChangeNeeded; private Set permissions; private String password; @@ -51,16 +52,16 @@ public void setUserName(String userName) { this.userName = userName; } - public boolean isPasswordAuthEnabled() { - return passwordAuthEnabled; + public Optional isPasswordAuthEnabled() { + return Optional.ofNullable(passwordAuthEnabled); } public void setPasswordAuthEnabled(boolean passwordAuthEnabled) { this.passwordAuthEnabled = passwordAuthEnabled; } - public boolean isPasswordChangeNeeded() { - return passwordChangeNeeded; + public Optional isPasswordChangeNeeded() { + return Optional.ofNullable(passwordChangeNeeded); } public void setPasswordChangeNeeded(boolean passwordChangeNeeded) { From b1a6d000605c88a8a441fc67464163e2f3fcf44b Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 30 Oct 2023 16:33:26 +0100 Subject: [PATCH 61/66] Added tests and several minor fixes. --- .../provider/IdentityRestService.java | 10 +- .../identity/provider/IdentityService.java | 14 +- .../rest/identity/provider/dto/UserDTO.java | 18 + .../validator/PasswordStrengthValidators.java | 8 +- .../provider/validator/ValidatorOptions.java | 8 +- .../kura/util/useradmin/UserAdminHelper.java | 3 +- .../IdentityRestServiceDependenciesTest.java | 221 ++++++++++ .../provider/test/IdentityServiceTest.java | 413 ++++++++++++++---- 8 files changed, 586 insertions(+), 109 deletions(-) create mode 100644 kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 582ebd32f6d..0113ef83aab 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -159,7 +159,6 @@ public Response deleteUser(final UserDTO userName) { } @GET - @RolesAllowed(REST_ROLE_NAME) @Path("/defined-permissions") @Produces(MediaType.APPLICATION_JSON) public PermissionDTO getDefinedPermissions() { @@ -187,7 +186,6 @@ public UserConfigDTO getUserConfig() { } @GET - @RolesAllowed(REST_ROLE_NAME) @Path("/password-requirements") @Produces(MediaType.APPLICATION_JSON) public ValidatorOptionsDTO getValidatorOptions() { @@ -195,10 +193,10 @@ public ValidatorOptionsDTO getValidatorOptions() { logger.debug(DEBUG_MESSAGE, "getValidatorOptions"); ValidatorOptions validatorOptions = this.identityService.getValidatorOptions(); return new ValidatorOptionsDTO(// - validatorOptions.getPasswordMinimumLength(), // - validatorOptions.getPasswordRequireDigits(), // - validatorOptions.getPasswordRequireBothCases(), // - validatorOptions.getPasswordRequireSpecialChars()); + validatorOptions.isPasswordMinimumLength(), // + validatorOptions.isPasswordRequireDigits(), // + validatorOptions.isPasswordRequireBothCases(), // + validatorOptions.isPasswordRequireSpecialChars()); } catch (Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index e95d9103dbf..1aa7f219970 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -45,9 +45,7 @@ public class IdentityService { private static final String PERMISSION_ROLE_NAME_PREFIX = "kura.permission."; private static final String USER_ROLE_NAME_PREFIX = "kura.user."; - private static final String PASSWORD_PROPERTY = "kura.password"; private static final String KURA_NEED_PASSWORD_CHANGE_PROPERTY = "kura.need.password.change"; - private static final String KURA_NEED_PASSWORD_CHANGE = "kura.need.password.change"; private UserAdminHelper userAdminHelper; private ConfigurationService configurationService; @@ -113,7 +111,8 @@ public Set getUserConfig() { private UserDTO initUserConfig(final User user) { - final boolean isPasswordEnabled = user.getCredentials().get(PASSWORD_PROPERTY) instanceof String; + final boolean isPasswordEnabled = user.getCredentials() + .get(KURA_NEED_PASSWORD_CHANGE_PROPERTY) instanceof String; final boolean isPasswordChangeRequired = Objects.equals("true", user.getProperties().get(KURA_NEED_PASSWORD_CHANGE_PROPERTY)); @@ -201,13 +200,13 @@ private void updatePasswordOptions(UserDTO userDTO, final Dictionary> fromConfig(final ValidatorOptions userOpti public static List> fromConfig(final ValidatorOptions userOptions, final Messages messages) { final List> result = new ArrayList<>(); - final int minPasswordLength = userOptions.getPasswordMinimumLength(); + final int minPasswordLength = userOptions.isPasswordMinimumLength(); if (minPasswordLength > 0) { result.add(passwordLengthValidator(minPasswordLength, messages)); } - if (userOptions.getPasswordRequireDigits()) { + if (userOptions.isPasswordRequireDigits()) { result.add(containsDigitsValidator(messages)); } - if (userOptions.getPasswordRequireBothCases()) { + if (userOptions.isPasswordRequireBothCases()) { result.add(containsBothCases(messages)); } - if (userOptions.getPasswordRequireSpecialChars()) { + if (userOptions.isPasswordRequireSpecialChars()) { result.add(containsSpecialChars(messages)); } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java index 5c898ae1b84..fc6109bd78a 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java @@ -51,19 +51,19 @@ public ValidatorOptions(Map configurationProperties) { } } - public int getPasswordMinimumLength() { + public int isPasswordMinimumLength() { return this.passwordMinimumLength; } - public boolean getPasswordRequireDigits() { + public boolean isPasswordRequireDigits() { return this.passwordRequireDigits; } - public boolean getPasswordRequireBothCases() { + public boolean isPasswordRequireBothCases() { return this.passwordRequireBothCases; } - public boolean getPasswordRequireSpecialChars() { + public boolean isPasswordRequireSpecialChars() { return this.passwordRequireSpecialChars; } diff --git a/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java b/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java index d4463e2864d..7dc67086ee9 100644 --- a/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java +++ b/kura/org.eclipse.kura.util/src/main/java/org/eclipse/kura/util/useradmin/UserAdminHelper.java @@ -122,7 +122,8 @@ public boolean isPasswordChangeRequired(final String username) { } public void createUser(final String userName) { - getOrCreateUser(userName); + User createdUser = getOrCreateUser(userName); + Objects.requireNonNull(createdUser, "Could not create user " + userName); } public void deleteUser(final String userName) { diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java new file mode 100644 index 00000000000..bc10649af30 --- /dev/null +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2023 Eurotech and/or its affiliates and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eurotech + *******************************************************************************/ +package org.eclipse.kura.internal.rest.identity.provider.test; + +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Objects; + +import org.eclipse.kura.KuraErrorCode; +import org.eclipse.kura.KuraException; +import org.eclipse.kura.cloudconnection.request.RequestHandler; +import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; +import org.eclipse.kura.configuration.ConfigurationService; +import org.eclipse.kura.crypto.CryptoService; +import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; +import org.junit.Test; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.UserAdmin; + +public class IdentityRestServiceDependenciesTest { + + private static final String MQTT_APP_ID = "ID-V1"; + private static final String REST_ROLE_NAME = "identity"; + private static final String KURA_PERMISSION_REST_ROLE = "kura.permission.rest." + REST_ROLE_NAME; + + private IdentityRestService service = new IdentityRestService(); + private UserAdmin userAdmin; + private CryptoService cryptoService; + private ConfigurationService configurationService; + + private RequestHandlerRegistry requestHandlerRegistry; + private Exception occurredException; + + /* + * Scenarios + */ + + @Test + public void shouldCreateRoleOnUserAdminBinding() { + givenMockUserAdmin(); + + whenBindUserAdmin(); + + thenRoleIsCreated(KURA_PERMISSION_REST_ROLE, Role.GROUP); + } + + @Test + public void shouldRegisterRequestHandler() throws KuraException { + givenMockRequestHandlerRegistry(); + + whenBindRequestHandlerRegistry(); + + thenRequestHandlerIsRegistered(MQTT_APP_ID); + } + + @Test + public void shouldUnregisterRequestHandler() throws KuraException { + givenMockRequestHandlerRegistry(); + givenBoundRequestHandlerRegistry(); + + whenUnbindRequestHandlerRegistry(); + + thenRequestHandlerIsUnregistered(MQTT_APP_ID); + } + + @Test + public void shouldCatchExceptionsOnRequestHandlerBind() throws KuraException { + givenFailingMockRequestHandlerRegistry(); + + whenBindRequestHandlerRegistry(); + + thenNoExceptionOccurred(); + } + + @Test + public void shouldCatchExceptionsOnRequestHandlerUnbind() throws KuraException { + givenFailingMockRequestHandlerRegistry(); + + whenUnbindRequestHandlerRegistry(); + + thenNoExceptionOccurred(); + } + + @Test + public void shouldCreateIdentityService() throws KuraException { + givenMockUserAdmin(); + givenMockCryptoService(); + givenMockConfigurationService(); + givenBoundCryptoService(); + givensBoundConfigurationService(); + givenBoundUserAdmin(); + + whenActivate(); + + thenNoExceptionOccurred(); + } + + /* + * Given + */ + + private void givenMockCryptoService() { + this.cryptoService = mock(CryptoService.class); + } + + private void givenMockConfigurationService() { + this.configurationService = mock(ConfigurationService.class); + } + + private void givenMockUserAdmin() { + this.userAdmin = mock(UserAdmin.class); + } + + private void givenBoundCryptoService() { + this.service.bindCryptoService(this.cryptoService); + } + + private void givensBoundConfigurationService() { + this.service.bindConfigurationService(this.configurationService); + } + + private void givenBoundUserAdmin() { + this.service.bindUserAdmin(this.userAdmin); + } + + private void givenMockRequestHandlerRegistry() { + this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); + } + + private void givenBoundRequestHandlerRegistry() { + bindRequestHandlerRegistry(); + } + + private void givenFailingMockRequestHandlerRegistry() throws KuraException { + this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); + doThrow(new KuraException(KuraErrorCode.BAD_REQUEST)).when(this.requestHandlerRegistry) + .registerRequestHandler(any(), any()); + doThrow(new KuraException(KuraErrorCode.BAD_REQUEST)).when(this.requestHandlerRegistry).unregister(any()); + } + + /* + * When + */ + + private void whenBindUserAdmin() { + this.service.bindUserAdmin(this.userAdmin); + } + + private void whenBindRequestHandlerRegistry() { + bindRequestHandlerRegistry(); + } + + private void whenUnbindRequestHandlerRegistry() { + try { + this.service.unbindRequestHandlerRegistry(this.requestHandlerRegistry); + } catch (Exception e) { + this.occurredException = e; + } + } + + private void whenActivate() { + this.service.activate(); + } + + /* + * Then + */ + + private void thenRoleIsCreated(String expectedKuraPermission, int expectedRole) { + verify(this.userAdmin, times(1)).createRole(expectedKuraPermission, expectedRole); + } + + private void thenRequestHandlerIsRegistered(String expectedMqttAppId) throws KuraException { + verify(this.requestHandlerRegistry, times(1)).registerRequestHandler(eq(expectedMqttAppId), + any(RequestHandler.class)); + } + + private void thenRequestHandlerIsUnregistered(String expectedMqttAppId) throws KuraException { + verify(this.requestHandlerRegistry, times(1)).unregister(expectedMqttAppId); + } + + private void thenNoExceptionOccurred() { + String errorMessage = "Empty message"; + if (Objects.nonNull(this.occurredException)) { + StringWriter sw = new StringWriter(); + this.occurredException.printStackTrace(new PrintWriter(sw)); + + errorMessage = String.format("No exception expected, \"%s\" found. Caused by: %s", + this.occurredException.getClass().getName(), sw.toString()); + } + + assertNull(errorMessage, this.occurredException); + } + + private void bindRequestHandlerRegistry() { + try { + this.service.bindRequestHandlerRegistry(this.requestHandlerRegistry); + } catch (Exception e) { + this.occurredException = e; + } + } + +} diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java index f8615fd2126..491b4da11fe 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java @@ -1,186 +1,319 @@ /******************************************************************************* * Copyright (c) 2023 Eurotech and/or its affiliates and others - * + * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Eurotech *******************************************************************************/ package org.eclipse.kura.internal.rest.identity.provider.test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doThrow; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.io.PrintWriter; import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; import java.util.Objects; +import java.util.Set; -import org.eclipse.kura.KuraErrorCode; import org.eclipse.kura.KuraException; -import org.eclipse.kura.cloudconnection.request.RequestHandler; -import org.eclipse.kura.cloudconnection.request.RequestHandlerRegistry; +import org.eclipse.kura.configuration.ComponentConfiguration; import org.eclipse.kura.configuration.ConfigurationService; import org.eclipse.kura.crypto.CryptoService; -import org.eclipse.kura.internal.rest.identity.provider.IdentityRestService; +import org.eclipse.kura.internal.rest.identity.provider.IdentityService; +import org.eclipse.kura.internal.rest.identity.provider.dto.UserDTO; +import org.eclipse.kura.internal.rest.identity.provider.validator.ValidatorOptions; import org.junit.Test; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Group; import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; public class IdentityServiceTest { - private static final String MQTT_APP_ID = "ID-V1"; - private static final String REST_ROLE_NAME = "identity"; - private static final String KURA_PERMISSION_REST_ROLE = "kura.permission.rest." + REST_ROLE_NAME; + private static final String KURA_WEB_CONSOLE_SERVICE_PID = "org.eclipse.kura.web.Console"; + private static final String USER_ROLE_NAME_PREFIX = "kura.user."; + private static final String PERMISSION_ROLE_NAME_PREFIX = "kura.permission."; + + private IdentityService identityService; + private Exception occurredException; + private UserDTO user; + private UserDTO newUser; - private IdentityRestService service = new IdentityRestService(); - private UserAdmin userAdmin; private CryptoService cryptoService; + private UserAdmin userAdmin; private ConfigurationService configurationService; - private RequestHandlerRegistry requestHandlerRegistry; - private Exception occurredException; + private Set definedPermissions; + private Set userConfig; + private boolean isPasswordValid; + private ValidatorOptions validatorOptions; + + @Test + public void shouldCreateAnUser() throws KuraException { + givenIdentityService(); + + whenCreatingUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - /* - * Scenarios - */ + thenNoExceptionOccurred(); + thenUserIsCreated(); + } @Test - public void shouldCreateRoleOnUserAdminBinding() { - givenMockUserAdmin(); + public void shouldDeleteExistingUser() { + givenIdentityService(); + givenExistingUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenBindUserAdmin(); + whenDeleting("testuser"); - thenRoleIsCreated(KURA_PERMISSION_REST_ROLE, Role.GROUP); + thenNoExceptionOccurred(); + thenUserIsDeleted(); } @Test - public void shouldRegisterRequestHandler() throws KuraException { - givenMockRequestHandlerRegistry(); + public void shouldGetDefinedPermissions() throws InvalidSyntaxException { + givenIdentityService(); + givenExistingPermissions(new PermissionRole("perm1"), new PermissionRole("perm2")); + + whenGettingDefinedPermissions(); - whenBindRequestHandlerRegistry(); + thenNoExceptionOccurred(); + thenPermissionsAre("perm1", "perm2"); - thenRequestHandlerIsRegistered(MQTT_APP_ID); } @Test - public void shouldUnregisterRequestHandler() throws KuraException { - givenMockRequestHandlerRegistry(); - givenBoundRequestHandlerRegistry(); + public void shoulGetUser() { + givenIdentityService(); + givenExistingUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); + + whenGettingUser("testuser"); - whenUnbindRequestHandlerRegistry(); + thenNoExceptionOccurred(); + thenUserIs("testuser"); - thenRequestHandlerIsUnregistered(MQTT_APP_ID); + } + + private void whenGettingUser(String username) { + try { + this.user = this.identityService.getUser(username); + } catch (KuraException e) { + this.occurredException = e; + } } @Test - public void shouldCatchExceptionsOnRequestHandlerBind() throws KuraException { - givenFailingMockRequestHandlerRegistry(); + public void shouldGetUserConfig() { + givenIdentityService(); + givenExistingUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenBindRequestHandlerRegistry(); + whenGetUserConfig(); thenNoExceptionOccurred(); + thenConfigContains(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); } @Test - public void shouldCatchExceptionsOnRequestHandlerUnbind() throws KuraException { - givenFailingMockRequestHandlerRegistry(); + public void shouldGetValidatorOptions() { + givenIdentityService(); - whenUnbindRequestHandlerRegistry(); + whenGettingValidatorOptions(); thenNoExceptionOccurred(); + thenValidatorOptionsAre(8, false, false, false); + + } + + private void thenValidatorOptionsAre(int passwordMinimumLength, boolean passwordRequireDigits, + boolean passwordRequireBothCases, boolean passwordRequireSpecialChars) { + + assertEquals(passwordMinimumLength, this.validatorOptions.isPasswordMinimumLength()); + assertEquals(passwordRequireDigits, this.validatorOptions.isPasswordRequireDigits()); + assertEquals(passwordRequireBothCases, this.validatorOptions.isPasswordRequireBothCases()); + assertEquals(passwordRequireSpecialChars, this.validatorOptions.isPasswordRequireSpecialChars()); + } @Test - public void shouldCreateIdentityService() throws KuraException { - givenMockUserAdmin(); - givenMockCryptoService(); - givenMockConfigurationService(); + public void shouldUpdatedUser() throws InvalidSyntaxException { + givenIdentityService(); + givenExistingUser(new UserDTO("testuser", Collections.emptySet(), true, false, "testpassw")); - whenActivate(); + whenUpdatingUser(new UserDTO("testuser", Collections.emptySet(), true, true, "testpassw2")); thenNoExceptionOccurred(); + thenUserIsUpdated(); } - /* - * Given - */ + @Test + public void shouldValidateRightPassword() { + givenIdentityService(); + + whenValidatingPassword("password123"); - private void givenMockCryptoService() { - this.cryptoService = mock(CryptoService.class); + thenNoExceptionOccurred(); + thenPasswordValidationIs(true); } - private void givenMockConfigurationService() { - this.configurationService = mock(ConfigurationService.class); + @Test + public void shouldNotValidateWrongPassword() { + givenIdentityService(); + + whenValidatingPassword("short"); + + thenPasswordValidationIs(false); + } + + private void whenValidatingPassword(String password) { + try { + this.identityService.validateUserPassword(password); + this.isPasswordValid = true; + } catch (Exception e) { + this.isPasswordValid = false; + this.occurredException = e; + } } - private void givenMockUserAdmin() { + private void givenIdentityService() { + this.cryptoService = mock(CryptoService.class); this.userAdmin = mock(UserAdmin.class); + this.configurationService = mock(ConfigurationService.class); + + ComponentConfiguration mockWebConsoleConfiguration = mock(ComponentConfiguration.class); + when(mockWebConsoleConfiguration.getConfigurationProperties()).thenReturn(defaultValidatorProperties()); + + try { + when(this.configurationService.getComponentConfiguration(KURA_WEB_CONSOLE_SERVICE_PID)) + .thenReturn(mockWebConsoleConfiguration); + + when(this.cryptoService.sha256Hash(anyString())).thenReturn("sha256hash"); + } catch (KuraException | NoSuchAlgorithmException | UnsupportedEncodingException e) { + fail("fail to setup mocks"); + } + + this.identityService = new IdentityService(this.cryptoService, this.userAdmin, this.configurationService); + + } + + private void givenExistingUser(UserDTO user) { + this.user = user; + + UserImpl userImpl = new UserImpl(this.user.getUserName(), this.user.getPassword(), + this.user.isPasswordChangeNeeded().get()); + + try { + when(this.userAdmin.getRole(USER_ROLE_NAME_PREFIX + user.getUserName())).thenReturn(userImpl); + when(this.userAdmin.getRoles(null)).thenReturn(new Role[] { userImpl }); + } catch (InvalidSyntaxException e) { + fail("unable to setup mock user admin"); + } } - private void givenMockRequestHandlerRegistry() { - this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); + private void givenExistingPermissions(Role... roles) throws InvalidSyntaxException { + when(this.userAdmin.getRoles(null)).thenReturn(roles); } - private void givenBoundRequestHandlerRegistry() { - bindRequestHandlerRegistry(); + private void whenCreatingUser(UserDTO newUser) { + try { + this.newUser = newUser; + when(this.userAdmin.createRole(USER_ROLE_NAME_PREFIX + newUser.getUserName(), Role.USER)).then(anser -> { + + User userImpl = new UserImpl(newUser.getUserName(), newUser.getPassword(), + newUser.isPasswordChangeNeeded().get()); + + when(this.userAdmin.getRole(USER_ROLE_NAME_PREFIX + newUser.getUserName())).thenReturn(userImpl); + + return userImpl; + }); + this.identityService.createUser(this.newUser); + } catch (Exception e) { + this.occurredException = e; + } } - private void givenFailingMockRequestHandlerRegistry() throws KuraException { - this.requestHandlerRegistry = mock(RequestHandlerRegistry.class); - doThrow(new KuraException(KuraErrorCode.BAD_REQUEST)).when(this.requestHandlerRegistry) - .registerRequestHandler(any(), any()); - doThrow(new KuraException(KuraErrorCode.BAD_REQUEST)).when(this.requestHandlerRegistry).unregister(any()); + private void whenDeleting(String username) { + try { + this.identityService.deleteUser(username); + } catch (Exception e) { + this.occurredException = e; + } } - /* - * When - */ + private void whenGettingDefinedPermissions() { + this.definedPermissions = this.identityService.getDefinedPermissions(); + } - private void whenBindUserAdmin() { - this.service.bindUserAdmin(this.userAdmin); + private void whenGetUserConfig() { + this.userConfig = this.identityService.getUserConfig(); } - private void whenBindRequestHandlerRegistry() { - bindRequestHandlerRegistry(); + private void whenGettingValidatorOptions() { + try { + this.validatorOptions = this.identityService.getValidatorOptions(); + } catch (Exception e) { + this.occurredException = e; + } + } - private void whenUnbindRequestHandlerRegistry() { + private void whenUpdatingUser(UserDTO user) { + this.user = user; try { - this.service.unbindRequestHandlerRegistry(this.requestHandlerRegistry); + this.identityService.updateUser(user); } catch (Exception e) { this.occurredException = e; } } - private void whenActivate() { - // TODO Auto-generated method stub + private void thenUserIsCreated() throws KuraException { + verify(this.userAdmin, times(1)).createRole(USER_ROLE_NAME_PREFIX + this.newUser.getUserName(), Role.USER); + } + + private void thenUserIsDeleted() { + verify(this.userAdmin, times(1)).removeRole(USER_ROLE_NAME_PREFIX + this.user.getUserName()); + } + private void thenPermissionsAre(String... permissions) { + assertTrue(new HashSet<>(this.definedPermissions).containsAll(Arrays.asList(permissions))); } - /* - * Then - */ + private void thenUserIs(String username) { + assertEquals(username, this.user.getUserName()); + } - private void thenRoleIsCreated(String expectedKuraPermission, int expectedRole) { - verify(this.userAdmin, times(1)).createRole(expectedKuraPermission, expectedRole); + private void thenConfigContains(UserDTO userDTO) { + assertTrue(this.userConfig.contains(userDTO)); } - private void thenRequestHandlerIsRegistered(String expectedMqttAppId) throws KuraException { - verify(this.requestHandlerRegistry, times(1)).registerRequestHandler(eq(expectedMqttAppId), - any(RequestHandler.class)); + private void thenUserIsUpdated() throws InvalidSyntaxException { + verify(this.userAdmin, times(1)).getRole(USER_ROLE_NAME_PREFIX + this.user.getUserName()); + verify(this.userAdmin, times(1)).getRoles(null); } - private void thenRequestHandlerIsUnregistered(String expectedMqttAppId) throws KuraException { - verify(this.requestHandlerRegistry, times(1)).unregister(expectedMqttAppId); + private void thenPasswordValidationIs(boolean expectedValue) { + assertEquals(expectedValue, this.isPasswordValid); + } private void thenNoExceptionOccurred() { @@ -196,12 +329,118 @@ private void thenNoExceptionOccurred() { assertNull(errorMessage, this.occurredException); } - private void bindRequestHandlerRegistry() { - try { - this.service.bindRequestHandlerRegistry(this.requestHandlerRegistry); - } catch (Exception e) { - this.occurredException = e; + public static class PermissionRole implements Group { + + private final String name; + + public PermissionRole(String name) { + this.name = name; + } + + @Override + public String getName() { + return PERMISSION_ROLE_NAME_PREFIX + this.name; + + } + + @Override + public int getType() { + return Role.GROUP; + } + + @Override + public Dictionary getProperties() { + return null; + } + + @Override + public Dictionary getCredentials() { + return null; + } + + @Override + public boolean hasCredential(String key, Object value) { + return false; } + + @Override + public boolean addMember(Role role) { + return false; + } + + @Override + public boolean addRequiredMember(Role role) { + return false; + } + + @Override + public boolean removeMember(Role role) { + return false; + } + + @Override + public Role[] getMembers() { + return null; + } + + @Override + public Role[] getRequiredMembers() { + return null; + } + } + + public static class UserImpl implements User { + + private final String name; + private final String password; + private final boolean needPasswordChange; + + public UserImpl(String name, String password, boolean needPasswordChange) { + this.name = name; + this.password = password; + this.needPasswordChange = needPasswordChange; + } + + @Override + public String getName() { + return USER_ROLE_NAME_PREFIX + this.name; + } + + @Override + public int getType() { + return Role.USER; + } + + @Override + public Dictionary getProperties() { + Dictionary properties = new Hashtable(); + properties.put("kura.need.password.change", this.needPasswordChange); + return properties; + } + + @Override + public boolean hasCredential(String key, Object value) { + return true; + } + + @Override + public Dictionary getCredentials() { + Dictionary credentials = new Hashtable(); + credentials.put("kura.password", this.password); + + return credentials; + } + } + + private static Map defaultValidatorProperties() { + Map properties = new HashMap(); + + properties.put("new.password.min.length", 8); + properties.put("new.password.require.digits", false); + properties.put("new.password.require.special.characters", false); + properties.put("new.password.require.both.cases", false); + + return properties; } } From 5795eaa6feea6177aaecf1336c7261a7f61465cd Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 30 Oct 2023 16:50:15 +0100 Subject: [PATCH 62/66] Added rest.identity permission configuration in the snapshot_0.xml files. --- .../resources/common/snapshots/snapshot_0.xml-generic-device | 2 +- .../src/main/resources/common/snapshots/snapshot_0.xml-intelup2 | 2 +- .../main/resources/common/snapshots/snapshot_0.xml-jetson-nano | 2 +- kura/distrib/src/main/resources/docker-x86_64-nn/snapshot_0.xml | 2 +- .../src/main/resources/intel-up2-ubuntu-20-nn/snapshot_0.xml | 2 +- .../src/main/resources/intel-up2-ubuntu-20/snapshot_0.xml | 2 +- .../src/main/resources/nvidia-jetson-nano-nn/snapshot_0.xml | 2 +- .../src/main/resources/nvidia-jetson-nano/snapshot_0.xml | 2 +- .../src/main/resources/raspberry-pi-arm64-nn/snapshot_0.xml | 2 +- .../src/main/resources/raspberry-pi-arm64/snapshot_0.xml | 2 +- .../src/main/resources/raspberry-pi-armhf-nn/snapshot_0.xml | 2 +- .../src/main/resources/raspberry-pi-armhf/snapshot_0.xml | 2 +- .../src/main/resources/Kura_Emulator.launch | 1 + 13 files changed, 13 insertions(+), 12 deletions(-) diff --git a/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-generic-device b/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-generic-device index 29670978426..14a9bd0dcc3 100644 --- a/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-generic-device +++ b/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-generic-device @@ -463,7 +463,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.netadmin","credentials":{"kura.password":"3PgDKAMCxgRWBHiT1dEBS97bPqt7xckgdwrADJiDoWg="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.network.status"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.network.status"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-intelup2 b/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-intelup2 index f3f8a2f67cb..a4c1d4d21de 100644 --- a/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-intelup2 +++ b/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-intelup2 @@ -456,7 +456,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.netadmin","credentials":{"kura.password":"3PgDKAMCxgRWBHiT1dEBS97bPqt7xckgdwrADJiDoWg="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.network.status"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.network.status"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-jetson-nano b/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-jetson-nano index 74c8789dd62..68f53811ecc 100644 --- a/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-jetson-nano +++ b/kura/distrib/src/main/resources/common/snapshots/snapshot_0.xml-jetson-nano @@ -382,7 +382,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.netadmin","credentials":{"kura.password":"3PgDKAMCxgRWBHiT1dEBS97bPqt7xckgdwrADJiDoWg="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.network.status"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.network.status"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/docker-x86_64-nn/snapshot_0.xml b/kura/distrib/src/main/resources/docker-x86_64-nn/snapshot_0.xml index dddb15e1b1c..61e4baff5dd 100644 --- a/kura/distrib/src/main/resources/docker-x86_64-nn/snapshot_0.xml +++ b/kura/distrib/src/main/resources/docker-x86_64-nn/snapshot_0.xml @@ -337,7 +337,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/intel-up2-ubuntu-20-nn/snapshot_0.xml b/kura/distrib/src/main/resources/intel-up2-ubuntu-20-nn/snapshot_0.xml index 6255c44abda..e21af1902ef 100644 --- a/kura/distrib/src/main/resources/intel-up2-ubuntu-20-nn/snapshot_0.xml +++ b/kura/distrib/src/main/resources/intel-up2-ubuntu-20-nn/snapshot_0.xml @@ -337,7 +337,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/intel-up2-ubuntu-20/snapshot_0.xml b/kura/distrib/src/main/resources/intel-up2-ubuntu-20/snapshot_0.xml index 8302ecc48db..0042581a93e 100644 --- a/kura/distrib/src/main/resources/intel-up2-ubuntu-20/snapshot_0.xml +++ b/kura/distrib/src/main/resources/intel-up2-ubuntu-20/snapshot_0.xml @@ -444,7 +444,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.netadmin","credentials":{"kura.password":"3PgDKAMCxgRWBHiT1dEBS97bPqt7xckgdwrADJiDoWg="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/nvidia-jetson-nano-nn/snapshot_0.xml b/kura/distrib/src/main/resources/nvidia-jetson-nano-nn/snapshot_0.xml index fdd079c85fe..c005116d6ea 100644 --- a/kura/distrib/src/main/resources/nvidia-jetson-nano-nn/snapshot_0.xml +++ b/kura/distrib/src/main/resources/nvidia-jetson-nano-nn/snapshot_0.xml @@ -337,7 +337,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/nvidia-jetson-nano/snapshot_0.xml b/kura/distrib/src/main/resources/nvidia-jetson-nano/snapshot_0.xml index 7a9f0f12ac2..2e9a0d149e9 100644 --- a/kura/distrib/src/main/resources/nvidia-jetson-nano/snapshot_0.xml +++ b/kura/distrib/src/main/resources/nvidia-jetson-nano/snapshot_0.xml @@ -373,7 +373,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.netadmin","credentials":{"kura.password":"3PgDKAMCxgRWBHiT1dEBS97bPqt7xckgdwrADJiDoWg="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/raspberry-pi-arm64-nn/snapshot_0.xml b/kura/distrib/src/main/resources/raspberry-pi-arm64-nn/snapshot_0.xml index f1bdd9f72af..18d21c321fd 100644 --- a/kura/distrib/src/main/resources/raspberry-pi-arm64-nn/snapshot_0.xml +++ b/kura/distrib/src/main/resources/raspberry-pi-arm64-nn/snapshot_0.xml @@ -337,7 +337,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/raspberry-pi-arm64/snapshot_0.xml b/kura/distrib/src/main/resources/raspberry-pi-arm64/snapshot_0.xml index 388c288513e..abc777d9a1c 100644 --- a/kura/distrib/src/main/resources/raspberry-pi-arm64/snapshot_0.xml +++ b/kura/distrib/src/main/resources/raspberry-pi-arm64/snapshot_0.xml @@ -460,7 +460,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.netadmin","credentials":{"kura.password":"3PgDKAMCxgRWBHiT1dEBS97bPqt7xckgdwrADJiDoWg="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/raspberry-pi-armhf-nn/snapshot_0.xml b/kura/distrib/src/main/resources/raspberry-pi-armhf-nn/snapshot_0.xml index 6b6f5b62b49..779d189e36f 100644 --- a/kura/distrib/src/main/resources/raspberry-pi-armhf-nn/snapshot_0.xml +++ b/kura/distrib/src/main/resources/raspberry-pi-armhf-nn/snapshot_0.xml @@ -337,7 +337,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.device"},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/distrib/src/main/resources/raspberry-pi-armhf/snapshot_0.xml b/kura/distrib/src/main/resources/raspberry-pi-armhf/snapshot_0.xml index 9801677fef5..0344ff7e6b6 100644 --- a/kura/distrib/src/main/resources/raspberry-pi-armhf/snapshot_0.xml +++ b/kura/distrib/src/main/resources/raspberry-pi-armhf/snapshot_0.xml @@ -466,7 +466,7 @@ [{"name":"kura.user.admin","credentials":{"kura.password":"jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.appadmin","credentials":{"kura.password":"3hPckF8Zc+IF3pVineBvck3zJERUl8itosySULE1hpM="},"properties":{"kura.need.password.change":"true"}},{"name":"kura.user.netadmin","credentials":{"kura.password":"3PgDKAMCxgRWBHiT1dEBS97bPqt7xckgdwrADJiDoWg="},"properties":{"kura.need.password.change":"true"}}] - [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] + [{"name":"kura.permission.kura.admin","basicMembers":["kura.user.admin"]},{"name":"kura.permission.kura.cloud.connection.admin","basicMembers":["kura.user.appadmin","kura.user.netadmin"]},{"name":"kura.permission.kura.device","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.maintenance"},{"name":"kura.permission.kura.network.admin","basicMembers":["kura.user.netadmin"]},{"name":"kura.permission.kura.packages.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.kura.wires.admin","basicMembers":["kura.user.appadmin"]},{"name":"kura.permission.rest.assets"},{"name":"kura.permission.rest.command"},{"name":"kura.permission.rest.configuration"},{"name":"kura.permission.rest.identity"},{"name":"kura.permission.rest.inventory"},{"name":"kura.permission.rest.keystores"},{"name":"kura.permission.rest.position"},{"name":"kura.permission.rest.system"},{"name":"kura.permission.rest.tamper.detection"},{"name":"kura.permission.rest.wires.admin"}] diff --git a/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch b/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch index c351f8160db..4ca6c724318 100644 --- a/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch +++ b/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch @@ -153,6 +153,7 @@ + From 9c44038bbb1debc00424e84207f3ec2c48f97b67 Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 30 Oct 2023 16:56:10 +0100 Subject: [PATCH 63/66] Added rest.identity.provider to emulator configuration --- kura/distrib/src/main/resources/common/Kura_Emulator.launch | 1 + .../src/main/resources/Kura_Emulator.launch | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kura/distrib/src/main/resources/common/Kura_Emulator.launch b/kura/distrib/src/main/resources/common/Kura_Emulator.launch index 745e715ca0c..b8a5ab73635 100644 --- a/kura/distrib/src/main/resources/common/Kura_Emulator.launch +++ b/kura/distrib/src/main/resources/common/Kura_Emulator.launch @@ -150,6 +150,7 @@ + diff --git a/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch b/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch index 4ca6c724318..ec702361a37 100644 --- a/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch +++ b/kura/emulator/org.eclipse.kura.emulator/src/main/resources/Kura_Emulator.launch @@ -149,11 +149,11 @@ + - From 436145ed429167707ef30c63092294bfa316edbc Mon Sep 17 00:00:00 2001 From: Salvatore Coppola Date: Mon, 30 Oct 2023 17:17:13 +0100 Subject: [PATCH 64/66] Applied cleanup --- .../provider/IdentityRestService.java | 6 ++--- .../identity/provider/IdentityService.java | 12 +++++----- .../identity/provider/dto/PermissionDTO.java | 2 +- .../identity/provider/dto/UserConfigDTO.java | 2 +- .../rest/identity/provider/dto/UserDTO.java | 22 +++++++++---------- .../validator/PredicateValidator.java | 6 ++--- .../provider/validator/Validator.java | 6 ++--- .../provider/validator/ValidatorOptions.java | 8 +++---- .../IdentityRestServiceDependenciesTest.java | 8 +++---- .../provider/test/IdentityServiceTest.java | 6 ++--- 10 files changed, 39 insertions(+), 39 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 0113ef83aab..88bd90df8f1 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright (c) 2023 Eurotech and/or its affiliates and others - * + * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Eurotech ******************************************************************************/ diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index 1aa7f219970..8e9db3f67d2 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -47,9 +47,9 @@ public class IdentityService { private static final String KURA_NEED_PASSWORD_CHANGE_PROPERTY = "kura.need.password.change"; - private UserAdminHelper userAdminHelper; - private ConfigurationService configurationService; - private CryptoService cryptoService; + private final UserAdminHelper userAdminHelper; + private final ConfigurationService configurationService; + private final CryptoService cryptoService; public IdentityService(CryptoService cryptoService, UserAdmin userAdmin, ConfigurationService configurationService) { @@ -65,11 +65,11 @@ public void createUser(UserDTO user) throws KuraException { final String password = user.getPassword(); if (password != null) { - this.validateUserPassword(password); + validateUserPassword(password); } this.userAdminHelper.createUser(user.getUserName()); - this.updateUser(user); + updateUser(user); } else { throw new KuraException(KuraErrorCode.BAD_REQUEST, "user " + user.getUserName() + " already exists"); } @@ -198,7 +198,7 @@ private void updatePasswordOptions(UserDTO userDTO, final Dictionary permissions) { } public Set getPermissions() { - return permissions; + return this.permissions; } } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigDTO.java index 9cec0b017d4..289d24cbfde 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigDTO.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserConfigDTO.java @@ -20,7 +20,7 @@ public class UserConfigDTO { private Set userConfig = new HashSet<>(); public Set getUserConfig() { - return userConfig; + return this.userConfig; } public void setUserConfig(Set userConfig) { diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java index c93f4cd9cfa..dbe7df943a5 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/dto/UserDTO.java @@ -46,7 +46,7 @@ public UserDTO(final String userName, final Set permissions, final boole } public String getUserName() { - return userName; + return this.userName; } public void setUserName(String userName) { @@ -54,7 +54,7 @@ public void setUserName(String userName) { } public Optional isPasswordAuthEnabled() { - return Optional.ofNullable(passwordAuthEnabled); + return Optional.ofNullable(this.passwordAuthEnabled); } public void setPasswordAuthEnabled(boolean passwordAuthEnabled) { @@ -62,7 +62,7 @@ public void setPasswordAuthEnabled(boolean passwordAuthEnabled) { } public Optional isPasswordChangeNeeded() { - return Optional.ofNullable(passwordChangeNeeded); + return Optional.ofNullable(this.passwordChangeNeeded); } public void setPasswordChangeNeeded(boolean passwordChangeNeeded) { @@ -70,7 +70,7 @@ public void setPasswordChangeNeeded(boolean passwordChangeNeeded) { } public Set getPermissions() { - return permissions; + return this.permissions; } public void setPermissions(Set permissions) { @@ -78,7 +78,7 @@ public void setPermissions(Set permissions) { } public String getPassword() { - return password; + return this.password; } public void setPassword(String password) { @@ -87,19 +87,19 @@ public void setPassword(String password) { @Override public int hashCode() { - return Objects.hash(userName); + return Objects.hash(this.userName); } @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) + } + if ((obj == null) || (getClass() != obj.getClass())) { return false; + } UserDTO other = (UserDTO) obj; - return Objects.equals(userName, other.userName); + return Objects.equals(this.userName, other.userName); } } diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java index 208743d450d..00d651fddd7 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/PredicateValidator.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright (c) 2023 Eurotech and/or its affiliates and others - * + * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Eurotech *******************************************************************************/ diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java index 39bb2529a0b..99e3956fe96 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/Validator.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright (c) 2023 Eurotech and/or its affiliates and others - * + * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Eurotech *******************************************************************************/ diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java index fc6109bd78a..d65ff7d4f5f 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/validator/ValidatorOptions.java @@ -44,10 +44,10 @@ public ValidatorOptions(int passwordMinimumLength, boolean passwordRequireDigits public ValidatorOptions(Map configurationProperties) { if (configurationProperties != null) { - this.passwordMinimumLength = newPasswMinLenghthProperty.get(configurationProperties); - this.passwordRequireDigits = newPassRequireDigits.get(configurationProperties); - this.passwordRequireSpecialChars = newPassRequireSpecialChars.get(configurationProperties); - this.passwordRequireBothCases = newPassRequireBothCases.get(configurationProperties); + this.passwordMinimumLength = this.newPasswMinLenghthProperty.get(configurationProperties); + this.passwordRequireDigits = this.newPassRequireDigits.get(configurationProperties); + this.passwordRequireSpecialChars = this.newPassRequireSpecialChars.get(configurationProperties); + this.passwordRequireBothCases = this.newPassRequireBothCases.get(configurationProperties); } } diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java index bc10649af30..2c372d03981 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright (c) 2023 Eurotech and/or its affiliates and others - * + * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Eurotech *******************************************************************************/ @@ -41,7 +41,7 @@ public class IdentityRestServiceDependenciesTest { private static final String REST_ROLE_NAME = "identity"; private static final String KURA_PERMISSION_REST_ROLE = "kura.permission.rest." + REST_ROLE_NAME; - private IdentityRestService service = new IdentityRestService(); + private final IdentityRestService service = new IdentityRestService(); private UserAdmin userAdmin; private CryptoService cryptoService; private ConfigurationService configurationService; diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java index 491b4da11fe..7fd9587c11e 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityServiceTest.java @@ -413,7 +413,7 @@ public int getType() { @Override public Dictionary getProperties() { - Dictionary properties = new Hashtable(); + Dictionary properties = new Hashtable<>(); properties.put("kura.need.password.change", this.needPasswordChange); return properties; } @@ -425,7 +425,7 @@ public boolean hasCredential(String key, Object value) { @Override public Dictionary getCredentials() { - Dictionary credentials = new Hashtable(); + Dictionary credentials = new Hashtable<>(); credentials.put("kura.password", this.password); return credentials; @@ -433,7 +433,7 @@ public Dictionary getCredentials() { } private static Map defaultValidatorProperties() { - Map properties = new HashMap(); + Map properties = new HashMap<>(); properties.put("new.password.min.length", 8); properties.put("new.password.require.digits", false); From caf0a6659c6dd25b6c5de8410da959804133e22d Mon Sep 17 00:00:00 2001 From: Nicola Timeus Date: Mon, 30 Oct 2023 20:49:59 +0100 Subject: [PATCH 65/66] Fixed sonar lint issue Signed-off-by: Nicola Timeus --- .../internal/rest/identity/provider/IdentityService.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java index 8e9db3f67d2..438e2d74c0d 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityService.java @@ -41,6 +41,7 @@ @SuppressWarnings("restriction") public class IdentityService { + private static final String IDENTITY = "Identity "; private static final String KURA_WEB_CONSOLE_SERVICE_PID = "org.eclipse.kura.web.Console"; private static final String PERMISSION_ROLE_NAME_PREFIX = "kura.permission."; private static final String USER_ROLE_NAME_PREFIX = "kura.user."; @@ -71,7 +72,7 @@ public void createUser(UserDTO user) throws KuraException { this.userAdminHelper.createUser(user.getUserName()); updateUser(user); } else { - throw new KuraException(KuraErrorCode.BAD_REQUEST, "user " + user.getUserName() + " already exists"); + throw new KuraException(KuraErrorCode.BAD_REQUEST, IDENTITY + user.getUserName() + " already exists"); } } @@ -86,7 +87,7 @@ public UserDTO getUser(String userName) throws KuraException { fillPermissions(Collections.singletonMap(user.get().getName(), userFound)); return userFound; } else { - throw new KuraException(KuraErrorCode.NOT_FOUND, "user " + userName + " not found"); + throw new KuraException(KuraErrorCode.NOT_FOUND, IDENTITY + userName + " not found"); } } @@ -182,7 +183,7 @@ public void updateUser(UserDTO userDTOToUpdate) throws KuraException { updatePasswordOptions(userDTOToUpdate, user.get().getCredentials(), user.get().getProperties()); } else { - throw new KuraException(KuraErrorCode.NOT_FOUND, "user " + userDTOToUpdate.getUserName() + " not found"); + throw new KuraException(KuraErrorCode.NOT_FOUND, IDENTITY + userDTOToUpdate.getUserName() + " not found"); } } From b4f7d2b192b7200bfcfc1f45cbbf0131c06be0ae Mon Sep 17 00:00:00 2001 From: Nicola Timeus Date: Tue, 31 Oct 2023 09:27:09 +0100 Subject: [PATCH 66/66] Minor naming changes Signed-off-by: Nicola Timeus --- .../rest/identity/provider/IdentityRestService.java | 6 +++--- .../rest/identity/provider/test/IdentityEndpointsTest.java | 6 +++--- .../provider/test/IdentityRestServiceDependenciesTest.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java index 88bd90df8f1..668fc3db455 100644 --- a/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java +++ b/kura/org.eclipse.kura.rest.identity.provider/src/main/java/org/eclipse/kura/internal/rest/identity/provider/IdentityRestService.java @@ -45,7 +45,7 @@ public class IdentityRestService { private static final Logger logger = LoggerFactory.getLogger(IdentityRestService.class); private static final String DEBUG_MESSAGE = "Processing request for method '{}'"; - private static final String MQTT_APP_ID = "ID-V1"; + private static final String MQTT_APP_ID = "IDN-V1"; private static final String REST_ROLE_NAME = "identity"; private static final String KURA_PERMISSION_REST_ROLE = "kura.permission.rest." + REST_ROLE_NAME; @@ -159,7 +159,7 @@ public Response deleteUser(final UserDTO userName) { } @GET - @Path("/defined-permissions") + @Path("/definedPermissions") @Produces(MediaType.APPLICATION_JSON) public PermissionDTO getDefinedPermissions() { try { @@ -186,7 +186,7 @@ public UserConfigDTO getUserConfig() { } @GET - @Path("/password-requirements") + @Path("/passwordRequirements") @Produces(MediaType.APPLICATION_JSON) public ValidatorOptionsDTO getValidatorOptions() { try { diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java index 32534d0f67f..57683c1077e 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/main/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityEndpointsTest.java @@ -53,7 +53,7 @@ @RunWith(Parameterized.class) public class IdentityEndpointsTest extends AbstractRequestHandlerTest { - private static final String MQTT_APP_ID = "ID-V1"; + private static final String MQTT_APP_ID = "IDN-V1"; private static final String METHOD_SPEC_GET = "GET"; private static final String METHOD_SPEC_POST = "POST"; @@ -161,7 +161,7 @@ public void shouldReturnUserConfig() throws KuraException { public void shouldReturnDefinedPermissions() throws KuraException { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/defined-permissions"); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/definedPermissions"); thenRequestSucceeds(); thenResponseBodyEqualsJson("{\"permissions\": [\"perm1\",\"perm2\"]}"); @@ -171,7 +171,7 @@ public void shouldReturnDefinedPermissions() throws KuraException { public void shouldReturnPasswordRequirements() throws KuraException { givenIdentityService(); - whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/password-requirements"); + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/passwordRequirements"); thenRequestSucceeds(); thenResponseBodyEqualsJson(EXPECTED_GET_PASSWORD_REQUIREMENTS_RESPONSE); diff --git a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java index 2c372d03981..70d30044eea 100644 --- a/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java +++ b/kura/test/org.eclipse.kura.rest.identity.provider.test/src/test/java/org/eclipse/kura/internal/rest/identity/provider/test/IdentityRestServiceDependenciesTest.java @@ -37,7 +37,7 @@ public class IdentityRestServiceDependenciesTest { - private static final String MQTT_APP_ID = "ID-V1"; + private static final String MQTT_APP_ID = "IDN-V1"; private static final String REST_ROLE_NAME = "identity"; private static final String KURA_PERMISSION_REST_ROLE = "kura.permission.rest." + REST_ROLE_NAME;