Skip to content

Commit

Permalink
clean code by making doPost more readable
Browse files Browse the repository at this point in the history
  • Loading branch information
jnsereko committed Mar 27, 2023
1 parent b5b1ea7 commit cf3474c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 78 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ cd openmrs-module-spa && mvn clean install
| `spa.local.directory` | The directory containing the Frontend 3.0 application's `index.html`. Can be an absolute path, or relative to the application data directory. Only used if `spa.remote.enabled` is false. | frontend |
| `spa.remote.enabled` | If enabled, serves from `spa.remote.url` instead of `spa.local.directory` | false |
| `spa.remote.url` | The URL of the Frontend 3.0 application files. Only used if `spa.remote.enabled` is true. | https://spa-modules.nyc3.digitaloceanspaces.com/@openmrs/esm-app-shell/latest/ |
| `spa.json.config.filename` | The name of the Frontend 3.0 application's json configuration file. | config.json |

5 changes: 0 additions & 5 deletions omod/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>

<!--tests -->
<dependency>
Expand Down
4 changes: 0 additions & 4 deletions omod/src/main/java/org/openmrs/module/spa/SpaConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ private SpaConstants() {}

public static final String GP_REMOTE_URL = "spa.remote.url";

public static final String DEFAULT_CONFIG_DIRECTORY = "config";
public static final String CONFIG_DIRECTORY = "spa.config.directory";

public static final String DEFAULT_JSON_CONFIG_FILE_NAME = "config.json";
public static final String GP_JSON_CONFIG_FILE_NAME = "spa.json.config.filename";
}

125 changes: 64 additions & 61 deletions omod/src/main/java/org/openmrs/module/spa/servlet/SpaServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.openmrs.User;
import org.openmrs.api.AdministrationService;
Expand All @@ -33,17 +30,14 @@
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Base64;

import static org.openmrs.module.spa.SpaConstants.DEFAULT_JSON_CONFIG_FILE_NAME;
import static org.openmrs.module.spa.SpaConstants.GP_JSON_CONFIG_FILE_NAME;

@Slf4j
public class SpaServlet extends HttpServlet {
Expand Down Expand Up @@ -82,74 +76,83 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
String requestURI = request.getRequestURI();
if (requestURI.endsWith("/config.json")) {
if (!Context.isAuthenticated()) {
String basicAuth = request.getHeader("Authorization");
if (basicAuth != null) {
// check that header is in format "Basic ${base64encode(username + ":" + password)}"
if (basicAuth.startsWith("Basic")) {
try {
// remove the leading "Basic "
basicAuth = basicAuth.substring(6);
if (StringUtils.isBlank(basicAuth)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid credentials provided");
return;
}

String decoded = new String(Base64.decodeBase64(basicAuth), StandardCharsets.UTF_8);
if (StringUtils.isBlank(decoded) || !decoded.contains(":")) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid credentials provided");
return;
}

String[] userAndPass = decoded.split(":");
Context.authenticate(userAndPass[0], userAndPass[1]);
log.debug("authenticated [{}]", userAndPass[0]);
}
catch (Exception ex) {
// This filter never stops execution. If the user failed to
// authenticate, that will be caught later.
log.debug("authentication exception ", ex);
}
}
if (isValidAuthFormat(response, basicAuth)) return;
}
}

User user = Context.getAuthenticatedUser();
if (user != null && user.isSuperUser()) {
File jsonConfigFile = getJsonConfigFile();
try {
BufferedReader reader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
String requestBody = stringBuilder.toString();

new ObjectMapper().readTree(requestBody); // verify that is in a valid JSON format

InputStream inputStream = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8));
OutputStream outStream = new FileOutputStream(jsonConfigFile);
OpenmrsUtil.copyFile(inputStream, outStream);

if (jsonConfigFile.exists()) {
log.debug("file: '{}' written successfully", jsonConfigFile.getAbsolutePath());
response.setStatus(HttpServletResponse.SC_OK);
}
} catch (JsonProcessingException e) {
log.error("Invalid JSON format", e);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
saveJsonConfigFile(request, response);
} else {
log.error("Authorisation error while creating a config.json file");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
}

