Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(dataplane): integrate dataplane plugin for Device #5416

Merged
merged 1 commit into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.gravitee.am.service;

import io.gravitee.am.identityprovider.api.User;
package io.gravitee.am.gateway.handler.common.service;

import io.gravitee.am.model.Device;
import io.gravitee.am.model.Domain;
import io.gravitee.am.model.UserId;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Single;

/**
* @author Rémi SULTAN (remi.sultan at graviteesource.com)
* @author GraviteeSource Team
*/
public interface DeviceService {

Flowable<Device> findByDomainAndUser(String domain, UserId user);

Single<Boolean> deviceExists(String domain, String client, UserId user, String rememberDevice, String deviceId);
public interface DeviceGatewayService {

Single<Device> create(String domain, String client, UserId user, String rememberDevice, String type, Long timeExpirationMs, String deviceId);
Flowable<Device> findByDomainAndUser(Domain domain, UserId user);

Completable delete(String domain, UserId user, String id, User authenticatedUser);
Single<Boolean> deviceExists(Domain domain, String client, UserId user, String rememberDevice, String deviceId);

Single<Device> create(Domain domain, String client, UserId user, String rememberDevice, String type, Long timeExpirationMs, String deviceId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Maybe;
import io.reactivex.rxjava3.core.Single;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.Date;
import java.util.List;
Expand All @@ -47,11 +46,10 @@
* @author GraviteeSource Team
*/
@Slf4j
@AllArgsConstructor
public class CredentialGatewayServiceImpl implements CredentialGatewayService {

@Lazy
@Autowired
private DataPlaneRegistry dataPlaneRegistry;
private final DataPlaneRegistry dataPlaneRegistry;

//FIXME do we have to keep RefTyp & RefId into the repository signatures ?
//FIXME do we have to create a business Rule for the delete/update method to avoid logic duplication between mAPI and GW?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Copyright (C) 2015 The Gravitee team (http://gravitee.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.gravitee.am.gateway.handler.common.service.impl;


import io.gravitee.am.gateway.handler.common.service.DeviceGatewayService;
import io.gravitee.am.model.Device;
import io.gravitee.am.model.Domain;
import io.gravitee.am.model.UserId;
import io.gravitee.am.plugins.dataplane.core.DataPlaneRegistry;
import io.gravitee.am.service.exception.TechnicalManagementException;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Single;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.Optional;

import static io.gravitee.am.model.ReferenceType.DOMAIN;

/**
* @author Eric LELEU (eric.leleu at graviteesource.com)
* @author GraviteeSource Team
*/
@Slf4j
@AllArgsConstructor
public class DeviceGatewayServiceImpl implements DeviceGatewayService {
leleueri marked this conversation as resolved.
Show resolved Hide resolved
//Ten hours
private static final long DEFAULT_DEVICE_EXPIRATION_TIME_SECONDS = 10L * 60L * 60L;

private DataPlaneRegistry dataPlaneRegistry;

@Override
public Flowable<Device> findByDomainAndUser(Domain domain, UserId userId) {
return dataPlaneRegistry.getDeviceRepository(domain).findByDomainAndClientAndUser(domain.getId(), userId).onErrorResumeNext(ex -> {
log.error("An error occurs while trying to find Devices by {} {}", domain, userId, ex);
return Flowable.error(new TechnicalManagementException(String.format("An error occurs while trying to find Devices by %s %s", domain, userId), ex));
});
}

@Override
public Single<Boolean> deviceExists(Domain domain, String client, UserId user, String rememberDevice, String deviceId) {
return dataPlaneRegistry.getDeviceRepository(domain).findByDomainAndClientAndUserAndDeviceIdentifierAndDeviceId(domain.getId(), client, user, rememberDevice, deviceId).isEmpty();
}

@Override
public Single<Device> create(Domain domain, String client, UserId user, String rememberDevice, String deviceType, Long timeExpirationSeconds, String deviceId) {
long expiresAt = System.currentTimeMillis() + Optional.ofNullable(timeExpirationSeconds)
.filter(time -> time > 0L)
.orElse(DEFAULT_DEVICE_EXPIRATION_TIME_SECONDS) * 1000L;
return dataPlaneRegistry.getDeviceRepository(domain).create(new Device()
.setReferenceType(DOMAIN)
.setReferenceId(domain.getId())
.setClient(client)
.setUserId(user)
.setDeviceIdentifierId(rememberDevice)
.setType(deviceType)
.setDeviceId(deviceId)
.setCreatedAt(new Date())
.setExpiresAt(new Date(expiresAt))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@
import io.gravitee.am.gateway.handler.common.ruleengine.RuleEngine;
import io.gravitee.am.gateway.handler.common.ruleengine.SpELRuleEngine;
import io.gravitee.am.gateway.handler.common.service.CredentialGatewayService;
import io.gravitee.am.gateway.handler.common.service.DeviceGatewayService;
import io.gravitee.am.gateway.handler.common.service.UserActivityGatewayService;
import io.gravitee.am.gateway.handler.common.service.impl.CredentialGatewayServiceImpl;
import io.gravitee.am.gateway.handler.common.service.impl.DeviceGatewayServiceImpl;
import io.gravitee.am.gateway.handler.common.service.impl.UserActivityGatewayServiceImpl;
import io.gravitee.am.gateway.handler.common.spring.web.WebConfiguration;
import io.gravitee.am.gateway.handler.common.user.UserGatewayService;
Expand Down Expand Up @@ -340,12 +342,17 @@ public UserEnhancer facadeManagerUserEnhancer(GroupManager groupManager, RoleMan
}

@Bean
public CredentialGatewayService credentialGatewayService() {
return new CredentialGatewayServiceImpl();
public CredentialGatewayService credentialGatewayService(DataPlaneRegistry dataPlaneRegistry) {
return new CredentialGatewayServiceImpl(dataPlaneRegistry);
}

@Bean
public UserActivityGatewayService userActivityGatewayService(UserActivityConfiguration configuration, DataPlaneRegistry dataPlaneRegistry) {
return new UserActivityGatewayServiceImpl(configuration, dataPlaneRegistry);
}

@Bean
public DeviceGatewayService deviceGatewayService(DataPlaneRegistry dataPlaneRegistry) {
return new DeviceGatewayServiceImpl(dataPlaneRegistry);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.gravitee.am.common.jwt.Claims;
import io.gravitee.am.gateway.handler.common.auth.AuthenticationDetails;
import io.gravitee.am.gateway.handler.common.service.DeviceGatewayService;
import io.gravitee.am.gateway.handler.common.service.UserActivityGatewayService;
import io.gravitee.am.model.Device;
import io.gravitee.am.model.Domain;
import io.gravitee.am.model.User;
import io.gravitee.am.model.UserActivity;
import io.gravitee.am.service.DeviceService;
import io.gravitee.risk.assessment.api.assessment.AssessmentMessage;
import io.gravitee.risk.assessment.api.assessment.AssessmentMessageResult;
import io.gravitee.risk.assessment.api.assessment.AssessmentResult;
Expand Down Expand Up @@ -62,14 +62,14 @@ public class RiskAssessmentService {
private static final Logger logger = LoggerFactory.getLogger(RiskAssessmentService.class);
private static final String RISK_ASSESSMENT_SERVICE = "service:risk-assessment";

private final DeviceService deviceService;
private final DeviceGatewayService deviceService;
private final UserActivityGatewayService userActivityService;
private final ObjectMapper objectMapper;
private final EventBus eventBus;
private final RiskAssessmentSettings riskAssessmentSettings;

public RiskAssessmentService(
DeviceService deviceService,
DeviceGatewayService deviceService,
UserActivityGatewayService userActivityService,
ObjectMapper objectMapper,
RiskAssessmentSettings riskAssessmentSettings,
Expand Down Expand Up @@ -105,7 +105,7 @@ private Function<AssessmentMessage, Single<AssessmentMessage>> buildDeviceAssess
var deviceAssessment = ofNullable(riskAssessmentSettings.getDeviceAssessment()).orElse(new AssessmentSettings());
if (deviceAssessment.isEnabled()) {
logger.debug("Decorating assessment with devices");
return deviceService.findByDomainAndUser(domain.getId(), user.getFullId())
return deviceService.findByDomainAndUser(domain, user.getFullId())
.map(Device::getDeviceId)
.toList().flatMap(deviceIds -> {
assessmentMessage.getData().setDevices(new Devices()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
Expand All @@ -65,18 +64,17 @@
@RunWith(MockitoJUnitRunner.class)
public class CredentialGatewayServiceTest {

@InjectMocks
private CredentialGatewayService credentialService = new CredentialGatewayServiceImpl();

@Mock
private CredentialRepository credentialRepository;

@Mock
private DataPlaneRegistry dataPlaneRegistry;

@Mock
private UserRepository userRepository;

@Mock
private CredentialRepository credentialRepository;

private CredentialGatewayService credentialService;

private final static String DOMAIN = "domain1";

private Domain domain = new Domain();
Expand All @@ -86,6 +84,7 @@ public void init() {
this.domain.setId(DOMAIN);
when(dataPlaneRegistry.getUserRepository(any())).thenReturn(userRepository);
when(dataPlaneRegistry.getCredentialRepository(any())).thenReturn(credentialRepository);
credentialService = new CredentialGatewayServiceImpl(dataPlaneRegistry);
}

@Test
Expand Down
Loading