ApiResponse

This commit is contained in:
MathewFrancis 2025-08-25 13:33:35 +05:30
parent f716457c1f
commit d71fffd353
5 changed files with 300 additions and 12 deletions

View File

@ -0,0 +1,115 @@
package com.example.cezenBTC.config;
import com.example.cezenBTC.DAO.UserOpsDAO;
import com.example.cezenBTC.entity.user.UserEntity;
import com.example.cezenBTC.service.ABS.ABSServiceForLogIn;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class CezenABSAuthenticationProvider implements AuthenticationProvider/* */{
@Autowired
private UserOpsDAO userOpsDAO;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private ABSServiceForLogIn absServiceForLogIn;
//@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//get credentials from login form
String[] karthickHamu = authentication.getName().split(",");
String userStringId = karthickHamu[0];
String btId = karthickHamu[1];
String pwd = authentication.getCredentials().toString();
System.out.println("user Id " + userStringId + " password " + pwd);
//sanity check
if (userStringId.isEmpty() || pwd.isEmpty()) return null;
// validate if the user input consists of only numbers
// and in the number rage is only 12
try{
if(userStringId.length() != 12){
System.out.println("Number not equal to 12");
return null;
}
Double.parseDouble(userStringId);
}catch (Exception e){
System.out.println(e.toString());
return null;
}
//check for employee
UserEntity user = null;
try {
//check if employee exists if yes then fetch details
user = this.userOpsDAO.getUserByUserStringId(userStringId);
} catch (Exception e) {
System.out.println(e.toString());
return null;
}
Object returnData = null;
// for(int i =0; i < 5; i++){
//
// if(returnData != null && returnData)
//
// }
// this need to change for ABS
if (passwordEncoder.matches(pwd, user.getPassword())) {
//then it is a match a number of springs granted authorities
List<GrantedAuthority> authorities = new ArrayList<>();
//loop through the users authorities and add each of them to simple granted authority
try {
//check if user is part of permission set for admin signing in
boolean isAdmin = false;
for(var permission : user.getRoles()){
if(permission.getRole().equals("ROLE_admin")) isAdmin = true;
}
if(!isAdmin) throw new BadCredentialsException("no employee permission for given employee");
user.getRoles().forEach(a -> authorities.add(new SimpleGrantedAuthority(a.getRole())));
} catch (Exception e) {
//use/**/r doesn't have permissions or roles = null
System.out.println(e.toString());
return null;
}
System.out.println("Auth DONE");
return new UsernamePasswordAuthenticationToken(user.getUserIdNumber()+","+btId, pwd, authorities);
} else {
throw new BadCredentialsException("Invalid password!");
}
}
@Override
public boolean supports(Class<?> authentication) {
//tells spring that i want to support username password style of auth
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
}

View File

@ -17,7 +17,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@Component @Component
public class CezenCustomAuthenticationProviderForBTC implements AuthenticationProvider { public class CezenCustomAuthenticationProviderForBTC /*implements AuthenticationProvider */ {
@Autowired @Autowired
private UserOpsDAO userOpsDAO; private UserOpsDAO userOpsDAO;
@ -25,12 +25,12 @@ public class CezenCustomAuthenticationProviderForBTC implements AuthenticationPr
@Autowired @Autowired
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@Override //@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException { public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//get credentials from login form //get credentials from login form
String[] karthickHamu = authentication.getName().split(","); String[] karthickHamu = authentication.getName().split(",");
String userStringId = karthickHamu[0]; String userStringId = karthickHamu[0]+"disabled by ABS";
String btId = karthickHamu[1]; String btId = karthickHamu[1];
String pwd = authentication.getCredentials().toString(); String pwd = authentication.getCredentials().toString();
@ -92,10 +92,10 @@ public class CezenCustomAuthenticationProviderForBTC implements AuthenticationPr
} }
} }
@Override // @Override
public boolean supports(Class<?> authentication) { // public boolean supports(Class<?> authentication) {
//tells spring that i want to support username password style of auth // //tells spring that i want to support username password style of auth
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); // return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
} // }
} }

View File

