Merge pull request #145 from dikstub-rssa/fix/anything-moko
fix (encounter): add guard for create, delete and cancel
This commit is contained in:
@@ -104,10 +104,14 @@ type UpdateDto struct {
|
||||
type UpdateStatusDto struct {
|
||||
Id uint16 `json:"id"`
|
||||
StatusCode erc.DataStatusCode `json:"status_code"`
|
||||
|
||||
pa.AuthInfo
|
||||
}
|
||||
|
||||
type DeleteDto struct {
|
||||
Id uint16 `json:"id"`
|
||||
|
||||
pa.AuthInfo
|
||||
}
|
||||
|
||||
type MetaDto struct {
|
||||
|
||||
@@ -89,9 +89,14 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
if id <= 0 {
|
||||
return
|
||||
}
|
||||
authInfo, err := pa.GetAuthInfo(r)
|
||||
if err != nil {
|
||||
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
|
||||
}
|
||||
|
||||
dto := e.DeleteDto{}
|
||||
dto.Id = uint16(id)
|
||||
dto.AuthInfo = *authInfo
|
||||
res, err := u.Delete(dto)
|
||||
rw.DataResponse(w, res, err)
|
||||
}
|
||||
@@ -159,11 +164,17 @@ func (obj myBase) Cancel(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
authInfo, err := pa.GetAuthInfo(r)
|
||||
if err != nil {
|
||||
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
|
||||
}
|
||||
|
||||
dto := e.UpdateStatusDto{
|
||||
Id: uint16(id),
|
||||
StatusCode: erc.DSCCancel,
|
||||
}
|
||||
|
||||
dto.AuthInfo = *authInfo
|
||||
res, err := u.UpdateStatusCode(dto)
|
||||
rw.DataResponse(w, res, err)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ type AuthInfo struct {
|
||||
Uuid string
|
||||
User_Id uint
|
||||
User_Name string
|
||||
User_ContractPosition_code string
|
||||
User_ContractPosition_Code string
|
||||
Employee_Position_Code *string
|
||||
Employee_Id *uint
|
||||
Doctor_Code *string
|
||||
|
||||
@@ -205,7 +205,7 @@ func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err
|
||||
User_Name: fmt.Sprintf("%v", claims["user_name"]),
|
||||
}
|
||||
|
||||
data.User_ContractPosition_code = checkStrClaims(claims, "contractPosition_code")
|
||||
data.User_ContractPosition_Code = checkStrClaims(claims, "contractPosition_code")
|
||||
data.Employee_Position_Code = checkStrPtrClaims(claims, "employee_position_code")
|
||||
data.Doctor_Code = checkStrPtrClaims(claims, "doctor_code")
|
||||
data.Nurse_Code = checkStrPtrClaims(claims, "nurse_code")
|
||||
|
||||
@@ -16,10 +16,10 @@ import (
|
||||
|
||||
erc "simrs-vx/internal/domain/references/common"
|
||||
ere "simrs-vx/internal/domain/references/encounter"
|
||||
erg "simrs-vx/internal/domain/references/organization"
|
||||
|
||||
eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist"
|
||||
edc "simrs-vx/internal/domain/main-entities/death-cause"
|
||||
eem "simrs-vx/internal/domain/main-entities/employee"
|
||||
e "simrs-vx/internal/domain/main-entities/encounter"
|
||||
eir "simrs-vx/internal/domain/main-entities/internal-reference"
|
||||
erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist"
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
|
||||
uaeh "simrs-vx/internal/use-case/main-use-case/adm-employee-hist"
|
||||
udc "simrs-vx/internal/use-case/main-use-case/death-cause"
|
||||
uem "simrs-vx/internal/use-case/main-use-case/employee"
|
||||
uir "simrs-vx/internal/use-case/main-use-case/internal-reference"
|
||||
urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist"
|
||||
)
|
||||
@@ -79,6 +78,19 @@ func Create(input e.CreateDto) (*d.Data, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// check only user with registration position is allowed to create encounter
|
||||
if input.AuthInfo.User_ContractPosition_Code != string(erg.EPCReg) {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "auth-forbidden",
|
||||
Detail: "user position is not allowed, only user with registration position is allowed to create encounter",
|
||||
Raw: errors.New("authentication failed"),
|
||||
}
|
||||
return nil, pl.SetLogError(&event, input)
|
||||
} else {
|
||||
input.Adm_Employee_Id = input.AuthInfo.Employee_Id
|
||||
}
|
||||
|
||||
// check if patient is new in the hospital
|
||||
input.NewStatus, err = identifyPatientStatus(input)
|
||||
|
||||
@@ -90,12 +102,6 @@ func Create(input e.CreateDto) (*d.Data, error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if emp, err := uem.ReadDetailData(eem.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx); err != nil {
|
||||
return err
|
||||
} else {
|
||||
input.Adm_Employee_Id = &emp.Id
|
||||
}
|
||||
|
||||
// create encounter
|
||||
if resData, err := CreateData(input, &event, tx); err != nil {
|
||||
return err
|
||||
@@ -322,6 +328,17 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
|
||||
// Start log
|
||||
pl.SetLogInfo(&event, input, "started", "delete")
|
||||
|
||||
// check only user with registration position is allowed to create encounter
|
||||
if input.AuthInfo.User_ContractPosition_Code != string(erg.EPCReg) {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "auth-forbidden",
|
||||
Detail: "user position is not allowed, only user with registration position is allowed to create encounter",
|
||||
Raw: errors.New("authentication failed"),
|
||||
}
|
||||
return nil, pl.SetLogError(&event, input)
|
||||
}
|
||||
|
||||
err = dg.I.Transaction(func(tx *gorm.DB) error {
|
||||
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
|
||||
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
|
||||
@@ -494,6 +511,21 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) {
|
||||
// TODO: Prevent cancellation if the billing has been verified
|
||||
|
||||
// TODO: Only "supervisi pendaftaran" could cancel encounter
|
||||
roleAllowedToCancel := []string{
|
||||
string(erg.EPCReg),
|
||||
string(erg.EPCNur),
|
||||
string(erg.EPCDoc),
|
||||
}
|
||||
|
||||
if !pu.Contains(roleAllowedToCancel, input.AuthInfo.User_ContractPosition_Code) {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "auth-forbidden",
|
||||
Detail: "user position is not allowed, only user with registration, nurse, or doctor position is allowed to cancel encounter",
|
||||
Raw: errors.New("authentication failed"),
|
||||
}
|
||||
return pl.SetLogError(&event, input)
|
||||
}
|
||||
|
||||
// Prevent cancellation if soapi exist
|
||||
encounterId := uint(input.Id)
|
||||
|
||||
@@ -150,3 +150,19 @@ func IsDateBeforeNow(t *time.Time) bool {
|
||||
}
|
||||
return t.Before(time.Now())
|
||||
}
|
||||
|
||||
// Contains reports whether v is present in s.
|
||||
func Contains[S ~[]E, E comparable](s S, v E) bool {
|
||||
return index(s, v) >= 0
|
||||
}
|
||||
|
||||
// Index returns the index of the first occurrence of v in s,
|
||||
// or -1 if not present.
|
||||
func index[S ~[]E, E comparable](s S, v E) int {
|
||||
for i := range s {
|
||||
if v == s[i] {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user