diff --git a/v1/Application.cfc b/v1/Application.cfc index a98f3b6..ad73d5c 100644 --- a/v1/Application.cfc +++ b/v1/Application.cfc @@ -1,4 +1,4 @@ - +` @@ -51,7 +51,7 @@ //variables.framework.docs={}; variables.framework.docs.APIName="svc-api"; - variables.framework.docs.APIVersion="0.150"; /*$ git config --global --unset user.password*/ + variables.framework.docs.APIVersion="0.151"; /*$ git config --global --unset user.password*/ variables.framework.globalHeaders = structNew(); variables.framework.globalHeaders["Access-Control-Expose-Headers"] = "Location"; diff --git a/v1/Application.cfc.bak b/v1/Application.cfc.bak new file mode 100644 index 0000000..a98f3b6 --- /dev/null +++ b/v1/Application.cfc.bak @@ -0,0 +1,879 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + this.name = hash(getCurrentTemplatePath()); + //variables.framework = structNew(); // + variables.framework.debugKey = "debug"; + variables.framework.reloadKey = "reload"; + variables.framework.reloadPassword = "true"; + variables.framework.reloadOnEveryRequest = true; + variables.framework.serializer = "taffy.core.nativeJsonSerializer"; + //variables.framework.serializer = "JsonUtilSerializer"; + variables.framework.dashboardKey = "dashboard"; + variables.framework.disableDashboard = false; + variables.framework.unhandledPaths = "/flex2gateway"; + variables.framework.allowCrossDomain = true; // соответствующие заголовки, включая Access-Control-Allow-Origin выставляются только при наличии заголовка origin в реквесте + //variables.framework.allowCrossDomain = ""; // перепишем явно, возвращая Origin + + //variables.framework.docs={}; + variables.framework.docs.APIName="svc-api"; + variables.framework.docs.APIVersion="0.150"; /*$ git config --global --unset user.password*/ + + variables.framework.globalHeaders = structNew(); + variables.framework.globalHeaders["Access-Control-Expose-Headers"] = "Location"; + variables.framework.globalHeaders["Access-Control-Allow-Credentials"] = "true"; + variables.framework.globalHeaders["X-Application-Version"] = variables.framework.docs.APIVersion; + //variables.framework.globalHeaders["Access-Control-Allow-Origin"] = "*"; + + request.UNDEFINED_USR_ID=-1; + request.ANONYMOUS_USR_ID=2; + request.GUEST_USR_ID=3; + request.USER_AGENT="#variables.framework.docs.APIName# #variables.framework.docs.APIVersion# stand:#this.getStand()#"; + + //////////////////////////////////////////////////////// + request.ORCHESTRATOR_AUTH = createObject("java", "java.lang.System").getEnv("ORCHESTRATOR_AUTH"); + if (isNull(request.ORCHESTRATOR_AUTH)) { + request.ORCHESTRATOR_AUTH = "Basic c3ZjX2xrdGVzdDoxMTgzZDIyNzc1OWExYjFkZmVjM2M3NTFiMzIyNzdiYTQ3";//*** времянка, дубль из deck/Application.cfm + } + request.vault_role_id=createObject("java", "java.lang.System").getEnv("VAULT_ROLE_ID");// *** дальше к ним обращаемся через this (а надо блокировать приложение при этом?) + request.vault_secret_id=createObject("java", "java.lang.System").getEnv("VAULT_SECRET_ID");//*** тут в другом скоупе, не как deck, и вообще стоит ли это делать в псевдоконструкторе + + + //*** почему-то scope this ведет себя совершенно не так, как request и variables + // в нем, когда переменная получает значение Empty:null, можно выполнить writedump, а в других получаем ошибку, что такой переменной нет + + request.auth_header=""; + request.locateIamService=locateIamService; //for possible debug + //request.IAM_SERVICE_URL=this.iamServiceUrl; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select value as stand from config + where name='STAND' + + + + + + + + + + + + + + + + + + + + + + + + + + + select value as stand from config + where name='STAND' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ---> + + + + + + function onTaffyRequest(verb, cfc, requestArguments, mimeExt, headers){ + /* https://docs.taffy.io/#/3.5.0 */ +/* + //allow white-listed requests through + + if (cfc == "login"){ + return true; + } + + //otherwise require a device token + if (!structKeyExists(requestArguments, "deviceToken")){ + return newRepresentation().noData().withStatus(401, "Authentication Required"); + + //and make sure it's valid + }else if (!validateToken(requestArguments.deviceToken)){ + + return newRepresentation().noData().withStatus(403, "Not Authorized"); + } + + //return representationOf(requestArguments); + //if a token is included, and valid, allow the request to continue + return true; +*/ +//////////////////////////////////////////////// +// самым грубым образом получаем данные от IDP, не обрабатывая исключения + + + //if (variables.framework.allowCrossDomain EQ "") { + //corsHeaders(); // *** нужно, чтобы variables.framework.allowCrossDomain="" иначе задвоятся заголовки + //} + + //if (UCase(arguments.verb) EQ 'OPTIONS') return newRepresentation().noData().withStatus("204","No Data").withHeaders({"Content-Type":"application/json;charset=utf-8"}); + if (uCase(arguments.verb) EQ 'OPTIONS') return true; + if (lCase(arguments.cfc) EQ 'err') return true; + if (lCase(arguments.cfc) EQ 'throw') return true; + + + if (structKeyExists(headers,"Authorization")) { + request.auth_header=headers.Authorization; + } else { + return representationOf("Authorization header expected").withStatus(401); + } + var result=""; + try { + var httpService = new http(method = "GET", charset = "utf-8", url = #this.iamServiceUrl#, timeout="5"); + httpService.addParam(type = "HEADER", name = "Accept", value = "application/json"); + httpService.addParam(type = "HEADER", name = "Authorization", value = "#request.auth_header#"); //passthrough + //writedump(this.iamServiceUrl);abort; + var resp = httpService.send(); + //if (resp.status_code NEQ 200) throw("IDP response not OK"); + //writedump(resp);abort; + var prefix = resp.getPrefix(); + if (prefix.status_code NEQ 200) { + //writedump(this.iamServiceUrl); + //writedump(resp); + var iamStatusCode = (isValid("integer", prefix.status_code)) ? val(prefix.status_code) : 500; + return representationOf( {"iamServiceUrl"=this.iamServiceUrl, "idpResponse"=resp} ).withStatus(iamStatusCode); + //abort; + //throw("IDP response not OK"); + } + result = prefix.filecontent; + //writedump(result);abort; + } catch (e) { + /*if (fileExists("#GetDirectoryFromPath(GetCurrentTemplatePath())#/etc/local-debug")) { //true for local debug without IDP, etc/* does not go to repository + var result='{"accounts":[{"login":"","type":"telegram"}],"avatar":["d2d2b7ac-50af-432b-b7c4-f7d6561e288a"],"company":"ООО «НУБЕС»","companyId":"8ec70ac0-546d-42a7-8cff-339c8fb51a23","contactId":"983967a3-58c2-4cdd-84a5-8b427ccfac82","email":"smishchuk@nubes.ru","externalUser":false,"fio":{"fullName":"Мищук Сергей ","name":"Сергей","secondName":"","surname":"Мищук"},"groupIds":["94bf5be7-52f4-5c13-87c3-513786934685","ab12b6b8-0265-4683-a5c2-5e1a74a55216","aff008c3-7443-50f6-86e1-ecff3cd3b04d","d6000da0-c9aa-55eb-9882-f118b432730b","d89a33dc-3177-5854-9580-f7f860a5ab7c","ddfe2555-9ef4-42cb-9a2b-7f24e61e7747","df12926f-ecb8-5479-857f-6d291464baad","fda5c295-230a-5025-9797-b8b4e99e08aa","2be9b4b6-94d1-59f9-a649-cab228d82169","64fe6f5c-a91b-5fea-a7ca-d9823701ebd4"],"integration":{"serviceId":""},"login":"smishchuk@nubes.ru","mobilePhone":[],"position":"","userId":"d72530e1-66a4-412f-a046-38153c4e5405"}';} + */ + //writedump(resp); + //return representationOf( {"exception"=e} ); + return representationOf( {"exception"=e, "idpResponse"=result} ).withStatus(200); + } + + //writeDump(result); abort; + try { + var idpUserData=deserializeJson(result); + arguments.requestArguments.companyUid=idpUserData.userInfo.companyId;//GUID! + arguments.requestArguments.usrUid=idpUserData.userInfo.contactId;//userId; //GUID! + } catch (e) { + return representationOf( {"exception"=e, "idpResponse"=result} ); + } + + var usrCustomerInfo=getUsrCustomerInfo(idpUserData.userInfo.contactId, idpUserData.userInfo.companyId); + + if (lCase(arguments.cfc) EQ 'user') { + if (structIsEmpty(usrCustomerInfo)) return representationOf("User information not found").withStatus(404); + } + + if (lCase(arguments.cfc) EQ 'notification_ls') { //*** костыль: для нотификаций можно адресоваться к пользователю без контракта + if (structIsEmpty(usrCustomerInfo)) { + arguments.requestArguments.usrId=-1; //Integer! + arguments.requestArguments.contragentId=-1; //Integer + arguments.requestArguments.contractId=-1; //Integer + arguments.requestArguments.specificationId=-1; //Integer + + return true; + } + } + + if (structIsEmpty(usrCustomerInfo)) return representationOf("Cannot find default specification for current user #result#").withStatus(422); //это создает довольно много лишних движений при отладке + + arguments.requestArguments.usrId=usrCustomerInfo.usrId; //Integer! + arguments.requestArguments.contragentId=usrCustomerInfo.contragentId; //Integer + arguments.requestArguments.contractId=usrCustomerInfo.contractId; //Integer + arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //Integer + + return true; + + +//////////////////////////////////////////////////////////////////////////// + //ensure https because of basic authentication + if (!lcase(request.config.environment) == "development"){ + if (!cgi.server_port_secure) { return newRepresentation().noData().withStatus("403.4", "SSL Required");} + } + + request.usr_id=request.UNDEFINED_USR_ID; + + if (checkAuth()) {return true;} + + //return representationOf(arguments.headers); + //return representationOf(arguments.cfc); + var authToken=""; + if (structKeyExists(arguments.headers,"x-auth-token")) {authToken=structFind(arguments.headers,"x-auth-token");} + var issuedFor=""; + if (structKeyExists(arguments.headers,"x-issued-for")) {issuedFor=structFind(arguments.headers,"x-issued-for");} + if (validatePin(authToken,issuedFor, arguments.verb, arguments.cfc)) return true; //side effect: sets request.usr_id! + + if (!validateCredentials(getBasicAuthCredentials())) { + return newRepresentation().noData().withStatus("401", "Invalid Credentials").withHeaders({"WWW-Authenticate":"Basic realm=mms-api"}); + } + return true; + } + + //private function validateToken(token){ return false; } + + //refactoring required + private function validateCredentials(credentials) {//return true; + if (arguments.credentials.username == "medved" /*AND credentials.password == "ghtdtlrhjcfdxtu!Y"*/) { + request.usr_id=-3; + return true; + } + return false; + } + + + + + + + + + + + + + + + + + + + + select usr_id from usr where login= + + + + + + + + + + + + #cfcatch.message# : #cfcatch.detail# + + + + + + #cfcatch.message# : #cfcatch.detail# + + + + + + + + + + + + + + + + + + + + + + select z.contragent_id, c.contragent_id, c.contract_id, s.specification_id + from contragent z + join contract c on (z.contragent_id=c.contragent_id) + join specification s on (c.contract_id=s.contract_id) + where z.external_uid= + order by s.specification_id desc + limit 1; + + + + + select u.usr_id, c.contragent_id, c.contract_id, s.specification_id + from usr u + join contract c on (u.contragent_id=c.contragent_id) + join specification s on (c.contract_id=s.contract_id) + where u.idp_usr_uid= + order by s.specification_id desc + limit 1; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #local.resultSerialized# + + + +

Request Details:

+
+ + +
+ + + + + +
diff --git a/v1/resources/instance_operation.cfc b/v1/resources/instance_operation.cfc index 5c9193a..39e9816 100644 --- a/v1/resources/instance_operation.cfc +++ b/v1/resources/instance_operation.cfc @@ -100,8 +100,32 @@ from instance_state st where st.instance_operation_uid= order by st.version desc limit 1 + + + + select + + st.instance_state_uid::text as instance_state_uid + st.version + st.creator_id + to_char(st.dt_state, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM') as dt_state + st.is_test + st.instance_operation_uid::text as instance_operation_uid + st.instance_data::text as instance_data + + from instance_state st + where st.instance_uid= + order by st.version desc limit 1 + + + + + + + + select @@ -132,8 +156,9 @@ sop.sort iop.note sop.nested_ref - sop.config::text - null as nested_ref_data + sop.config::text as config + null as nested_ref_data + sop.state_path sop.is_sensitive from svc_operation_cfs_param sop @@ -169,6 +194,17 @@ }/> + + + diff --git a/v1/resources/instance_operation_cfs_param.cfc b/v1/resources/instance_operation_cfs_param.cfc index 93a5a0f..55e5750 100644 --- a/v1/resources/instance_operation_cfs_param.cfc +++ b/v1/resources/instance_operation_cfs_param.cfc @@ -55,8 +55,10 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In sop.man sop.func sop.nested_ref - sop.config + sop.config::text as config + sop.state_path e.service_id + e.instance_uid from instance_operation_cfs_param iop join svc_operation_cfs_param sop on (iop.svc_operation_cfs_param_id=sop.svc_operation_cfs_param_id) @@ -86,6 +88,21 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In + + + + select g.instance_state_uid, g.version, g.instance_data, g.is_test, g.instance_uid + from instance_state g + where g.instance_uid= + order by g.version desc + limit 1 + + + + + + + @@ -404,6 +421,20 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In + + + + + + + + + + + + + +
\ No newline at end of file