/*
    The SEHandler-Class will be used to interact with the A-Trust RK ONLINE security device.
*/
::CLASS SEHandler public
::ATTRIBUTE username
::ATTRIBUTE password
::ATTRIBUTE sigZert_value
::ATTRIBUTE zertstellen_value
::ATTRIBUTE zertnummer_value
::ATTRIBUTE zertSerienNr_value
::ATTRIBUTE alg_value
::ATTRIBUTE seIsOut
::ATTRIBUTE testEnv
::METHOD init
------------------------------------------------------------------------------------------------------------------------
::METHOD login PUBLIC
 EXPOSE username password sigZert_value zertstellen_value zertnummer_value zertSerienNr_value alg_value testEnv
 USE ARG username, password, testEnv

 username = username
 password = password
 testEnv = testEnv

IF testEnv = .true THEN DO
    urlStr = "https://hs-abnahme.a-trust.at/asignrkonline/v2/" || username || "/Certificate"     -- TEST
END
ELSE DO
    urlStr = "https://www.a-trust.at/asignrkonline/v2/" || username || "/Certificate"    -- LIVE
END
 url = .bsf~new("java.net.URL", urlStr)

 SIGNAL ON ANY
 conn = url~openConnection
 conn~setRequestMethod("GET")
 rd = .bsf~new("java.io.BufferedReader", .bsf~new("java.io.InputStreamReader", conn~getInputStream))
 mb = .mutableBuffer~new
 line = rd~readLine
DO WHILE line <> .nil
     mb~append(line)
     line = rd~readLine
END
 responseStr = mb~string   -- create a single string
 rd~close
 conn~disconnect
 PARSE VAR responseStr '{"' sigZert_name '":"' sigZert_value '","' zertstellen_name '":["' zertstellen_value '"],"' zertnummer_name '":"' zertnummer_value '","' zertSerienNr_name '":"' zertSerienNr_value '","' alg_name '":"' alg_value '"}'
 .my.app~SEHandler~seIsOut = .false
 .my.app~remotePay = .true
 .my.app~offPay =.false
 EXIT 0
------------------------------------------------------------------------------------------------------------------------
ANY:
    .my.app~SEHandler~seIsOut = .true
------------------------------------------------------------------------------------------------------------------------
::METHOD getCertificateHex PUBLIC
 EXPOSE zertSerienNr_value
 RETURN zertSerienNr_value
------------------------------------------------------------------------------------------------------------------------
::METHOD updateSessionDetailsDB PUBLIC
 EXPOSE username password
 USE ARG testEnv = .true

IF testEnv = .true THEN DO
    urlStr = "https://hs-abnahme.a-trust.at/asignrkonline/v2/Session/" || username
END
ELSE DO
    urlStr = "https://www.a-trust.at/asignrkonline/v2/Session/" || username
END
 url = .bsf~new("java.net.URL", urlStr)
 SIGNAL ON ANY
 conn = url~openConnection
 conn~setRequestMethod("PUT")
 conn~setDoOutput(.true)
 conn~setDoInput(.true)
 conn~setUseCaches(.false)
 conn~setAllowUserInteraction(.false)
 conn~setRequestProperty("Content-Type", "application/json")

 request = '{"password":"'|| password ||'"}'
 out = conn~getOutputStream
 writer = .bsf~new("java.io.OutputStreamWriter", out , "UTF-8")
 writer~write(request)
 writer~close
 out~close
 rd = .bsf~new("java.io.BufferedReader", .bsf~new("java.io.InputStreamReader", conn~getInputStream))
 mb = .mutableBuffer~new
 line = rd~readLine
DO WHILE line <> .nil
   mb~append(line)
   line = rd~readLine
END
 responseStr = mb~string   -- create a single string
 rd~close
 conn~disconnect
 PARSE VAR responseStr '{"' . '":"' sessionID '","' . '":"' sessionKey '"}'

 .my.app~DatabaseHandler~updateSessionData(1,sessionID,sessionKey)

 EXIT 0
------------------------------------------------------------------------------------------------------------------------
ANY:
  .my.app~SEHandler~seIsOut = .true
------------------------------------------------------------------------------------------------------------------------
::METHOD getZDAData PUBLIC
 EXPOSE username
 USE ARG testEnv = .true

IF testEnv = .true THEN DO
    urlStr = "https://hs-abnahme.a-trust.at/asignrkonline/v2/" || username || "/ZDA"
END
ELSE DO
    urlStr = "https://www.a-trust.at/asignrkonline/v2/" || username || "/ZDA"
END
 url = .bsf~new("java.net.URL", urlStr)

 SIGNAL ON ANY
 conn = url~openConnection
 conn~setRequestMethod("GET")
 rd = .bsf~new("java.io.BufferedReader", .bsf~new("java.io.InputStreamReader", conn~getInputStream))
 mb = .mutableBuffer~new
 line = rd~readLine

DO WHILE line <> .nil
   mb~append(line)
   line = rd~readLine
END
 responseStr = mb~string   -- create a single string
 rd~close
 conn~disconnect

 PARSE VAR responseStr '{"' . '":"' zda_value '"}'
 RETURN zda_value
 EXIT 0
------------------------------------------------------------------------------------------------------------------------
ANY:
   .my.app~SEHandler~seIsOut = .true
------------------------------------------------------------------------------------------------------------------------
::METHOD getJWS PUBLIC
 USE ARG headerAlgValue, Payload, testEnv = .true

 Header = '{"alg":"'|| headerAlgValue ||'"}'
 Header = Header~encodeBase64

 Payload = Payload~makeString
 Payload = Payload~encodeBase64

 to_be_signed = Header || '.' || Payload

 sessionIDplusKey = .my.app~DatabaseHandler~getSessionData("1")
 PARSE VAR sessionIDplusKey sessionID sessionKey

IF testEnv = .true THEN DO
    urlStr = "https://hs-abnahme.a-trust.at/asignrkonline/v2/Session/" || sessionID || "/Sign/JWS"
END
ELSE DO
    urlStr = "https://www.a-trust.at/asignrkonline/v2/Session/" || sessionID || "/Sign/JWS"
END

 url = .bsf~new("java.net.URL", urlStr)
 SIGNAL ON ANY
 conn = url~openConnection

 conn~setRequestMethod("POST")
 conn~setDoOutput(.true)
 conn~setDoInput(.true)
 conn~setUseCaches(.false)
 conn~setAllowUserInteraction(.false)
 conn~setRequestProperty("Content-Type", "application/json")

 request = '{"sessionkey":"' || sessionKey || '", "' 'jws_payload":"' || payload '"}'
 out = conn~getOutputStream
 writer = .bsf~new("java.io.OutputStreamWriter", out , "UTF-8")
 writer~write(request)
 writer~close
 out~close

 rd = .bsf~new("java.io.BufferedReader", .bsf~new("java.io.InputStreamReader", conn~getInputStream))
 mb = .mutableBuffer~new
 line = rd~readLine
DO WHILE line <> .nil
   mb~append(line)
   line = rd~readLine
END
 responseStr = mb~string   -- create a single string
 rd~close
 conn~disconnect

 PARSE VAR responseStr '{"' . '":"' jws_header '.' jws_payload '.' jws_signature '"}'
 RETURN jws_header jws_payload jws_signature
 EXIT 0
------------------------------------------------------------------------------------------------------------------------
ANY:
    .my.app~SEHandler~seIsOut = .true
------------------------------------------------------------------------------------------------------------------------
::REQUIRES "BSF.CLS"
::REQUIRES "DatabaseHandler_v2.CLS"
::REQUIRES "collection.rexx"

/*   License:

     ------------------------ Apache Version 2.0 license -------------------------
        Copyright (C) 2021 Manuel Schwarzer

        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at

            http://www.apache.org/licenses/LICENSE-2.0

        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
     -----------------------------------------------------------------------------
 */