Skip to content

Commit

Permalink
Merge pull request #3745 from MDeLuise/feature/user-profile-info
Browse files Browse the repository at this point in the history
Add the possibility for an authenticated user to read and change his own profile information
  • Loading branch information
Coduz authored Mar 27, 2023
2 parents 4775838 + 1849c65 commit aa5e04a
Show file tree
Hide file tree
Showing 21 changed files with 688 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.eclipse.kapua.qa.common.cucumber.CucTopic;
import org.eclipse.kapua.qa.common.cucumber.CucTriggerProperty;
import org.eclipse.kapua.qa.common.cucumber.CucUser;
import org.eclipse.kapua.qa.common.cucumber.CucUserProfile;
import org.eclipse.kapua.service.datastore.internal.setting.DatastoreElasticsearchClientSettings;
import org.eclipse.kapua.service.datastore.internal.setting.DatastoreElasticsearchClientSettingsKey;
import org.eclipse.kapua.transport.message.jms.JmsTopic;
Expand Down Expand Up @@ -318,6 +319,14 @@ public CucUser cucUser(Map<String, String> entry) {
entry.get("expirationDate"));
}


@DataTableType
public CucUserProfile cucUserProfile(Map<String, String> entry) {
return new CucUserProfile(entry.get("displayName"),
entry.get("phoneNumber"),
entry.get("email"));
}

