All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fivefaces.structureclient.controller.PatientAuthController Maven / Gradle / Ivy

There is a newer version: 1.0.62
Show newest version
package com.fivefaces.structureclient.controller;

import com.fivefaces.cloud.workflow.WorkflowExecutionResult;
import com.fivefaces.cloud.workflow.WorkflowService;
import com.fivefaces.structure.query.builder.StructureQuery;
import com.fivefaces.structure.query.builder.criteria.BasicCriteria;
import com.fivefaces.structureclient.config.security.patient.PatientJwtTokenService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequiredArgsConstructor
@RestController
@RequestMapping("/pt-auth")
@Slf4j
public class PatientAuthController extends AbstractStructureController {

    private final PatientJwtTokenService patientJwtTokenService;
    private final WorkflowService workflowService;

    @GetMapping(value = "/.well-known/jwks.json", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public byte[] getFile() {
        return patientJwtTokenService.getJwtPublicKey().getBytes(StandardCharsets.UTF_8);
    }

    @GetMapping(value = "/.well-known/openid-configuration", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity> getOpenIdConfiguration() {
        String issuer = patientJwtTokenService.getIssuer();
        return ResponseEntity.ok(new HashMap<>() {{
            put("issuer", issuer);
            put("authorization_endpoint", issuer + "/validate");
            put("jwks_uri", issuer + "/.well-known/jwks.json");
            put("userinfo_endpoint", issuer + "/userinfo");
            put("token_endpoint", issuer + "/token");
            put("scopes_supported", List.of("patient_read"));
            put("response_types_supported", List.of("code"));
            put("token_endpoint_auth_methods_supported", List.of("client_secret_basic"));
        }});
    }

    @PostMapping(value = "/generate", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity handleGenerateOtp(@RequestBody OtpRequest request) {
        if (StringUtils.isBlank(request.getUsername())) {
            throw new IllegalArgumentException("Username and password are required");
        }
        JSONObject json = new JSONObject();
        json.put("query", new JSONObject() {{
            put("mobilePhone", request.getUsername());
            put("sendSms", true);
        }});
        WorkflowExecutionResult result = workflowService.instantiateWorkflow("createOTP", json.toString());
        if ("FAILED".equals(result.getStatus())) {
            throw new IllegalStateException("Failed to generate an OTP\n" + result.getOutput());
        }
        return ResponseEntity.ok(result);
    }

    @PostMapping("/validate")
    public ResponseEntity handleValidateOtp(@RequestBody AuthRequest request) {
        if (StringUtils.isAnyBlank(request.getUsername(), request.getPassword())) {
            throw new IllegalArgumentException("Username and password are required");
        }
        validateOtp(request);
        String jwt = patientJwtTokenService.generateToken(new HashMap<>() {{
            put("roles", List.of("PATIENT"));
            put("oid", request.getUsername());
        }}, request.getUsername());
        return ResponseEntity.ok(new AuthResponse(jwt));
    }

    private void validateOtp(AuthRequest request) {
        query(StructureQuery.builder()
                .type("otp")
                .criteria(
                        BasicCriteria.builder()
                                .member("$.mobilePhone").type("eq").string(true).value(request.getUsername()),
                        BasicCriteria.builder()
                                .member("$.otp").type("eq").string(true).value(request.getPassword())
                ).build());
    }

    @Data
    static class OtpRequest {
        private String username;
    }

    @Data
    static class AuthRequest {
        private String username;
        private String password;
    }

    @Data
    @AllArgsConstructor
    static class AuthResponse {
        private String jwt;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy