Skip to content

Commit

Permalink
Merge pull request #9 from edsonmartins/resource-edit
Browse files Browse the repository at this point in the history
Criar endpoints para cadastro de permissões
  • Loading branch information
edsonmartins authored Jun 23, 2024
2 parents e97f680 + 51e830e commit fbd2f92
Show file tree
Hide file tree
Showing 9 changed files with 423 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,34 @@
import br.com.archbase.ddd.domain.contracts.FindDataWithFilterQuery;
import br.com.archbase.query.rsql.jpa.SortUtils;
import br.com.archbase.security.adapter.port.ResourcePersistencePort;
import br.com.archbase.security.domain.dto.ProfileDto;
import br.com.archbase.security.persistence.ProfileEntity;
import br.com.archbase.security.persistence.ResourceEntity;
import br.com.archbase.security.domain.dto.*;
import br.com.archbase.security.persistence.*;
import br.com.archbase.security.repository.PermissionJpaRepository;
import br.com.archbase.security.repository.ResourceJpaRepository;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Component;

import br.com.archbase.security.domain.dto.ResourceDto;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class ResourcePersistenceAdapter implements ResourcePersistencePort, FindDataWithFilterQuery<String, ResourceDto> {

private final ResourceJpaRepository repository;
private final PermissionJpaRepository permissionRepository;
private final JPAQueryFactory queryFactory;

@Autowired
private ResourceJpaRepository repository;
public ResourcePersistenceAdapter(ResourceJpaRepository repository, PermissionJpaRepository permissionRepository, EntityManager entityManager) {
this.repository = repository;
this.permissionRepository = permissionRepository;
this.queryFactory = new JPAQueryFactory(entityManager);
}

@Override
public List<ResourceDto> findAllResources() {
Expand Down Expand Up @@ -59,6 +65,171 @@ public void deleteResource(String id) {
repository.deleteById(id);
}

public List<ResoucePermissionsWithTypeDto> findUserResourcesPermissions(String userId) {

QPermissionEntity permission = QPermissionEntity.permissionEntity;
QUserEntity user = QUserEntity.userEntity;
QUserGroupEntity userGroup = QUserGroupEntity.userGroupEntity;
QGroupEntity group = QGroupEntity.groupEntity;
QProfileEntity profile = QProfileEntity.profileEntity;

List<Tuple> userPermissions = queryFactory
.select(permission.action.resource.id, permission.action.resource.description, permission.action.id, permission.action.description, Expressions.constant(SecurityType.USER), permission.id)
.from(permission)
.where(permission.security.id.eq(userId))
.fetch();

List<Tuple> profilePermissions = queryFactory
.select(permission.action.resource.id, permission.action.resource.description, permission.action.id, permission.action.description, Expressions.constant(SecurityType.PROFILE))
.from(permission)
.join(permission.security, profile._super)
.join(user).on(user.profile.eq(profile))
.where(user.id.eq(userId))
.fetch();

List<Tuple> groupPermissions = queryFactory
.select(permission.action.resource.id, permission.action.resource.description, permission.action.id, permission.action.description, Expressions.constant(SecurityType.GROUP))
.from(permission)
.join(permission.security, group._super)
.join(userGroup).on(userGroup.group.eq(group))
.where(userGroup.user.id.eq(userId))
.fetch();

List<Tuple> permissionsTuple = new ArrayList<>();
permissionsTuple.addAll(userPermissions);
permissionsTuple.addAll(profilePermissions);
permissionsTuple.addAll(groupPermissions);

return groupTuplesToResourcePermissions(permissionsTuple, permission);
}

public List<ResoucePermissionsWithTypeDto> findProfileResourcesPermissions(String profileId) {

QPermissionEntity permission = QPermissionEntity.permissionEntity;
QUserEntity user = QUserEntity.userEntity;
QProfileEntity profile = QProfileEntity.profileEntity;

List<Tuple> profilePermissions = queryFactory
.select(permission.action.resource.id, permission.action.resource.description, permission.action.id, permission.action.description, Expressions.constant(SecurityType.PROFILE), permission.id)
.from(permission)
.join(permission.security, profile._super)
.join(user).on(user.profile.eq(profile))
.where(profile.id.eq(profileId))
.fetch();

return groupTuplesToResourcePermissions(profilePermissions, permission);
}

public List<ResoucePermissionsWithTypeDto> findGroupResourcesPermissions(String groupId) {

QPermissionEntity permission = QPermissionEntity.permissionEntity;
QUserGroupEntity userGroup = QUserGroupEntity.userGroupEntity;
QGroupEntity group = QGroupEntity.groupEntity;

List<Tuple> groupPermissions = queryFactory
.select(permission.action.resource.id, permission.action.resource.description, permission.action.id, permission.action.description, Expressions.constant(SecurityType.GROUP), permission.id)
.from(permission)
.join(permission.security, group._super)
.join(userGroup).on(userGroup.group.eq(group))
.where(group.id.eq(groupId))
.fetch();


return groupTuplesToResourcePermissions(groupPermissions, permission);
}

public List<ResoucePermissionsWithTypeDto> findAllResourcesPermissions() {
QActionEntity action = QActionEntity.actionEntity;

List<Tuple> permissionsTuple = queryFactory
.select(action.resource.id, action.resource.description, action.id, action.description)
.from(action)
.fetch();

Map<String, Map<String, List<Tuple>>> groupedByResource = permissionsTuple.stream()
.collect(Collectors.groupingBy(t -> t.get(action.resource.id) + ":" + t.get(action.resource.description),
Collectors.groupingBy(t -> t.get(action.id))));

return groupedByResource.entrySet().stream()
.map(entry -> {
List<String> resourceIdName = Arrays.stream(entry.getKey().split(":")).toList();
List<PermissionWithTypesDto> permissions = entry.getValue().entrySet().stream()
.map(actionEntry -> {
String actionId = actionEntry.getKey();
String actionName = actionEntry.getValue().get(0).get(action.description);
return PermissionWithTypesDto.builder()
.actionDescription(actionName)
.actionId(actionId)
.build();
})
.collect(Collectors.toList());
return ResoucePermissionsWithTypeDto.builder()
.resourceId(resourceIdName.get(0))
.resourceDescription(resourceIdName.get(1))
.permissions(permissions)
.build();
})
.collect(Collectors.toList());
}

private static List<ResoucePermissionsWithTypeDto> groupTuplesToResourcePermissions(List<Tuple> permissionsTuple, QPermissionEntity permission) {
Map<String, Map<String, List<Tuple>>> groupedByResource = permissionsTuple.stream()
.collect(Collectors.groupingBy(t -> t.get(permission.action.resource.id) + ":" + t.get(permission.action.resource.description),
Collectors.groupingBy(t -> t.get(permission.action.id))));

return groupedByResource.entrySet().stream()
.map(entry -> {
List<String> resourceIdDescription = Arrays.stream(entry.getKey().split(":")).toList();
List<PermissionWithTypesDto> permissions = entry.getValue().entrySet().stream()
.map(actionEntry -> {
String actionId = actionEntry.getKey();
Set<SecurityType> types = actionEntry.getValue().stream()
.map(t -> t.get(4, SecurityType.class))
.collect(Collectors.toSet());
String actionDescription = actionEntry.getValue().get(0).get(permission.action.description);
String permissionId = actionEntry.getValue().get(0).get(permission.id);
PermissionWithTypesDto permissionWithTypesDto = PermissionWithTypesDto.builder()
.actionDescription(actionDescription)
.actionId(actionId)
.types(types)
.build();

if (permissionId != null) {
permissionWithTypesDto.setPermissionId(permissionId);
}

return permissionWithTypesDto;
})
.collect(Collectors.toList());
return ResoucePermissionsWithTypeDto.builder()
.resourceId(resourceIdDescription.get(0))
.resourceDescription(resourceIdDescription.get(1))
.permissions(permissions)
.build();
})
.collect(Collectors.toList());
}

public void deletePermission(String id) {
permissionRepository.deleteById(id);
}

public PermissionDto grantPermission(PermissionDto permissionDto) {
return permissionRepository.save(PermissionEntity.fromDomain(permissionDto.toDomain())).toDto();
}

public PermissionDto findPermission(String securityId, String actionId) {
QPermissionEntity permission = QPermissionEntity.permissionEntity;

PermissionEntity permissionEntity = queryFactory.selectFrom(permission)
.where(permission.action.id.eq(actionId).and(permission.security.id.eq(securityId)))
.fetchFirst();
if (permissionEntity == null) {
return null;
}
return permissionEntity.toDto();
}

@Override
public ResourceDto findById(String id) {
Optional<ResourceEntity> byId = repository.findById(id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package br.com.archbase.security.controller;

import br.com.archbase.query.rsql.jpa.SortUtils;
import br.com.archbase.security.domain.dto.GroupDto;
import br.com.archbase.security.domain.dto.ResourceDto;
import br.com.archbase.security.service.GroupService;
import br.com.archbase.security.service.ResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import br.com.archbase.security.domain.dto.*;
import br.com.archbase.security.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
Expand All @@ -15,17 +13,18 @@
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/resource")
public class ResourceController {

private final ResourceService resourceService;

@Autowired
public ResourceController(ResourceService resourceService) {
this.resourceService = resourceService;
}
private final ActionService actionService;
private final UserService userService;
private final GroupService groupService;
private final UserProfileService userProfileService;

@PostMapping
public ResponseEntity<ResourceDto> createResource(@RequestBody ResourceDto resource) {
Expand All @@ -52,6 +51,72 @@ public ResponseEntity<ResourceDto> getResourceById(@PathVariable String id) {
}
}

@GetMapping(
value = {"/permissions/security/{id}"},
params = {"type"}
)
public ResponseEntity<List<ResoucePermissionsWithTypeDto>> findResourcesPermissions(@PathVariable String id, @RequestParam("type") SecurityType type) {
try {
List<ResoucePermissionsWithTypeDto> resourcesPermissions = resourceService.findResourcesPermissions(id, type);
return ResponseEntity.ok(resourcesPermissions);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

@GetMapping("/permissions")
public ResponseEntity<List<ResoucePermissionsWithTypeDto>> findAllResourcesPermissions() {
try {
List<ResoucePermissionsWithTypeDto> resourcesPermissions = resourceService.findAllResourcesPermissions();
return ResponseEntity.ok(resourcesPermissions);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

@PostMapping("/permissions")
public ResponseEntity<?> grantPermission(@RequestBody GrantPermissionDto grantPermission) {
try {
Optional<ActionDto> action = actionService.findActionById(grantPermission.getActionId());
if (action.isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Ação não encontrada");
}
SecurityDto security = null;
if (grantPermission.getType().equals(SecurityType.USER)) {
security = userService.findById(grantPermission.getSecurityId());
}
if (grantPermission.getType().equals(SecurityType.PROFILE)) {
security = userProfileService.findById(grantPermission.getSecurityId());
}
if (grantPermission.getType().equals(SecurityType.GROUP)) {
security = groupService.findById(grantPermission.getSecurityId());
}

if (security == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Entidade de segurança não encontrada");
}

PermissionDto existingPermission = resourceService.findPermission(security.getId(), action.get().getId());

if (existingPermission != null) {
return ResponseEntity.ok(ResouceActionPermissionDto.fromPermissionDto(existingPermission));
}

PermissionDto permission = PermissionDto.builder()
.action(action.get())
.security(security)
.build();
PermissionDto savedPermission = resourceService.grantPermission(permission);
return ResponseEntity.ok(ResouceActionPermissionDto.fromPermissionDto(savedPermission));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

@DeleteMapping("/permissions/{id}")
public void deletePermission(@PathVariable String id) {
resourceService.deletePermission(id);
}

@GetMapping(
value = {"/findAll"},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package br.com.archbase.security.domain.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;


@Getter
@Setter
@Builder
public class GrantPermissionDto {
private String securityId;
private String actionId;
private SecurityType type;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package br.com.archbase.security.domain.dto;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.util.Set;


@Getter
@Setter
@Builder
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "@id")
public class PermissionWithTypesDto {
@JsonInclude(JsonInclude.Include.NON_NULL)
private String permissionId;
private String actionId;
private String actionDescription;
@JsonInclude(JsonInclude.Include.NON_NULL)
private Set<SecurityType> types;
}
Loading

0 comments on commit fbd2f92

Please sign in to comment.