Skip to content
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 @@ -18,11 +18,14 @@
package tools.dynamia.modules.saas.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.*;
import tools.dynamia.domain.query.QueryConditions;
import tools.dynamia.domain.query.QueryParameters;
import tools.dynamia.domain.services.AbstractService;
import tools.dynamia.modules.saas.api.AccountServiceAPI;
import tools.dynamia.modules.saas.api.AccountStatsList;
import tools.dynamia.modules.saas.api.dto.AccountDTO;
import tools.dynamia.modules.saas.api.enums.AccountPeriodicity;
Expand All @@ -37,6 +40,7 @@

import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;

@RestController
@RequestMapping(value = "/api/saas", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
Expand All @@ -53,15 +57,20 @@ public class AccountApiController extends AbstractService {
}

private final AccountService service;
private final AccountServiceAPI serviceAPI;

@Autowired
public AccountApiController(AccountService service) {
public AccountApiController(AccountService service, AccountServiceAPI serviceAPI) {
this.service = service;
this.serviceAPI = serviceAPI;
}

@GetMapping("/account/{uuid}")
public AccountDTO getAccount(@PathVariable("uuid") String uuid, HttpServletRequest request) {
public ResponseEntity<AccountDTO> getAccount(@PathVariable("uuid") String uuid, HttpServletRequest request) {

if (!isAuthorized(request) && !isSameAccount(uuid, request)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

Account account = getAccount(uuid);

Expand All @@ -75,28 +84,31 @@ public AccountDTO getAccount(@PathVariable("uuid") String uuid, HttpServletReque
accountDTO.setStatusDescription("Licencia invalida");
}
}
return accountDTO;
return ResponseEntity.ok(accountDTO);
}


return NO_ACCOUNT;
return ResponseEntity.ok(NO_ACCOUNT);

}

@PostMapping("/account/{uuid}/stats")
public String updateStats(@PathVariable("uuid") String uuid, @RequestBody AccountStatsList stats, HttpServletRequest request) {
public ResponseEntity<Map<String, String>> updateStats(@PathVariable("uuid") String uuid, @RequestBody AccountStatsList stats, HttpServletRequest request) {

if (!isAuthorized(request) && !isSameAccount(uuid, request)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

Account account = getAccount(uuid);
if (account != null) {
if (stats != null) {
service.updateStats(account, stats.getData());
return "DONE: Account stats updated";
return ResponseEntity.ok(Map.of("message", "DONE: Account stats updated"));
} else {
return "Invalid stats";
return ResponseEntity.ok(Map.of("message", "Invalid stats"));
}
} else {
return "Cannot found account with uuid: " + uuid;
return ResponseEntity.notFound().build();
}
}

Expand All @@ -110,7 +122,12 @@ private Account getAccount(@PathVariable("uuid") String uuid) {
}

@GetMapping("/account/{uuid}/parameter/{name}")
public String getAccountParameter(@PathVariable("uuid") String uuid, @PathVariable("name") String name, HttpServletRequest request) {
public ResponseEntity<Map<String, String>> getAccountParameter(@PathVariable("uuid") String uuid, @PathVariable("name") String name, HttpServletRequest request) {

if (!isAuthorized(request) && !isSameAccount(uuid, request)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

String defautlValue = request.getParameter("defaultValue");
String value = null;
Account account = getAccount(uuid);
Expand All @@ -129,7 +146,11 @@ public String getAccountParameter(@PathVariable("uuid") String uuid, @PathVariab
});
}
}
return value;
if (value != null) {
return ResponseEntity.ok(Map.of("parameter", name, "value", value));
} else {
return ResponseEntity.notFound().build();
}
}

private void newLog(String uuid, HttpServletRequest request, Account account) {
Expand All @@ -142,4 +163,18 @@ private void newLog(String uuid, HttpServletRequest request, Account account) {

}
}

public boolean isAuthorized(HttpServletRequest request) {
if (serviceAPI.getSystemAccountId().equals(serviceAPI.getCurrentAccountId())) {
return true;
}

return false;
}
Comment on lines +167 to +173

public boolean isSameAccount(String uuid, HttpServletRequest request) {
var subdomain = HttpUtils.getSubdomain(request);
var currentAccount = service.getAccount(subdomain);
Comment on lines +175 to +177
return uuid.equals(currentAccount.getUuid());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import tools.dynamia.commons.SimpleCache;
import tools.dynamia.commons.StringPojoParser;
import tools.dynamia.domain.ValidationError;
import tools.dynamia.domain.query.QueryParameters;
import tools.dynamia.domain.services.CrudService;
import tools.dynamia.integration.Containers;
import tools.dynamia.viewers.ViewDescriptorFactory;
import tools.jackson.core.JacksonException;
import tools.jackson.databind.json.JsonMapper;

Expand Down Expand Up @@ -46,8 +49,11 @@ public abstract class AbstractCrudServiceRestController {
*/
private final JsonMapper mapper = StringPojoParser.createJsonMapper();

private SimpleCache<String, Class> allowedClasses = new SimpleCache<>();

/**
* Constructs a new {@code CrudServiceRestController} with the given CRUD service.
*
* @param crudService the CRUD service to use
*/
public AbstractCrudServiceRestController(CrudService crudService) {
Expand All @@ -56,8 +62,9 @@ public AbstractCrudServiceRestController(CrudService crudService) {

/**
* Creates or updates an entity of the specified class.
*
* @param className the fully qualified class name of the entity
* @param json the JSON representation of the entity
* @param json the JSON representation of the entity
* @return the persisted entity
*/
@RequestMapping(method = {RequestMethod.POST, RequestMethod.PUT})
Expand All @@ -69,8 +76,9 @@ public ResponseEntity<Object> createOrSave(@PathVariable String className, @Requ

/**
* Deletes an entity by its class name and ID.
*
* @param className the fully qualified class name of the entity
* @param id the entity ID
* @param id the entity ID
* @return the deleted entity ID if successful, or 404 if not found
*/
@DeleteMapping("/{id}")
Expand All @@ -87,8 +95,9 @@ public ResponseEntity<Object> delete(@PathVariable String className, @PathVariab

/**
* Retrieves an entity by its class name and ID.
*
* @param className the fully qualified class name of the entity
* @param id the entity ID
* @param id the entity ID
* @return the entity if found, or 404 if not found
*/
@GetMapping("/{id}")
Expand All @@ -103,7 +112,8 @@ public ResponseEntity<Object> get(@PathVariable String className, @PathVariable

/**
* Finds entities by query parameters.
* @param className the fully qualified class name of the entity
*
* @param className the fully qualified class name of the entity
* @param parameters the query parameters
* @return the list of matching entities
*/
Expand All @@ -116,7 +126,8 @@ public ResponseEntity<List<Object>> find(@PathVariable String className, @Reques

/**
* Gets the ID of an entity by query parameters.
* @param className the fully qualified class name of the entity
*
* @param className the fully qualified class name of the entity
* @param parameters the query parameters
* @return the entity ID
*/
Expand All @@ -129,8 +140,9 @@ public ResponseEntity<Object> getId(@PathVariable String className, @RequestBody

/**
* Parses a JSON string into an entity object of the specified class.
*
* @param className the fully qualified class name
* @param json the JSON string
* @param json the JSON string
* @return the entity object
* @throws ValidationError if parsing fails
*/
Expand All @@ -145,15 +157,29 @@ private Object parseJson(String className, String json) {

/**
* Loads a class by its fully qualified name.
*
* @param className the class name
* @return the {@link Class} object
* @throws ValidationError if the class is not found
*/
private Class loadClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new ValidationError("Class not found " + className + " - " + e.getMessage(), e);
initAllowedClasses();
Class entityClass = allowedClasses.get(className);
if (entityClass == null) {
throw new ValidationError("Class not allowed: " + className);
}
return entityClass;
}

private void initAllowedClasses() {
if (allowedClasses == null || allowedClasses.isEmpty()) {
ViewDescriptorFactory viewDescriptorFactory = Containers.get().findObject(ViewDescriptorFactory.class);
if (viewDescriptorFactory != null) {
viewDescriptorFactory.findDescriptorsByType("crud").forEach(d -> {
var entityClass = d.getKey();
allowedClasses.add(entityClass.getName(), entityClass);
});
}
}
Comment on lines +174 to 183
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ public void add(K key, V value) {
data.put(key, value);
}

/**
* Alias to add
* @param key
* @param value
*/
public void put(K key, V value) {
data.put(key, value);
}

public void putIfAbsent(K key, V value) {
data.putIfAbsent(key, value);
}

/**
* Retrieves a value from the cache by key.
*
Expand Down
Loading