private void saveJsonConfigFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
File jsonConfigFile = getJsonConfigFile();
try {
BufferedReader reader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
String requestBody = stringBuilder.toString();

new ObjectMapper().readTree(requestBody); // verify that is in a valid JSON format

InputStream inputStream = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8));
OutputStream outStream = Files.newOutputStream(jsonConfigFile.toPath());
OpenmrsUtil.copyFile(inputStream, outStream);

if (jsonConfigFile.exists()) {
log.debug("file: '{}' written successfully", jsonConfigFile.getAbsolutePath());
response.setStatus(HttpServletResponse.SC_OK);
}
} catch (JsonProcessingException e) {
log.error("Invalid JSON format", e);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}

private boolean isValidAuthFormat(HttpServletResponse response, String basicAuth) {
if (basicAuth.startsWith("Basic")) {
try {
// remove the leading "Basic "
basicAuth = basicAuth.substring(6);
if (StringUtils.isBlank(basicAuth)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid credentials provided");
return true;
}

String decoded = new String(Base64.getDecoder().decode(basicAuth), StandardCharsets.UTF_8);
if (StringUtils.isBlank(decoded) || !decoded.contains(":")) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid credentials provided");
return true;
}

String[] userAndPass = decoded.split(":");
Context.authenticate(userAndPass[0], userAndPass[1]);
log.debug("authenticated [{}]", userAndPass[0]);
}
catch (Exception ex) {
// This filter never stops execution. If the user failed to
// authenticate, that will be caught later.
log.debug("authentication exception ", ex);
}
}
return false;
}

protected void handleLocalAssets(HttpServletRequest request, HttpServletResponse response) throws IOException {
File file = getFile(request);

Expand All @@ -167,7 +170,7 @@ protected void handleLocalAssets(HttpServletRequest request, HttpServletResponse
String mimeType = getServletContext().getMimeType(file.getName());
response.setContentType(mimeType);

try (InputStream is = new FileInputStream(file)) {
try (InputStream is = Files.newInputStream(file.toPath())) {
OpenmrsUtil.copyFile(is, response.getOutputStream());
}
}
Expand All @@ -180,7 +183,7 @@ protected void handleLocalAssets(HttpServletRequest request, HttpServletResponse
* @param response {@link HttpServletResponse}
* @throws IOException {@link IOException} F
*/
protected void handleRemoteAssets(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
protected void handleRemoteAssets(HttpServletRequest request, HttpServletResponse response) throws IOException {
Resource resource = getResource(request);
if (!resource.exists()) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
Expand Down Expand Up @@ -259,7 +262,7 @@ protected File getFile(HttpServletRequest request) {

File file = folder.toPath().resolve(extractedFile).toFile();
if (!file.exists()) {
log.warn("File with path '{}' doesn't exist", file.toString());
log.warn("File with path '{}' doesn't exist", file);
return null;
}
return file;
Expand All @@ -280,7 +283,7 @@ private File getJsonConfigFile() {
}

AdministrationService as = Context.getAdministrationService();
String jsonConfigFileName = as.getGlobalProperty(GP_JSON_CONFIG_FILE_NAME, DEFAULT_JSON_CONFIG_FILE_NAME);
String jsonConfigFileName = as.getGlobalProperty(DEFAULT_JSON_CONFIG_FILE_NAME);

return new File(folder.getAbsolutePath(), jsonConfigFileName);
}
Expand Down
8 changes: 1 addition & 7 deletions omod/src/main/resources/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,7 @@
<defaultValue>https://spa-modules.nyc3.digitaloceanspaces.com/@openmrs/esm-app-shell/latest/</defaultValue>
<description>The URL of the Frontend 3.0 application files. Only used if `spa.remote.enabled` is true.</description>
</globalProperty>

<globalProperty>
<property>spa.json.config.filename</property>
<defaultValue>config.json</defaultValue>
<description>The name of the Frontend 3.0 application's json configuration file</description>
</globalProperty>


<servlet>
<servlet-name>spaServlet</servlet-name>
<servlet-class>org.openmrs.module.spa.servlet.SpaServlet</servlet-class>
Expand Down

0 comments on commit cf3474c

Please sign in to comment.