@ParameterType(".*")
public org.eclipse.kapua.transport.message.jms.JmsTopic topic(String topic) {
return new JmsTopic(topic);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2023, 2022 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.kapua.qa.common.cucumber;

public class CucUserProfile {
private String displayName;
private String phoneNumber;
private String email;


public CucUserProfile(String displayName, String phoneNumber, String email) {
this.displayName = displayName;
this.phoneNumber = phoneNumber;
this.email = email;
}


public String getDisplayName() {
return displayName;
}


public void setDisplayName(String displayName) {
this.displayName = displayName;
}


public String getPhoneNumber() {
return phoneNumber;
}


public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}


public String getEmail() {
return email;
}


public void setEmail(String email) {
this.email = email;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2023, 2022 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.kapua.integration.service.user;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
features = { "classpath:features/user/UserProfileUnitTests.feature"
},
glue = {"org.eclipse.kapua.service.security.test",
"org.eclipse.kapua.service.authorization.steps",
"org.eclipse.kapua.service.authentication.steps",
"org.eclipse.kapua.service.user.steps",
"org.eclipse.kapua.service.account.steps",
"org.eclipse.kapua.qa.common"
},
plugin = {"pretty",
"html:target/cucumber/UserProfile",
"json:target/UserProfile_cucumber.json"
},
monochrome = true)
public class RunUserProfileUnitTests {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
###############################################################################
# Copyright (c) 2023, 2022 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
###############################################################################
@security
@env_none

Feature: User Credential
This feature file contains Unit tests for User Profile.

@setup
Scenario: Initialize test environment
Given Init Jaxb Context
And Init Security Context

Scenario: Change User Profile correctly
Create a user, login with it, change the user profile and then check if the operation is performed correctly.
Given I login as user with name "kapua-sys" and password "kapua-password"
And I change the profile to the following
| displayName | phoneNumber | email |
| Foo | 424242 | foo@bar.com |
When I search for user with name "kapua-sys"
Then I find user
| kapua-sys | Foo | foo@bar.com | 424242 | ENABLED |
And I logout

Scenario: Change User Profile correctly to all blank values
Create a user, login with it, change the user profile with all fields blank, and then check if the operation is performed correctly.
Given I login as user with name "kapua-sys" and password "kapua-password"
And I change the profile to the following
| displayName | phoneNumber | email |
| | | |
When I search for user with name "kapua-sys"
Then I find user
| kapua-sys | | | | ENABLED |
And I logout

Scenario: Change User Profile incorrectly
Create a user, login with it, change the user profile incorrectly, and then check if the exception is occurred.
Given I login as user with name "kapua-sys" and password "kapua-password"
And I expect the exception "KapuaIllegalArgumentException" with the text "An illegal value was provided for the argument userProfile.email: foo.com."
When I change the profile to the following
| displayName | phoneNumber | email |
| Foo | 424242 | foo.com |
Then An exception was thrown
And I logout

Scenario: Read User Profile correctly
Create a user, login with it, and then read its user profile.
Given I login as user with name "kapua-sys" and password "kapua-password"
Then I read the following user profile
| displayName | phoneNumber | email |
| Kapua Sysadmin | +1 555 123 4567 | kapua-sys@eclipse.org |
And I logout
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2023, 2022 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.kapua.app.api.resources.v1.resources;

import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.app.api.core.model.ScopeId;
import org.eclipse.kapua.app.api.core.resources.AbstractKapuaResource;
import org.eclipse.kapua.locator.KapuaLocator;
import org.eclipse.kapua.service.user.profile.UserProfile;
import org.eclipse.kapua.service.user.profile.UserProfileService;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
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;

@Path("{scopeId}/user/profile")
public class UserProfiles extends AbstractKapuaResource {
private final KapuaLocator locator = KapuaLocator.getInstance();
private final UserProfileService userProfileService = locator.getService(UserProfileService.class);


@PUT
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response changeUserProfile(@PathParam("scopeId") ScopeId scopeId, UserProfile userProfile) throws KapuaException {
userProfileService.changeUserProfile(userProfile);
return returnOk();
}

@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public UserProfile getUserProfile(@PathParam("scopeId") ScopeId scopeId) throws KapuaException {
return userProfileService.getUserProfile();
}
}

6 changes: 6 additions & 0 deletions rest-api/resources/src/main/resources/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,9 @@ paths:
$ref: './userCredentials/userCredentials-scopeId.yaml#/paths/~1{scopeId}~1user~1credentials~1password'
/{scopeId}/user/credentials/{credentialId}/_reset:
$ref: './userCredentials/userCredentials-scopeId-credentialId-_reset.yaml#/paths/~1{scopeId}~1user~1credentials~1{credentialId}~1_reset'
### User Profile ###
/{scopeId}/user/profile/:
$ref: './userProfile/userProfile-scopeId.yaml#/paths/~1{scopeId}~1user~1profile~1'

components:
parameters:
Expand Down Expand Up @@ -939,6 +942,9 @@ components:
$ref: './userCredentials/userCredentials.yaml#/components/schemas/passwordChangeRequest'
passwordResetRequest:
$ref: './userCredentials/userCredentials.yaml#/components/schemas/passwordResetRequest'
### User Profile Entities ###
userProfile:
$ref: './userProfile/userProfile.yaml#/components/schemas/userProfile'
requestBodies:
kapuaQuery:
description: An object to specify Query options
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
openapi: 3.0.2

info:
title: Everyware Cloud REST API - User Profile
version: '1.0'
contact:
name: Eurotech
url: https://www.eurotech.com

paths:

/{scopeId}/user/profile/:
get:
tags:
- User Profile
summary: Get the User Profile
operationId: userProfileGet
parameters:
- $ref: '../openapi.yaml#/components/parameters/scopeId'
responses:
200:
description: The desired user profile
content:
application/json:
schema:
$ref: './userProfile.yaml#/components/schemas/userProfile'
401:
$ref: '../openapi.yaml#/components/responses/unauthenticated'
403:
$ref: '../openapi.yaml#/components/responses/subjectUnauthorized'
404:
$ref: '../openapi.yaml#/components/responses/entityNotFound'
500:
$ref: '../openapi.yaml#/components/responses/kapuaError'
put:
tags:
- User Profile
summary: Change the User Profile
operationId: userProfileUpdate
parameters:
- $ref: '../openapi.yaml#/components/parameters/scopeId'
requestBody:
content:
application/json:
schema:
$ref: '../openapi.yaml#/components/schemas/userProfile'
responses:
200:
description: The user profile has been updated
401:
$ref: '../openapi.yaml#/components/responses/unauthenticated'
403:
$ref: '../openapi.yaml#/components/responses/subjectUnauthorized'
500:
$ref: '../openapi.yaml#/components/responses/kapuaError'
description: Change logged user profile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
openapi: 3.0.2

info:
title: Everyware Cloud REST API - User Profile
version: '1.0'
contact:
name: Eurotech
url: https://www.eurotech.com

paths: {}

components:
schemas:
userProfile:
allOf:
- description: The user profile
type: object
properties:
displayName:
type: string
phoneNumber:
type: string
email:
type: string
example:
displayName: "Foo42"
phoneNumber: "424202424"
email: "foo@bar.com"
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@
import org.eclipse.kapua.service.user.UserListResult;
import org.eclipse.kapua.service.user.UserQuery;
import org.eclipse.kapua.service.user.UserXmlRegistry;
import org.eclipse.kapua.service.user.profile.UserProfile;
import org.eclipse.kapua.service.user.profile.UserProfileXmlRegistry;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.MarshallerProperties;

Expand Down Expand Up @@ -699,6 +701,10 @@ public JaxbContextResolver() {
PasswordResetRequest.class,
UserCredentialsXmlRegistry.class,

// User Profile
UserProfile.class,
UserProfileXmlRegistry.class,

// KapuaEvent
ServiceEvent.class,
EventStoreRecordCreator.class,
Expand Down
7 changes: 6 additions & 1 deletion rest-api/web/src/main/resources/shiro.ini
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,9 @@ kapuaAuthcAccessToken = org.eclipse.kapua.app.api.core.auth.KapuaTokenAuthentica
# User Credentials
/v1/*/user/credentials.json = kapuaAuthcAccessToken
/v1/*/user/credentials.xml = kapuaAuthcAccessToken
/v1/*/user/credentials/** = kapuaAuthcAccessToken
/v1/*/user/credentials/** = kapuaAuthcAccessToken

# User Profile
/v1/*/user/profile.json = kapuaAuthcAccessToken
/v1/*/user/profile.xml = kapuaAuthcAccessToken
/v1/*/user/profile/** = kapuaAuthcAccessToken
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* @since 2.0.0
*/
public class UserCredentialsModule extends AbstractKapuaModule implements Module {
public class UserCredentialsModule extends AbstractKapuaModule {
@Override
protected void configureModule() {
bind(UserCredentialsService.class).to(UserCredentialsServiceImpl.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
package org.eclipse.kapua.service.systeminfo;

import org.eclipse.kapua.locator.KapuaLocator;
import org.eclipse.kapua.service.KapuaService;

import javax.xml.bind.annotation.XmlRegistry;

@XmlRegistry
public class SystemInfoXmlRegistry implements KapuaService {
public class SystemInfoXmlRegistry {
private static final KapuaLocator LOCATOR = KapuaLocator.getInstance();
private static final SystemInfoFactory SYSTEM_INFO_FACTORY = LOCATOR.getFactory(SystemInfoFactory.class);

Expand Down
Loading

0 comments on commit aa5e04a

Please sign in to comment.