@ -1,11 +1,10 @@
package com.example.cezenBTC.controller; package com.example.cezenBTC.controller;
import com.example.cezenBTC.DTO.CenteralServerConect.ApiResponse;
import com.example.cezenBTC.absbridge.model.HealthResponse; import com.example.cezenBTC.absbridge.model.HealthResponse;
import com.example.cezenBTC.absbridge.model.LoginRequest; import com.example.cezenBTC.absbridge.model.LoginRequest;
import com.example.cezenBTC.config.AbsClient;
import com.example.cezenBTC.service.ABS.ABSServiceForLogIn; import com.example.cezenBTC.service.ABS.ABSServiceForLogIn;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -35,8 +34,8 @@ public class AbsController {
} }
@PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public Object login(@RequestBody LoginRequest req) { public ApiResponse login(@RequestBody LoginRequest req) {
return absServiceForLogIn.loginRew(req); return absServiceForLogIn.loginRewWithFixedResponse(req);
} }
} }

View File

@ -1,5 +1,9 @@
package com.example.cezenBTC.service.ABS; package com.example.cezenBTC.service.ABS;
import com.example.cezenBTC.DTO.CenteralServerConect.ApiResponse;
import com.example.cezenBTC.DTO.CenteralServerConect.Encryption;
import com.example.cezenBTC.DTO.CenteralServerConect.Log;
import com.example.cezenBTC.DTO.CenteralServerConect.RcvHeaderRaw;
import com.example.cezenBTC.DTO.bridge.RcvHeader; import com.example.cezenBTC.DTO.bridge.RcvHeader;
import com.example.cezenBTC.DTO.bridge.RcvLog; import com.example.cezenBTC.DTO.bridge.RcvLog;
import com.example.cezenBTC.absbridge.core.AbsProtocol; import com.example.cezenBTC.absbridge.core.AbsProtocol;
@ -155,6 +159,7 @@ public class ABSServiceForLogIn {
} }
} }
json.put("offsetProbe", Map.of( json.put("offsetProbe", Map.of(
"bodyOffset", bodyOffset, "bodyOffset", bodyOffset,
"around", new String(slice(reply, Math.max(0, bodyOffset - 8), "around", new String(slice(reply, Math.max(0, bodyOffset - 8),
@ -177,6 +182,175 @@ public class ABSServiceForLogIn {
} }
public ApiResponse loginRewWithFixedResponse(LoginRequest req){
ApiResponse apiResponse = null;
try {
if (isEmpty(req.opCard) || isEmpty(req.btId) || (isEmpty(req.password) && isEmpty(req.passwordEnc))) {
throw new Exception("One of the fields are empty");
}
String passwd;
Map<String, Object> encMeta = new LinkedHashMap<>();
if (req.passwordEnc != null && !req.passwordEnc.isBlank()) {
passwd = req.passwordEnc;
encMeta.put("used", false);
encMeta.put("providedPasswordEnc", true);
} else {
AbsProtocol.Enc enc = AbsProtocol.encryptPasswordLikeMFC(req.password);
passwd = enc.enc();
encMeta.put("used", true);
encMeta.put("utcSeconds", enc.utcSeconds());
encMeta.put("key", enc.key());
encMeta.put("encPasswd", passwd);
}
int btMake = extractBtMake(req.btMake);
byte[] sndHeader = AbsProtocol.packSndHeader(
AbsProtocol.LOG, AbsProtocol.LOGBT, 1, 1, 0, btMake
);
byte[] sndLog = AbsProtocol.packSndLog(
safe(req.usrId), safe(req.opCard), passwd, safe(req.btId)
);
byte[] sendBuf = concat(sndHeader, sndLog);
byte[] reply = client.roundtrip(sendBuf, 10_000);
byte[] hdrSlice = slice(reply, 0, Math.min(reply.length, 24));
RcvHeader rcvHeader = AbsProtocol.parseRcvHeaderFlexible(hdrSlice);
Map<String, Object> json = new LinkedHashMap<>();
json.put("ok", true);
json.put("target", target);
json.put("sentHeaderHex", toHex(sndHeader));
json.put("sentBodyHex", toHex(sndLog));
json.put("replyBytes", reply.length);
json.put("replyHexFirst64", toHex(slice(reply, 0, Math.min(64, reply.length))));
json.put("rcvHeaderRaw", rcvHeader);
json.put("success", rcvHeader.nRetCd() == AbsProtocol.SUCCESS);
json.put("encryption", encMeta);
System.out.println("-".repeat(10) + json.get("ok"));
Object rcvHeaderRaw = json.get("rcvHeaderRaw");
RcvHeader rcvHeaderMix = (RcvHeader) json.get("rcvHeaderRaw");
//building the object
RcvHeaderRaw rcvHeaderRawMix = new RcvHeaderRaw(
rcvHeaderMix.nTxnCd(),
rcvHeaderMix.nRetCd(),
rcvHeaderMix.nNumRecs(),
rcvHeaderMix.nTxnId(),
rcvHeaderMix.cBtMake(),
rcvHeaderMix.size()
);
// Encryption for the builder
boolean used = encMeta.get("used") instanceof Boolean ? (Boolean) encMeta.get("used") : false;
int utcSeconds = encMeta.get("utcSeconds") instanceof Number ? ((Number) encMeta.get("utcSeconds")).intValue() : 0;
int key = encMeta.get("key") instanceof Number ? ((Number) encMeta.get("key")).intValue() : 0;
String encPasswd = encMeta.get("encPasswd") instanceof String ? (String) encMeta.get("encPasswd") : "";
Encryption encryption = new Encryption(used, utcSeconds, key, encPasswd);
Log logDump = null;
System.out.println("-".repeat(10) + encryption);
// ---- body offset logic (like Node) ----
int bodyOffset = rcvHeader.size();
if (reply.length >= bodyOffset + 4) {
int maybeOp = leInt(reply, bodyOffset);
if (maybeOp == AbsProtocol.LOGBT || maybeOp == AbsProtocol.LOG || maybeOp == 0
|| (maybeOp >= 1000 && maybeOp <= 10000)) {
bodyOffset += 4;
json.put("rcvExtraOpCd", maybeOp);
} else {
boolean looksYear = looksYear(reply, bodyOffset);
boolean looksYearFwd = looksYear(reply, bodyOffset + 4);
if (!looksYear && looksYearFwd) bodyOffset += 4;
}
}
if (bodyOffset >= 4 && byteAt(reply, bodyOffset) == (byte)'/') {
if (byteAt(reply, bodyOffset - 4) == '2' && byteAt(reply, bodyOffset - 3) == '0') {
bodyOffset -= 4;
}
}
json.put("offsetProbe", Map.of(
"bodyOffset", bodyOffset,
"around", new String(slice(reply, Math.max(0, bodyOffset - 8),
Math.min(reply.length, bodyOffset + 16)), StandardCharsets.US_ASCII)
));
if ((boolean) json.get("success") && reply.length >= bodyOffset + 20) {
try {
RcvLog log = AbsProtocol.parseRcvLog(reply, bodyOffset);
logDump = new Log(
log.cDateTime(),
log.cUsrNm(),
log.cUsrId(),
log.cSupNm(),
log.cSupId(),
log.cUsrTyp(),
log.fOpenBal(),
log.fTktSalesByVoucher(),
log.fTktSalesByCash(),
log.fTktSalesByMemCard(),
log.nTktSalesByVoucherCount(),
log.nTktSalesByCashCount(),
log.nTktSalesByMemCardCount(),
log.fPayoutByVoucher(),
log.fPayoutByCash(),
log.fPayoutByMemCard(),
log.nPayoutByVoucherCount(),
log.nPayoutByCashCount(),
log.nPayoutByMemCardCount(),
log.fCancelByVoucher(),
log.fCancelByCash(),
log.fCancelByMemCard(),
log.nCancelByVoucherCount(),
log.nCancelByCashCount(),
log.nCancelByMemCardCount(),
log.fDeposit(),
log.fWithdrawAmt(),
log.fVoucherSales(),
log.fVoucherEncash(),
log.fCloseBal(),
log.fSaleTarget(),
log.size()
);
if(log.cDateTime() != null){
// then build the final json response apiResponse
apiResponse = new ApiResponse(
(boolean)json.get("ok"),
(String)json.get("target"),
(String)json.get("sentHeaderHex"),
(String)json.get("sentBodyHex"),
(int)json.get("replyBytes"),
(String)json.get("replyHexFirst64"),
rcvHeaderRawMix,
(boolean)json.get("success"),
encryption,
logDump
);
}
//json.put("log", log);
} catch (Exception ex) {
json.put("parseLogError", ex.toString());
}
}
return apiResponse;
} catch (Exception e) {
return null;
}
}
// ---------- helpers ---------- // ---------- helpers ----------
private static byte[] slice(byte[] a, int off, int end) { private static byte[] slice(byte[] a, int off, int end) {

0
struct.txt Normal file
View File