se adicionan archivos faltantes
FossilOrigin-Name: 85fd66cb6f56b56c71826cb1cc02afa625c277c1f12dc92cfbc741b3808cf646
This commit is contained in:
parent
23d6f668bf
commit
d36259d121
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
|
|
||||||
test: xmlsec1/errors.c xmlsec1/xmltree.c xades.c xades_test.c
|
test: xmlsec1/errors.c xmlsec1/xmltree.c templates.c xades_test.c
|
||||||
$(CC) -o $@ -Wall $(shell pkg-config libxml-2.0 --cflags --libs) $(shell pkg-config xmlsec1 --cflags --libs) $^
|
$(CC) -o $@ -Wall -Werror -std=gnu11 $(shell pkg-config libxml-2.0 --cflags --libs) $(shell pkg-config xmlsec1 --cflags --libs) $^
|
||||||
./test
|
./test
|
||||||
|
@ -1,306 +1,58 @@
|
|||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "xades.h"
|
#include "xades.h"
|
||||||
|
|
||||||
#define xmlXadesAssert2(p, ret) \
|
int
|
||||||
xmlSecAssert2(p, ret)
|
xmlFachoAppSign(xmlDocPtr doc,
|
||||||
|
xmlSecTransformId hashMethodId) {
|
||||||
#define xmlXadesNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \
|
xmlXadesAssert2(doc != NULL, NULL);
|
||||||
xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject)
|
|
||||||
|
|
||||||
#define xmlXadesXmlError2(errorFunction, errorObject, msg, param) \
|
|
||||||
xmlSecXmlError2(errorFunction, errorObject, msg, param)
|
|
||||||
|
|
||||||
#define xmlXadesErrorsSafeString(msg) \
|
|
||||||
xmlSecErrorsSafeString(msg)
|
|
||||||
|
|
||||||
#define xmlXadesInternalError(errorFunction, errorObject) \
|
|
||||||
xmlSecInternalError(errorFunction, errorObject)
|
|
||||||
|
|
||||||
#define xmlXadesNodeAlreadyPresentError(parent, nodeName, errObject) \
|
|
||||||
xmlSecNodeAlreadyPresentError(parent, nodeName, errObject)
|
|
||||||
|
|
||||||
xmlNodePtr
|
|
||||||
xmlXadesTmplQualifyingPropertiesCreateNsPref(xmlDocPtr doc, const xmlChar* id, const xmlChar* nsPrefix) {
|
|
||||||
xmlNodePtr qualifyingPropertiesNode;
|
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
xmlNsPtr ns;
|
xmlNodePtr signedSignaturePropertiesNode;
|
||||||
|
xmlNodePtr signaturePolicyIdentifierNode;
|
||||||
|
xmlNodePtr signaturePolicyIdNode;
|
||||||
|
xmlChar* signedPropertiesId = BAD_CAST "ref1-signedprops";
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
// crear nodo
|
cur = xmlXadesTmplQualifyingPropertiesCreateNsPref(doc, "qualify-ref1", BAD_CAST "ds");
|
||||||
qualifyingPropertiesNode = xmlNewDocNode(doc, NULL, xmlXadesNodeQualifyingProperties, NULL);
|
|
||||||
if (qualifyingPropertiesNode == NULL) {
|
|
||||||
xmlXadesXmlError2("xmlNewDocNode", NULL, "node=%s", xmlXadesErrorsSafeString(xmlXadesNodeQualifyingProperties));
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// crear namespace y asignar
|
|
||||||
ns = xmlNewNs(qualifyingPropertiesNode, xmlXadesDSigNs, nsPrefix);
|
|
||||||
if (ns == NULL) {
|
|
||||||
xmlXadesXmlError2("xmlNewNs", NULL,
|
|
||||||
"ns=%s", xmlXadesErrorsSafeString(xmlXadesDSigNs));
|
|
||||||
xmlFreeNode(qualifyingPropertiesNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
xmlSetNs(qualifyingPropertiesNode, ns);
|
|
||||||
|
|
||||||
if (id != NULL) {
|
|
||||||
xmlSetProp(qualifyingPropertiesNode, BAD_CAST "id", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add SignedProperties
|
|
||||||
cur = xmlSecAddChild(qualifyingPropertiesNode, xmlXadesNodeSignedProperties, xmlXadesDSigNs);
|
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedProperties)", NULL);
|
return(-1);
|
||||||
xmlFreeNode(qualifyingPropertiesNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cur = xmlXadesTmplAddSignedProperties(cur, signedPropertiesId);
|
||||||
return (qualifyingPropertiesNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xmlNodePtr
|
|
||||||
xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr parentNode, const xmlChar* id, struct tm* signingTime) {
|
|
||||||
xmlNodePtr cur;
|
|
||||||
xmlNodePtr node;
|
|
||||||
xmlNodePtr signedPropertiesNode;
|
|
||||||
|
|
||||||
xmlXadesAssert2(parentNode != NULL, NULL);
|
|
||||||
|
|
||||||
signedPropertiesNode = xmlSecFindChild(parentNode, xmlXadesNodeSignedProperties, xmlXadesDSigNs);
|
|
||||||
if (signedPropertiesNode == NULL) {
|
|
||||||
xmlXadesNodeNotFoundError("xmlSecFindChild", parentNode,
|
|
||||||
xmlXadesNodeSignedProperties, NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add SignedSignatureProperties
|
|
||||||
node = xmlSecAddChild(signedPropertiesNode, xmlXadesNodeSignedSignatureProperties, xmlXadesDSigNs);
|
|
||||||
if (node == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedSignatureProperties)", NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id != NULL) {
|
|
||||||
xmlSetProp(node, BAD_CAST "id", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add SignigTime
|
|
||||||
cur = xmlSecAddChild(node, xmlXadesNodeSigningTime, xmlXadesDSigNs);
|
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigningTime)", NULL);
|
return(-1);
|
||||||
xmlFreeNode(node);
|
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
signedSignaturePropertiesNode = xmlXadesTmplAddSignedSignatureProperties(cur, now);
|
||||||
int ret;
|
if (signedSignaturePropertiesNode == NULL) {
|
||||||
char strtime[200];
|
return(-1);
|
||||||
|
|
||||||
if (strftime(strtime, sizeof(strtime), "%Y-%m-%dT%T", signingTime) == 0) {
|
|
||||||
xmlXadesInternalError("strftime", NULL);
|
|
||||||
xmlFreeNode(cur);
|
|
||||||
xmlFreeNode(node);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = xmlSecNodeEncodeAndSetContent(cur, BAD_CAST strtime);
|
|
||||||
if (ret < 0) {
|
|
||||||
xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
|
|
||||||
xmlFreeNode(cur);
|
|
||||||
xmlFreeNode(node);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addSigningCertificate
|
// addSigningCertificate
|
||||||
cur = xmlSecAddChild(node, xmlXadesNodeSigningCertificate, xmlXadesDSigNs);
|
|
||||||
|
// addSignaturePolicyIdentifier
|
||||||
|
|
||||||
|
signaturePolicyIdNode = xmlXadesAddChildRecursiveNs(signedSignaturePropertiesNode, BAD_CAST "SignaturePolicyIdentifier/SignaturePolicyId", xmlXadesDSigNs)
|
||||||
|
if (signaturePolicyIdNode == NULL) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
cur = xmlXadesTmplAddSigPolicyId(signaturePolicyIdNode, identifier, description, hashMethodId);
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigningCertificate)", NULL);
|
return(-1);
|
||||||
xmlFreeNode(node);
|
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
|
// SignaturePolicyIdentifier/SignaturePolicyId/SigPolicyHash
|
||||||
return(node);
|
cur = xmlXadesTmplAddSigPolicyHash(signaturePolicyIdNode);
|
||||||
}
|
|
||||||
|
|
||||||
xmlNodePtr
|
|
||||||
xmlXadesTmplAddSigningCertificate(xmlNodePtr signedSignaturePropertiesNode) {
|
|
||||||
xmlNodePtr node;
|
|
||||||
|
|
||||||
xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL);
|
|
||||||
if (xmlSecFindChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs) != NULL) {
|
|
||||||
xmlXadesNodeAlreadyPresentError(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs);
|
|
||||||
if (node == NULL) {
|
|
||||||
xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSigningCertificate)", NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlNodePtr
|
|
||||||
xmlXadesTmplAddCert(xmlNodePtr parentNode) {
|
|
||||||
xmlNodePtr node;
|
|
||||||
|
|
||||||
xmlXadesAssert2(parentNode != NULL, NULL);
|
|
||||||
if (xmlSecFindChild(parentNode, xmlXadesNodeCertificate, xmlXadesDSigNs) != NULL) {
|
|
||||||
xmlXadesNodeAlreadyPresentError(parentNode, xmlXadesNodeCertificate, NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = xmlSecAddChild(parentNode, xmlXadesNodeCertificate, xmlXadesDSigNs);
|
|
||||||
if (node == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeCertificate)", NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlNodePtr
|
|
||||||
xmlXadesTmplAddSignaturePolicyIdentifierSignaturePolicyId(xmlNodePtr signedSignaturePropertiesNode) {
|
|
||||||
xmlNodePtr cur;
|
|
||||||
|
|
||||||
xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL);
|
|
||||||
if (xmlSecFindChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs) != NULL) {
|
|
||||||
xmlXadesNodeAlreadyPresentError(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignaturePolicyIdentifier, xmlXadesDSigNs);
|
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSignaturePolicyIdentifier)", NULL);
|
return(-1);
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
|
cur = xmlXadesTmplAddDigest(cur, hashMethodId);
|
||||||
cur = xmlSecAddChild(cur, xmlXadesNodeSignaturePolicyId, xmlXadesDSigNs);
|
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSignaturePolicyId)", NULL);
|
return(-1);
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(cur);
|
// addSignerRole
|
||||||
}
|
xmlXadesTmplAddSignerRole(signedSignaturePropertiesNode, BAD_CAST "supplier");
|
||||||
|
|
||||||
xmlNodePtr
|
cur = xmlSecTmplSignatureAddReference(xmlDocGetRootElement(doc),
|
||||||
xmlXadesTmplAddSigPolicyId(xmlNodePtr signaturePolicyId, const xmlChar* identifier, const xmlChar *description, xmlSecTransformId policyDigestMethodId) {
|
hashMethodId,
|
||||||
xmlNodePtr sigPolicyIdNode;
|
signedPropertiesId,
|
||||||
xmlNodePtr sigPolicyHashNode;
|
NULL, NULL);
|
||||||
xmlNodePtr node;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
sigPolicyIdNode = xmlSecAddChild(signaturePolicyId, xmlXadesNodeSigPolicyId, xmlXadesDSigNs);
|
|
||||||
if (sigPolicyIdNode == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyId)", NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeIdentifier, xmlXadesDSigNs);
|
|
||||||
if (node == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeIdentifier)", NULL);
|
|
||||||
xmlFreeNode(sigPolicyIdNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = xmlSecNodeEncodeAndSetContent(node, identifier);
|
|
||||||
if (ret < 0) {
|
|
||||||
xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
|
|
||||||
xmlFreeNode(sigPolicyIdNode);
|
|
||||||
xmlFreeNode(node);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeDescription, xmlXadesDSigNs);
|
|
||||||
if (node == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeDescription)", NULL);
|
|
||||||
xmlFreeNode(sigPolicyIdNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = xmlSecNodeEncodeAndSetContent(node, identifier);
|
|
||||||
if (ret < 0) {
|
|
||||||
xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
|
|
||||||
xmlFreeNode(sigPolicyIdNode);
|
|
||||||
xmlFreeNode(node);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//add policyHash
|
|
||||||
sigPolicyHashNode = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeSigPolicyHash, xmlXadesDSigNs);
|
|
||||||
if (sigPolicyHashNode == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyHash)", NULL);
|
|
||||||
xmlFreeNode(sigPolicyIdNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = xmlSecAddChild(sigPolicyHashNode, xmlSecNodeDigestMethod, xmlXadesDSigNs);
|
|
||||||
if (sigPolicyHashNode == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestMethod)", NULL);
|
|
||||||
xmlUnlinkNode(sigPolicyHashNode);
|
|
||||||
xmlFreeNode(sigPolicyHashNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
if (xmlSetProp(node, xmlSecAttrAlgorithm, policyDigestMethodId->href) == NULL) {
|
|
||||||
xmlXadesXmlError2("xmlSetProp", NULL,
|
|
||||||
"name=%s", xmlXadesErrorsSafeString(xmlSecAttrAlgorithm));
|
|
||||||
xmlUnlinkNode(sigPolicyHashNode);
|
|
||||||
xmlFreeNode(sigPolicyHashNode);
|
|
||||||
return(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = xmlSecAddChild(sigPolicyHashNode, xmlSecNodeDigestValue, xmlXadesDSigNs);
|
|
||||||
if (node == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL);
|
|
||||||
xmlUnlinkNode(sigPolicyHashNode);
|
|
||||||
xmlFreeNode(sigPolicyHashNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(sigPolicyIdNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role) {
|
|
||||||
xmlNodePtr signerRoleNode;
|
|
||||||
xmlNodePtr claimedRolesNode;
|
|
||||||
xmlNodePtr claimedRoleNode;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
signerRoleNode = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignerRole, xmlXadesDSigNs);
|
|
||||||
if (signerRoleNode == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignerRole)", NULL);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
claimedRolesNode = xmlSecAddChild(signerRoleNode, xmlXadesNodeClaimedRoles, xmlXadesDSigNs);
|
|
||||||
if (claimedRolesNode == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRoles)", NULL);
|
|
||||||
xmlUnlinkNode(signerRoleNode);
|
|
||||||
xmlFreeNode(signerRoleNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
claimedRoleNode = xmlSecAddChild(claimedRolesNode, xmlXadesNodeClaimedRole, xmlXadesDSigNs);
|
|
||||||
if (claimedRoleNode == NULL) {
|
|
||||||
xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRole)", NULL);
|
|
||||||
xmlUnlinkNode(signerRoleNode);
|
|
||||||
xmlFreeNode(signerRoleNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = xmlSecNodeEncodeAndSetContent(claimedRoleNode, role);
|
|
||||||
if (ret < 0) {
|
|
||||||
xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
|
|
||||||
xmlUnlinkNode(signerRoleNode);
|
|
||||||
xmlFreeNode(signerRoleNode);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,14 @@ xmlNodePtr
|
|||||||
xmlXadesTmplQualifyingPropertiesCreateNsPref(xmlDocPtr doc, const xmlChar* id, const xmlChar* nsPrefix);
|
xmlXadesTmplQualifyingPropertiesCreateNsPref(xmlDocPtr doc, const xmlChar* id, const xmlChar* nsPrefix);
|
||||||
|
|
||||||
|
|
||||||
xmlNodePtr
|
|
||||||
xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr parentNode, const xmlChar* id, struct tm* signingTime);
|
|
||||||
|
|
||||||
xmlNodePtr
|
xmlNodePtr
|
||||||
xmlXadesTmplAddSigningCertificate(xmlNodePtr parentNode);
|
xmlXadesTmplAddSigningCertificate(xmlNodePtr parentNode);
|
||||||
xmlNodePtr
|
xmlNodePtr
|
||||||
xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode);
|
xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode);
|
||||||
xmlNodePtr
|
xmlNodePtr
|
||||||
xmlXadesTmplAddSignaturePolicyIdentifierSignaturePolicyId(xmlNodePtr signedSignaturePropertiesNode);
|
xmlXadesTmplAddSignaturePolicyIdentifierSignaturePolicyId(xmlNodePtr signedSignaturePropertiesNode);
|
||||||
|
xmlNodePtr
|
||||||
|
xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr parentNode, struct tm* signingTime);
|
||||||
|
xmlNodePtr
|
||||||
|
xmlXadesAddChildRecursiveNs(xmlNodePtr parentNode, const xmlChar* path, const xmlChar* nsPrefix);
|
||||||
#endif //XADES_H
|
#endif //XADES_H
|
||||||
|
@ -6,7 +6,31 @@
|
|||||||
#include "xades.h"
|
#include "xades.h"
|
||||||
|
|
||||||
|
|
||||||
|
MU_TEST(test_xml_add_node_recursive) {
|
||||||
|
xmlDocPtr doc;
|
||||||
|
xmlNodePtr root;
|
||||||
|
xmlNodePtr child;
|
||||||
|
xmlChar* xmlbuff;
|
||||||
|
int xmlbuffsize;
|
||||||
|
|
||||||
|
doc = xmlNewDoc(BAD_CAST "1.0");
|
||||||
|
root = xmlNewNode(NULL, BAD_CAST "root");
|
||||||
|
xmlDocSetRootElement(doc, root);
|
||||||
|
|
||||||
|
child = xmlXadesAddChildRecursiveNs(root, BAD_CAST "A/B/C", NULL);
|
||||||
|
mu_check(child != NULL);
|
||||||
|
|
||||||
|
xmlDocDumpMemory(doc, &xmlbuff, &xmlbuffsize);
|
||||||
|
mu_assert_string_eq("<?xml version=\"1.0\"?>\n"
|
||||||
|
"<root>\n"
|
||||||
|
"<A>\n"
|
||||||
|
"<B>\n"
|
||||||
|
"<C/>\n"
|
||||||
|
"</B>\n"
|
||||||
|
"</A>\n"
|
||||||
|
"</root>\n"
|
||||||
|
, (char *)xmlbuff);
|
||||||
|
}
|
||||||
|
|
||||||
MU_TEST(test_qualifying_properties_layout) {
|
MU_TEST(test_qualifying_properties_layout) {
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
@ -30,7 +54,7 @@ MU_TEST(test_qualifying_properties_layout) {
|
|||||||
xmlDocSetRootElement(doc, root);
|
xmlDocSetRootElement(doc, root);
|
||||||
|
|
||||||
node = xmlXadesTmplQualifyingPropertiesCreateNsPref(doc, BAD_CAST "123", NULL);
|
node = xmlXadesTmplQualifyingPropertiesCreateNsPref(doc, BAD_CAST "123", NULL);
|
||||||
xmlXadesTmplAddSignedSignatureProperties(node, NULL, &tm);
|
xmlXadesTmplAddSignedSignatureProperties(node, &tm);
|
||||||
mu_check(node != NULL);
|
mu_check(node != NULL);
|
||||||
|
|
||||||
xmlSecAddChildNode(root, node);
|
xmlSecAddChildNode(root, node);
|
||||||
@ -53,12 +77,8 @@ MU_TEST(test_qualifying_properties_layout) {
|
|||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(test_check) {
|
|
||||||
mu_check(5 == 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
MU_TEST_SUITE(test_suite) {
|
MU_TEST_SUITE(test_suite) {
|
||||||
MU_RUN_TEST(test_check);
|
MU_RUN_TEST(test_xml_add_node_recursive);
|
||||||
MU_RUN_TEST(test_qualifying_properties_layout);
|
MU_RUN_TEST(test_qualifying_properties_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
93
facho/fe/nomina/devengado/horas_extras.py
Normal file
93
facho/fe/nomina/devengado/horas_extras.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from ..amount import Amount
|
||||||
|
from .devengado import Devengado
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHoraExtra:
|
||||||
|
hora_inicio: str
|
||||||
|
hora_fin: str
|
||||||
|
cantidad: int
|
||||||
|
porcentaje: Amount
|
||||||
|
pago: Amount
|
||||||
|
|
||||||
|
def apply(self, child_path, fragment):
|
||||||
|
fragment.set_element(child_path, None,
|
||||||
|
append_=True,
|
||||||
|
# NIE074
|
||||||
|
HoraInicio=self.hora_inicio,
|
||||||
|
# NIE075
|
||||||
|
HoraFin=self.hora_fin,
|
||||||
|
# NIE076
|
||||||
|
Cantidad=self.cantidad,
|
||||||
|
# NIE077
|
||||||
|
Porcentaje=self.porcentaje,
|
||||||
|
# NIE078
|
||||||
|
Pago=str(round(self.pago, 2)))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHorasExtrasDiarias(Devengado):
|
||||||
|
horas_extras: List[DevengadoHoraExtra]
|
||||||
|
|
||||||
|
def apply(self, fragment):
|
||||||
|
hora_extra_xml = fragment.fragment('./HEDs')
|
||||||
|
for hora_extra in self.horas_extras:
|
||||||
|
hora_extra.apply('./HED', hora_extra_xml)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHorasExtrasNocturnas(Devengado):
|
||||||
|
horas_extras: List[DevengadoHoraExtra]
|
||||||
|
|
||||||
|
def apply(self, fragment):
|
||||||
|
hora_extra_xml = fragment.fragment('./HENs')
|
||||||
|
for hora_extra in self.horas_extras:
|
||||||
|
hora_extra.apply('./HEN', hora_extra_xml)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHorasRecargoNocturno(Devengado):
|
||||||
|
horas_extras: List[DevengadoHoraExtra]
|
||||||
|
|
||||||
|
def apply(self, fragment):
|
||||||
|
hora_extra_xml = fragment.fragment('./HRNs')
|
||||||
|
for hora_extra in self.horas_extras:
|
||||||
|
hora_extra.apply('./HRN', hora_extra_xml)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHorasExtrasDiariasDominicalesYFestivos(Devengado):
|
||||||
|
horas_extras: List[DevengadoHoraExtra]
|
||||||
|
|
||||||
|
def apply(self, fragment):
|
||||||
|
hora_extra_xml = fragment.fragment('./HEDDFs')
|
||||||
|
for hora_extra in self.horas_extras:
|
||||||
|
hora_extra.apply('./HEDDF', hora_extra_xml)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHorasRecargoDiariasDominicalesYFestivos(Devengado):
|
||||||
|
horas_extras: List[DevengadoHoraExtra]
|
||||||
|
|
||||||
|
def apply(self, fragment):
|
||||||
|
hora_extra_xml = fragment.fragment('./HRDDFs')
|
||||||
|
for hora_extra in self.horas_extras:
|
||||||
|
hora_extra.apply('./HRDDF', hora_extra_xml)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHorasExtrasNocturnasDominicalesYFestivos(Devengado):
|
||||||
|
horas_extras: List[DevengadoHoraExtra]
|
||||||
|
|
||||||
|
def apply(self, fragment):
|
||||||
|
hora_extra_xml = fragment.fragment('./HENDFs')
|
||||||
|
for hora_extra in self.horas_extras:
|
||||||
|
hora_extra.apply('./HENDF', hora_extra_xml)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DevengadoHorasRecargoNocturnoDominicalesYFestivos(Devengado):
|
||||||
|
horas_extras: List[DevengadoHoraExtra]
|
||||||
|
|
||||||
|
def apply(self, fragment):
|
||||||
|
hora_extra_xml = fragment.fragment('./HRNDFs')
|
||||||
|
for hora_extra in self.horas_extras:
|
||||||
|
hora_extra.apply('./HRNDF', hora_extra_xml)
|
155
facho/fe/nomina/hablitacion.py
Normal file
155
facho/fe/nomina/hablitacion.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from facho import fe
|
||||||
|
|
||||||
|
class Habilitacion:
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Metadata:
|
||||||
|
software_pin: str
|
||||||
|
software_id: str
|
||||||
|
nit: str
|
||||||
|
dv: str
|
||||||
|
|
||||||
|
def __init__(self, metadata):
|
||||||
|
self.metadata = metadata
|
||||||
|
|
||||||
|
def generar(self, zipname, fecha):
|
||||||
|
nominas = []
|
||||||
|
dianzip = fe.DianZIP(open(zipname, 'w'))
|
||||||
|
|
||||||
|
fechabase = datetime.datetime.now()
|
||||||
|
consecutivo = 0
|
||||||
|
for _ in range(1, 11):
|
||||||
|
consecutivo += 1
|
||||||
|
fechabase += datetime.timedelta(days=1)
|
||||||
|
nomina = self._crear_nomina_individual()
|
||||||
|
|
||||||
|
# pag 96
|
||||||
|
nombre = "nie%010d%s%08x.xml" % (int(self.nit), fecha.strftime('%s'), consecutivo)
|
||||||
|
|
||||||
|
def _crear_nomina_individual_reemplazar(self, nomina, fechabase):
|
||||||
|
metadata = self.metadata
|
||||||
|
|
||||||
|
fecha = fechabase.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
nomina_ajuste = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar()
|
||||||
|
self._poblar_nomina(nomina_ajuste, metadata, fecha, prefijo='R')
|
||||||
|
informacion_general = nomina.informacion_general()
|
||||||
|
|
||||||
|
|
||||||
|
def _poblar_nomina(self, nomina, metadata, fecha, prefijo='N', consecutivo='0001'):
|
||||||
|
nomina.asignar_fecha_pago(fecha)
|
||||||
|
|
||||||
|
nomina.asignar_metadata(fe.nomina.Metadata(
|
||||||
|
secuencia=fe.nomina.NumeroSecuencia(
|
||||||
|
prefijo=prefijo,
|
||||||
|
consecutivo=consecutivo
|
||||||
|
),
|
||||||
|
lugar_generacion=fe.nomina.Lugar(
|
||||||
|
pais = fe.nomina.Pais(
|
||||||
|
code = 'CO'
|
||||||
|
),
|
||||||
|
departamento = fe.nomina.Departamento(
|
||||||
|
code = '05'
|
||||||
|
),
|
||||||
|
municipio = fe.nomina.Municipio(
|
||||||
|
code = '05001'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
proveedor=fe.nomina.Proveedor(
|
||||||
|
nit=metadata.nit,
|
||||||
|
dv=metadata.dv,
|
||||||
|
software_id=metadata.software_id,
|
||||||
|
software_pin=metadata.software_pin
|
||||||
|
)
|
||||||
|
))
|
||||||
|
|
||||||
|
nomina.asignar_periodo(fe.nomina.Periodo(
|
||||||
|
fecha_ingreso=fecha,
|
||||||
|
fecha_liquidacion_inicio=fecha,
|
||||||
|
fecha_liquidacion_fin=fecha,
|
||||||
|
fecha_generacion=fecha,
|
||||||
|
))
|
||||||
|
|
||||||
|
nomina.asignar_informacion_general(fe.nomina.InformacionGeneral(
|
||||||
|
fecha_generacion = fecha,
|
||||||
|
hora_generacion = '20:09:00-05:00',
|
||||||
|
tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRUEBAS,
|
||||||
|
software_pin = metadata.software_pin,
|
||||||
|
periodo_nomina = fe.nomina.PeriodoNomina(code='1'),
|
||||||
|
tipo_moneda = fe.nomina.TipoMoneda(code='COP')
|
||||||
|
))
|
||||||
|
|
||||||
|
nomina.asignar_pago(fe.nomina.Pago(
|
||||||
|
forma=fe.nomina.FormaPago(
|
||||||
|
code='1',
|
||||||
|
),
|
||||||
|
metodo=fe.nomina.MetodoPago(
|
||||||
|
code='10'
|
||||||
|
)
|
||||||
|
))
|
||||||
|
nomina.asignar_empleador(fe.nomina.Empleador(
|
||||||
|
nit = metadata.nit,
|
||||||
|
dv = '0',
|
||||||
|
pais = fe.nomina.Pais(
|
||||||
|
code = 'CO'
|
||||||
|
),
|
||||||
|
departamento = fe.nomina.Departamento(
|
||||||
|
code = '05'
|
||||||
|
),
|
||||||
|
municipio = fe.nomina.Municipio(
|
||||||
|
code = '05001'
|
||||||
|
),
|
||||||
|
direccion = 'calle etrivial'
|
||||||
|
))
|
||||||
|
|
||||||
|
nomina.asignar_trabajador(fe.nomina.Trabajador(
|
||||||
|
tipo_contrato = fe.nomina.TipoContrato(
|
||||||
|
code = '1'
|
||||||
|
),
|
||||||
|
alto_riesgo = False,
|
||||||
|
tipo_documento = fe.nomina.TipoDocumento(
|
||||||
|
code = '11'
|
||||||
|
),
|
||||||
|
primer_apellido = 'gnu',
|
||||||
|
segundo_apellido = 'emacs',
|
||||||
|
primer_nombre = 'facho',
|
||||||
|
lugar_trabajo = fe.nomina.LugarTrabajo(
|
||||||
|
pais = fe.nomina.Pais(code='CO'),
|
||||||
|
departamento = fe.nomina.Departamento(code='05'),
|
||||||
|
municipio = fe.nomina.Municipio(code='05001'),
|
||||||
|
direccion = 'calle facho'
|
||||||
|
),
|
||||||
|
numero_documento = metadata.nit,
|
||||||
|
tipo = fe.nomina.TipoTrabajador(
|
||||||
|
code = '01'
|
||||||
|
),
|
||||||
|
salario_integral = True,
|
||||||
|
sueldo = fe.nomina.Amount(1_500_000)
|
||||||
|
))
|
||||||
|
|
||||||
|
nomina.adicionar_devengado(fe.nomina.DevengadoBasico(
|
||||||
|
dias_trabajados = 60,
|
||||||
|
sueldo_trabajado = fe.nomina.Amount(3_500_000)
|
||||||
|
))
|
||||||
|
|
||||||
|
nomina.adicionar_deduccion(fe.nomina.DeduccionSalud(
|
||||||
|
porcentaje = fe.nomina.Amount(19),
|
||||||
|
deduccion = fe.nomina.Amount(1_000_000)
|
||||||
|
))
|
||||||
|
|
||||||
|
nomina.adicionar_deduccion(fe.nomina.DeduccionFondoPension(
|
||||||
|
porcentaje=fe.nomina.Amount(1),
|
||||||
|
deduccion=fe.nomina.Amount(10)
|
||||||
|
))
|
||||||
|
|
||||||
|
def _crear_nomina_individual(self, fechabase):
|
||||||
|
metadata = self.metadata
|
||||||
|
|
||||||
|
fecha = fechabase.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
nomina = fe.nomina.DIANNominaIndividual()
|
||||||
|
self._poblar_nomina(nomina, metadata, fecha)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user