From ffd2ba5ebba7c22caa7c3f4fdf32cbbd4e3d882f Mon Sep 17 00:00:00 2001 From: Ren RenJuan Date: Tue, 31 Dec 2013 19:36:07 +0000 Subject: [PATCH] zeroth toolkit state --- AusRegEPPTK/Makefile | 120 ++ AusRegEPPTK/README.txt | 146 ++ AusRegEPPTK/RELEASE_NOTES.txt | 20 + AusRegEPPTK/common/AutoMutex.hpp | 29 + AusRegEPPTK/common/ConfigurationError.hpp | 17 + AusRegEPPTK/common/Constants.cpp | 7 + AusRegEPPTK/common/Constants.hpp | 13 + AusRegEPPTK/common/Deprecated.hpp | 22 + AusRegEPPTK/common/EPPException.hpp | 54 + AusRegEPPTK/common/EPPExceptionTest.cpp | 14 + AusRegEPPTK/common/ErrorPkg.cpp | 104 ++ AusRegEPPTK/common/ErrorPkg.hpp | 32 + AusRegEPPTK/common/IllegalStateException.hpp | 15 + AusRegEPPTK/common/Logger.cpp | 237 ++++ AusRegEPPTK/common/Logger.hpp | 92 ++ .../common/ParameterSyntaxException.hpp | 14 + AusRegEPPTK/common/Properties.cpp | 212 +++ AusRegEPPTK/common/Properties.hpp | 110 ++ AusRegEPPTK/common/StringUtils.cpp | 73 + AusRegEPPTK/common/StringUtils.hpp | 25 + AusRegEPPTK/common/SystemProperties.cpp | 36 + AusRegEPPTK/common/SystemProperties.hpp | 44 + AusRegEPPTK/common/Test.hpp | 65 + AusRegEPPTK/common/init.cpp | 86 ++ AusRegEPPTK/common/init.hpp | 8 + AusRegEPPTK/config/Makefile | 28 + AusRegEPPTK/config/boolean.c | 10 + AusRegEPPTK/config/boolean.h | 13 + AusRegEPPTK/config/config.c | 512 +++++++ AusRegEPPTK/config/config.h | 61 + AusRegEPPTK/config/log.c | 84 ++ AusRegEPPTK/config/log.h | 27 + AusRegEPPTK/config/mem_debug.h | 4 + AusRegEPPTK/etc/Doxyfile | 1252 +++++++++++++++++ AusRegEPPTK/etc/logging.conf | 17 + AusRegEPPTK/etc/site.properties | 17 + AusRegEPPTK/etc/toolkit2.conf | 107 ++ AusRegEPPTK/resources/aedomain-1.0.xsd | 84 ++ AusRegEPPTK/resources/aeext-1.0.xsd | 196 +++ AusRegEPPTK/resources/ardomain-1.0.xsd | 79 ++ AusRegEPPTK/resources/arext-1.0.xsd | 28 + AusRegEPPTK/resources/audomain-1.0.xsd | 72 + AusRegEPPTK/resources/auext-1.0.xsd | 176 +++ AusRegEPPTK/resources/auext-1.1.xsd | 201 +++ AusRegEPPTK/resources/contact-1.0.xsd | 388 +++++ AusRegEPPTK/resources/domain-1.0.xsd | 432 ++++++ AusRegEPPTK/resources/e164epp-1.0.xsd | 111 ++ AusRegEPPTK/resources/epp-1.0.xsd | 441 ++++++ AusRegEPPTK/resources/eppcom-1.0.xsd | 103 ++ AusRegEPPTK/resources/host-1.0.xsd | 241 ++++ AusRegEPPTK/resources/idnadomain-1.0.xsd | 174 +++ AusRegEPPTK/resources/idnahost-1.0.xsd | 55 + AusRegEPPTK/resources/kv-1.0.xsd | 54 + AusRegEPPTK/resources/messages.properties | 91 ++ AusRegEPPTK/resources/registrant-1.0.xsd | 71 + AusRegEPPTK/resources/secDNS-1.1.xsd | 117 ++ AusRegEPPTK/resources/sync-1.0.xsd | 32 + AusRegEPPTK/se/AddRemType.cpp | 31 + AusRegEPPTK/se/AddRemType.hpp | 28 + AusRegEPPTK/se/AeDomainCreateCommand.cpp | 132 ++ AusRegEPPTK/se/AeDomainCreateCommand.hpp | 150 ++ AusRegEPPTK/se/AeDomainCreateCommandTest.cpp | 86 ++ AusRegEPPTK/se/AeDomainInfoResponse.cpp | 57 + AusRegEPPTK/se/AeDomainInfoResponse.hpp | 72 + .../se/AeDomainModifyRegistrantCommand.cpp | 93 ++ .../se/AeDomainModifyRegistrantCommand.hpp | 46 + AusRegEPPTK/se/AeDomainObjectType.cpp | 25 + AusRegEPPTK/se/AeDomainObjectType.hpp | 19 + .../se/AeDomainTransferRegistrantCommand.cpp | 92 ++ .../se/AeDomainTransferRegistrantCommand.hpp | 88 ++ .../se/AeDomainTransferRegistrantResponse.cpp | 37 + .../se/AeDomainTransferRegistrantResponse.hpp | 44 + AusRegEPPTK/se/AeExtension.cpp | 14 + AusRegEPPTK/se/AeExtension.hpp | 29 + AusRegEPPTK/se/Appendable.hpp | 27 + AusRegEPPTK/se/ArDomainObjectType.cpp | 25 + AusRegEPPTK/se/ArDomainObjectType.hpp | 17 + .../se/ArDomainPolicyDeleteCommand.cpp | 35 + .../se/ArDomainPolicyDeleteCommand.hpp | 28 + .../se/ArDomainPolicyDeleteCommandTest.cpp | 29 + .../se/ArDomainPolicyUndeleteCommand.cpp | 31 + .../se/ArDomainPolicyUndeleteCommand.hpp | 22 + .../se/ArDomainPolicyUndeleteCommandTest.cpp | 29 + AusRegEPPTK/se/ArDomainUndeleteCommand.cpp | 32 + AusRegEPPTK/se/ArDomainUndeleteCommand.hpp | 20 + .../se/ArDomainUndeleteCommandTest.cpp | 28 + AusRegEPPTK/se/ArDomainUnrenewCommand.cpp | 37 + AusRegEPPTK/se/ArDomainUnrenewCommand.hpp | 23 + AusRegEPPTK/se/ArDomainUnrenewCommandTest.cpp | 30 + AusRegEPPTK/se/ArDomainUnrenewResponse.cpp | 37 + AusRegEPPTK/se/ArDomainUnrenewResponse.hpp | 33 + .../se/ArDomainUnrenewResponseTest.cpp | 54 + AusRegEPPTK/se/ArExtension.cpp | 14 + AusRegEPPTK/se/ArExtension.hpp | 26 + AusRegEPPTK/se/ArUnrenewCommandType.cpp | 4 + AusRegEPPTK/se/ArUnrenewCommandType.hpp | 19 + AusRegEPPTK/se/AuDomainCreateCommand.cpp | 131 ++ AusRegEPPTK/se/AuDomainCreateCommand.hpp | 147 ++ AusRegEPPTK/se/AuDomainCreateCommandTest.cpp | 84 ++ AusRegEPPTK/se/AuDomainCreateCommandV1.cpp | 124 ++ AusRegEPPTK/se/AuDomainCreateCommandV1.hpp | 85 ++ AusRegEPPTK/se/AuDomainInfoResponse.cpp | 57 + AusRegEPPTK/se/AuDomainInfoResponse.hpp | 72 + AusRegEPPTK/se/AuDomainInfoResponseTest.cpp | 44 + AusRegEPPTK/se/AuDomainInfoResponseV1.cpp | 60 + AusRegEPPTK/se/AuDomainInfoResponseV1.hpp | 68 + AusRegEPPTK/se/AuDomainInfoResponsev1Test.cpp | 42 + .../se/AuDomainModifyRegistrantCommand.cpp | 93 ++ .../se/AuDomainModifyRegistrantCommand.hpp | 46 + .../AuDomainModifyRegistrantCommandTest.cpp | 48 + AusRegEPPTK/se/AuDomainObjectType.cpp | 25 + AusRegEPPTK/se/AuDomainObjectType.hpp | 17 + .../se/AuDomainTransferRegistrantCommand.cpp | 92 ++ .../se/AuDomainTransferRegistrantCommand.hpp | 89 ++ .../AuDomainTransferRegistrantCommandTest.cpp | 71 + .../se/AuDomainTransferRegistrantResponse.cpp | 37 + .../se/AuDomainTransferRegistrantResponse.hpp | 43 + ...AuDomainTransferRegistrantResponseTest.cpp | 38 + AusRegEPPTK/se/AuExtension.cpp | 14 + AusRegEPPTK/se/AuExtension.hpp | 27 + AusRegEPPTK/se/AuExtensionV1.cpp | 13 + AusRegEPPTK/se/AuExtensionV1.hpp | 25 + AusRegEPPTK/se/CLTRID.cpp | 44 + AusRegEPPTK/se/CLTRID.hpp | 37 + AusRegEPPTK/se/CheckCommand.hpp | 46 + AusRegEPPTK/se/CheckResponse.cpp | 118 ++ AusRegEPPTK/se/CheckResponse.hpp | 62 + AusRegEPPTK/se/Command.cpp | 57 + AusRegEPPTK/se/Command.hpp | 47 + AusRegEPPTK/se/CommandExtension.hpp | 23 + AusRegEPPTK/se/CommandType.hpp | 31 + AusRegEPPTK/se/ContactCheckCommand.hpp | 34 + AusRegEPPTK/se/ContactCheckCommandTest.cpp | 40 + AusRegEPPTK/se/ContactCheckResponse.cpp | 61 + AusRegEPPTK/se/ContactCheckResponse.hpp | 50 + AusRegEPPTK/se/ContactCheckResponseTest.cpp | 42 + AusRegEPPTK/se/ContactCreateCommand.cpp | 74 + AusRegEPPTK/se/ContactCreateCommand.hpp | 62 + AusRegEPPTK/se/ContactCreateResponse.cpp | 41 + AusRegEPPTK/se/ContactCreateResponse.hpp | 35 + AusRegEPPTK/se/ContactDeleteCommand.hpp | 24 + AusRegEPPTK/se/ContactDeleteCommandTest.cpp | 28 + AusRegEPPTK/se/ContactInfoCommand.hpp | 38 + AusRegEPPTK/se/ContactInfoCommandTest.cpp | 36 + AusRegEPPTK/se/ContactInfoResponse.cpp | 253 ++++ AusRegEPPTK/se/ContactInfoResponse.hpp | 122 ++ AusRegEPPTK/se/ContactInfoResponseTest.cpp | 37 + .../se/ContactNotificationResponse.cpp | 57 + .../se/ContactNotificationResponse.hpp | 35 + .../se/ContactTransferApproveCommand.hpp | 32 + .../se/ContactTransferCancelCommand.hpp | 32 + AusRegEPPTK/se/ContactTransferCommand.hpp | 27 + .../se/ContactTransferQueryCommand.hpp | 41 + .../se/ContactTransferRejectCommand.hpp | 32 + .../se/ContactTransferRequestCommand.hpp | 34 + .../se/ContactTransferRequestCommandTest.cpp | 31 + AusRegEPPTK/se/ContactTransferResponse.cpp | 55 + AusRegEPPTK/se/ContactTransferResponse.hpp | 51 + AusRegEPPTK/se/ContactUpdateCommand.cpp | 100 ++ AusRegEPPTK/se/ContactUpdateCommand.hpp | 38 + AusRegEPPTK/se/CreateCommand.hpp | 29 + AusRegEPPTK/se/CreateResponse.cpp | 45 + AusRegEPPTK/se/CreateResponse.hpp | 43 + AusRegEPPTK/se/DataResponse.cpp | 31 + AusRegEPPTK/se/DataResponse.hpp | 33 + AusRegEPPTK/se/DeleteCommand.hpp | 32 + AusRegEPPTK/se/Disclose.cpp | 41 + AusRegEPPTK/se/Disclose.hpp | 84 ++ AusRegEPPTK/se/DiscloseItem.hpp | 33 + AusRegEPPTK/se/DomainAdd.hpp | 26 + AusRegEPPTK/se/DomainAddRem.cpp | 98 ++ AusRegEPPTK/se/DomainAddRem.hpp | 46 + AusRegEPPTK/se/DomainCheckCommand.hpp | 37 + AusRegEPPTK/se/DomainCheckCommandTest.cpp | 31 + AusRegEPPTK/se/DomainCheckResponse.cpp | 49 + AusRegEPPTK/se/DomainCheckResponse.hpp | 36 + AusRegEPPTK/se/DomainCheckResponseTest.cpp | 37 + AusRegEPPTK/se/DomainCreateCommand.cpp | 54 + AusRegEPPTK/se/DomainCreateCommand.hpp | 32 + AusRegEPPTK/se/DomainCreateResponse.cpp | 54 + AusRegEPPTK/se/DomainCreateResponse.hpp | 38 + AusRegEPPTK/se/DomainDeleteCommand.hpp | 23 + AusRegEPPTK/se/DomainDeleteCommandTest.cpp | 28 + AusRegEPPTK/se/DomainInfoCommand.hpp | 49 + AusRegEPPTK/se/DomainInfoCommandTest.cpp | 28 + .../se/DomainInfoKVResponseExtension.cpp | 121 ++ .../se/DomainInfoKVResponseExtension.hpp | 79 ++ .../se/DomainInfoKVResponseExtensionTest.cpp | 124 ++ AusRegEPPTK/se/DomainInfoResponse.cpp | 194 +++ AusRegEPPTK/se/DomainInfoResponse.hpp | 79 ++ AusRegEPPTK/se/DomainKVCommandExtension.cpp | 64 + AusRegEPPTK/se/DomainKVCommandExtension.hpp | 58 + .../se/DomainKVCommandExtensionTest.cpp | 91 ++ AusRegEPPTK/se/DomainNotificationResponse.cpp | 57 + AusRegEPPTK/se/DomainNotificationResponse.hpp | 34 + .../se/DomainRegistrantTransferCommand.cpp | 73 + .../se/DomainRegistrantTransferCommand.hpp | 69 + .../DomainRegistrantTransferCommandTest.cpp | 74 + .../se/DomainRegistrantTransferResponse.cpp | 37 + .../se/DomainRegistrantTransferResponse.hpp | 35 + .../DomainRegistrantTransferResponseTest.cpp | 38 + AusRegEPPTK/se/DomainRem.hpp | 26 + AusRegEPPTK/se/DomainRenewCommand.cpp | 37 + AusRegEPPTK/se/DomainRenewCommand.hpp | 30 + AusRegEPPTK/se/DomainRenewResponse.cpp | 40 + AusRegEPPTK/se/DomainRenewResponse.hpp | 34 + .../se/DomainTransferApproveCommand.hpp | 51 + .../se/DomainTransferCancelCommand.hpp | 50 + AusRegEPPTK/se/DomainTransferCommand.hpp | 48 + AusRegEPPTK/se/DomainTransferQueryCommand.hpp | 59 + .../se/DomainTransferQueryCommandTest.cpp | 50 + .../se/DomainTransferRejectCommand.hpp | 49 + .../se/DomainTransferRequestCommand.hpp | 90 ++ AusRegEPPTK/se/DomainTransferResponse.cpp | 68 + AusRegEPPTK/se/DomainTransferResponse.hpp | 54 + AusRegEPPTK/se/DomainUpdateCommand.cpp | 39 + AusRegEPPTK/se/DomainUpdateCommand.hpp | 30 + AusRegEPPTK/se/DomainUpdateCommandTest.cpp | 122 ++ .../se/DomainUpdateSyncCommandExtension.cpp | 21 + .../se/DomainUpdateSyncCommandExtension.hpp | 39 + AusRegEPPTK/se/E164Extension.cpp | 15 + AusRegEPPTK/se/E164Extension.hpp | 26 + AusRegEPPTK/se/EPPDateFormatter.cpp | 25 + AusRegEPPTK/se/EPPDateFormatter.hpp | 16 + AusRegEPPTK/se/EPPDateFormatterTest.cpp | 22 + AusRegEPPTK/se/EnumDomainCreateCommand.cpp | 82 ++ AusRegEPPTK/se/EnumDomainCreateCommand.hpp | 70 + AusRegEPPTK/se/EnumDomainInfoResponse.cpp | 86 ++ AusRegEPPTK/se/EnumDomainInfoResponse.hpp | 32 + AusRegEPPTK/se/EnumDomainInfoResponseTest.cpp | 95 ++ AusRegEPPTK/se/EnumDomainUpdateCommand.cpp | 60 + AusRegEPPTK/se/EnumDomainUpdateCommand.hpp | 49 + AusRegEPPTK/se/EnumType.cpp | 30 + AusRegEPPTK/se/EnumType.hpp | 47 + AusRegEPPTK/se/Error.hpp | 17 + AusRegEPPTK/se/Extension.hpp | 37 + AusRegEPPTK/se/Greeting.cpp | 87 ++ AusRegEPPTK/se/Greeting.hpp | 87 ++ AusRegEPPTK/se/GreetingError.hpp | 10 + AusRegEPPTK/se/Hello.hpp | 25 + AusRegEPPTK/se/HelloTest.cpp | 24 + AusRegEPPTK/se/HostAddRem.cpp | 26 + AusRegEPPTK/se/HostAddRem.hpp | 34 + AusRegEPPTK/se/HostCheckCommand.hpp | 34 + AusRegEPPTK/se/HostCheckCommandTest.cpp | 40 + AusRegEPPTK/se/HostCheckResponse.cpp | 56 + AusRegEPPTK/se/HostCheckResponse.hpp | 32 + AusRegEPPTK/se/HostCreateCommand.cpp | 16 + AusRegEPPTK/se/HostCreateCommand.hpp | 33 + AusRegEPPTK/se/HostCreateCommandTest.cpp | 42 + AusRegEPPTK/se/HostCreateResponse.cpp | 44 + AusRegEPPTK/se/HostCreateResponse.hpp | 32 + AusRegEPPTK/se/HostDeleteCommand.hpp | 26 + AusRegEPPTK/se/HostDeleteCommandTest.cpp | 27 + AusRegEPPTK/se/HostInfoCommand.hpp | 25 + AusRegEPPTK/se/HostInfoCommandTest.cpp | 24 + AusRegEPPTK/se/HostInfoResponse.cpp | 92 ++ AusRegEPPTK/se/HostInfoResponse.hpp | 58 + AusRegEPPTK/se/HostInfoResponseTest.cpp | 66 + AusRegEPPTK/se/HostUpdateCommand.cpp | 30 + AusRegEPPTK/se/HostUpdateCommand.hpp | 28 + AusRegEPPTK/se/IPVersion.cpp | 33 + AusRegEPPTK/se/IPVersion.hpp | 25 + AusRegEPPTK/se/IPVersionTest.cpp | 24 + AusRegEPPTK/se/IllegalArgException.hpp | 15 + AusRegEPPTK/se/InetAddress.cpp | 8 + AusRegEPPTK/se/InetAddress.hpp | 59 + AusRegEPPTK/se/InfoCommand.hpp | 79 ++ AusRegEPPTK/se/InfoResponse.cpp | 135 ++ AusRegEPPTK/se/InfoResponse.hpp | 67 + AusRegEPPTK/se/IntPostalInfo.hpp | 38 + AusRegEPPTK/se/ItemNotFoundException.hpp | 15 + AusRegEPPTK/se/KVDefs.hpp | 14 + AusRegEPPTK/se/KVExtension.cpp | 15 + AusRegEPPTK/se/KVExtension.hpp | 31 + AusRegEPPTK/se/LocalPostalInfo.hpp | 37 + AusRegEPPTK/se/LoginCommand.cpp | 109 ++ AusRegEPPTK/se/LoginCommand.hpp | 53 + AusRegEPPTK/se/LoginCommandTest.cpp | 65 + AusRegEPPTK/se/LogoutCommand.hpp | 23 + AusRegEPPTK/se/LogoutCommandTest.cpp | 29 + AusRegEPPTK/se/NAPTR.cpp | 52 + AusRegEPPTK/se/NAPTR.hpp | 54 + AusRegEPPTK/se/NotificationResponse.cpp | 115 ++ AusRegEPPTK/se/NotificationResponse.hpp | 90 ++ AusRegEPPTK/se/ObjectCommand.cpp | 42 + AusRegEPPTK/se/ObjectCommand.hpp | 48 + AusRegEPPTK/se/ObjectType.hpp | 44 + AusRegEPPTK/se/Period.cpp | 19 + AusRegEPPTK/se/Period.hpp | 42 + AusRegEPPTK/se/PeriodUnit.cpp | 37 + AusRegEPPTK/se/PeriodUnit.hpp | 24 + AusRegEPPTK/se/PollAckCommand.hpp | 31 + AusRegEPPTK/se/PollAckCommandTest.cpp | 24 + AusRegEPPTK/se/PollCommand.hpp | 31 + AusRegEPPTK/se/PollOperation.cpp | 30 + AusRegEPPTK/se/PollOperation.hpp | 25 + AusRegEPPTK/se/PollRequestCommand.hpp | 24 + AusRegEPPTK/se/PollResponse.cpp | 136 ++ AusRegEPPTK/se/PollResponse.hpp | 81 ++ AusRegEPPTK/se/PollResponseTest.cpp | 103 ++ AusRegEPPTK/se/PostalInfo.cpp | 69 + AusRegEPPTK/se/PostalInfo.hpp | 79 ++ AusRegEPPTK/se/PostalInfoType.cpp | 31 + AusRegEPPTK/se/PostalInfoType.hpp | 28 + AusRegEPPTK/se/ProtocolExtensionCommand.cpp | 55 + AusRegEPPTK/se/ProtocolExtensionCommand.hpp | 44 + AusRegEPPTK/se/ReceiveSE.cpp | 24 + AusRegEPPTK/se/ReceiveSE.hpp | 37 + AusRegEPPTK/se/RegistrantObjectType.cpp | 25 + AusRegEPPTK/se/RegistrantObjectType.hpp | 17 + .../se/RegistrantTransferCommandType.cpp | 4 + .../se/RegistrantTransferCommandType.hpp | 19 + AusRegEPPTK/se/Response.cpp | 174 +++ AusRegEPPTK/se/Response.hpp | 80 ++ AusRegEPPTK/se/ResponseError.hpp | 11 + AusRegEPPTK/se/ResponseExtension.cpp | 7 + AusRegEPPTK/se/ResponseExtension.hpp | 36 + AusRegEPPTK/se/Result.cpp | 32 + AusRegEPPTK/se/Result.hpp | 122 ++ AusRegEPPTK/se/ResultCode.hpp | 49 + AusRegEPPTK/se/SendSE.cpp | 53 + AusRegEPPTK/se/SendSE.hpp | 47 + AusRegEPPTK/se/StandardCommandType.cpp | 96 ++ AusRegEPPTK/se/StandardCommandType.hpp | 34 + AusRegEPPTK/se/StandardObjectType.cpp | 69 + AusRegEPPTK/se/StandardObjectType.hpp | 44 + AusRegEPPTK/se/Status.hpp | 43 + AusRegEPPTK/se/SyncExtension.cpp | 16 + AusRegEPPTK/se/SyncExtension.hpp | 31 + AusRegEPPTK/se/TransferCommand.cpp | 88 ++ AusRegEPPTK/se/TransferCommand.hpp | 136 ++ AusRegEPPTK/se/TransferOp.cpp | 53 + AusRegEPPTK/se/TransferOp.hpp | 31 + AusRegEPPTK/se/TransferResponse.cpp | 77 + AusRegEPPTK/se/TransferResponse.hpp | 54 + AusRegEPPTK/se/UpdateCommand.hpp | 32 + AusRegEPPTK/se/XMLGregorianCalendar.cpp | 680 +++++++++ AusRegEPPTK/se/XMLGregorianCalendar.hpp | 148 ++ AusRegEPPTK/se/XMLGregorianCalendarTest.cpp | 135 ++ .../DomainSecDNSCreateCommandExtension.cpp | 24 + .../DomainSecDNSCreateCommandExtension.hpp | 36 + ...DomainSecDNSCreateCommandExtensionTest.cpp | 158 +++ .../DomainSecDNSInfoResponseExtension.cpp | 125 ++ .../DomainSecDNSInfoResponseExtension.hpp | 44 + .../DomainSecDNSInfoResponseExtensionTest.cpp | 249 ++++ .../DomainSecDNSUpdateCommandExtension.cpp | 40 + .../DomainSecDNSUpdateCommandExtension.hpp | 84 ++ ...DomainSecDNSUpdateCommandExtensionTest.cpp | 203 +++ AusRegEPPTK/se/secDNS/SecDNSChgType.cpp | 11 + AusRegEPPTK/se/secDNS/SecDNSChgType.hpp | 32 + AusRegEPPTK/se/secDNS/SecDNSDSData.cpp | 16 + AusRegEPPTK/se/secDNS/SecDNSDSData.hpp | 95 ++ AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.cpp | 75 + AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.hpp | 44 + AusRegEPPTK/se/secDNS/SecDNSExtension.cpp | 13 + AusRegEPPTK/se/secDNS/SecDNSExtension.hpp | 27 + AusRegEPPTK/se/secDNS/SecDNSKeyData.cpp | 11 + AusRegEPPTK/se/secDNS/SecDNSKeyData.hpp | 80 ++ .../se/secDNS/SecDNSMaxSigLifeType.hpp | 30 + AusRegEPPTK/se/secDNS/SecDNSRemType.cpp | 27 + AusRegEPPTK/se/secDNS/SecDNSRemType.hpp | 51 + .../CertificateUserMismatchException.cpp | 33 + .../CertificateUserMismatchException.hpp | 25 + AusRegEPPTK/session/CommandCounter.cpp | 106 ++ AusRegEPPTK/session/CommandCounter.hpp | 65 + AusRegEPPTK/session/CommandCounterTest.cpp | 98 ++ .../session/CommandFailedException.hpp | 16 + .../session/ConfigurationException.hpp | 14 + AusRegEPPTK/session/EPPIOException.hpp | 15 + .../session/EPPInterruptedException.hpp | 15 + .../session/FactoryConfigurationException.hpp | 13 + AusRegEPPTK/session/FatalSessionException.hpp | 16 + AusRegEPPTK/session/GreetingException.hpp | 15 + AusRegEPPTK/session/LoginException.hpp | 14 + AusRegEPPTK/session/LogoutException.hpp | 15 + AusRegEPPTK/session/ResultCounter.cpp | 23 + AusRegEPPTK/session/ResultCounter.hpp | 34 + AusRegEPPTK/session/SSLException.cpp | 38 + AusRegEPPTK/session/SSLException.hpp | 22 + AusRegEPPTK/session/Session.hpp | 217 +++ .../session/SessionConfigurationException.hpp | 15 + AusRegEPPTK/session/SessionFactory.cpp | 11 + AusRegEPPTK/session/SessionFactory.hpp | 26 + .../session/SessionLimitExceededException.hpp | 13 + AusRegEPPTK/session/SessionManager.hpp | 184 +++ AusRegEPPTK/session/SessionManagerFactory.cpp | 22 + AusRegEPPTK/session/SessionManagerFactory.hpp | 86 ++ AusRegEPPTK/session/SessionManagerImpl.cpp | 666 +++++++++ AusRegEPPTK/session/SessionManagerImpl.hpp | 171 +++ .../session/SessionManagerProperties.hpp | 70 + .../session/SessionManagerPropertiesImpl.cpp | 153 ++ .../session/SessionManagerPropertiesImpl.hpp | 63 + AusRegEPPTK/session/SessionManagerTest.cpp | 172 +++ AusRegEPPTK/session/SessionOpenException.hpp | 19 + AusRegEPPTK/session/SessionPool.hpp | 111 ++ AusRegEPPTK/session/SessionPoolImpl.cpp | 392 ++++++ AusRegEPPTK/session/SessionPoolImpl.hpp | 93 ++ AusRegEPPTK/session/SessionPoolProperties.hpp | 35 + AusRegEPPTK/session/SessionProperties.hpp | 139 ++ AusRegEPPTK/session/SessionTest.cpp | 80 ++ AusRegEPPTK/session/StatsManager.hpp | 30 + AusRegEPPTK/session/StatsViewer.hpp | 38 + AusRegEPPTK/session/TLSContext.cpp | 135 ++ AusRegEPPTK/session/TLSContext.hpp | 32 + AusRegEPPTK/session/TLSSession.cpp | 555 ++++++++ AusRegEPPTK/session/TLSSession.hpp | 218 +++ AusRegEPPTK/session/TLSSocket.cpp | 114 ++ AusRegEPPTK/session/TLSSocket.hpp | 36 + AusRegEPPTK/session/TestEnvironment.hpp | 139 ++ AusRegEPPTK/session/Timer.cpp | 74 + AusRegEPPTK/session/Timer.hpp | 42 + AusRegEPPTK/session/TimerTest.cpp | 37 + AusRegEPPTK/session/Transaction.hpp | 70 + .../session/UninitialisedSessionException.hpp | 15 + .../session/UserPassMismatchException.cpp | 16 + .../session/UserPassMismatchException.hpp | 24 + AusRegEPPTK/xml-deps.mk | 22 + AusRegEPPTK/xml/EPPWriter.cpp | 69 + AusRegEPPTK/xml/EPPWriter.hpp | 59 + AusRegEPPTK/xml/NamespaceResolver.cpp | 57 + AusRegEPPTK/xml/NamespaceResolver.hpp | 41 + AusRegEPPTK/xml/ParsingException.hpp | 14 + AusRegEPPTK/xml/Schema.hpp | 8 + AusRegEPPTK/xml/Source.hpp | 8 + AusRegEPPTK/xml/XMLDocument.cpp | 200 +++ AusRegEPPTK/xml/XMLDocument.hpp | 126 ++ AusRegEPPTK/xml/XMLHelper.hpp | 44 + AusRegEPPTK/xml/XMLInit.hpp | 36 + AusRegEPPTK/xml/XMLParser.cpp | 157 +++ AusRegEPPTK/xml/XMLParser.hpp | 53 + AusRegEPPTK/xml/XMLWriter.cpp | 139 ++ AusRegEPPTK/xml/XMLWriter.hpp | 171 +++ AusRegEPPTK/xml/XStr.hpp | 34 + AusRegEPPTK/xml/XalanMemoryManagerImpl.hpp | 60 + 435 files changed, 29422 insertions(+) create mode 100644 AusRegEPPTK/Makefile create mode 100644 AusRegEPPTK/README.txt create mode 100644 AusRegEPPTK/RELEASE_NOTES.txt create mode 100644 AusRegEPPTK/common/AutoMutex.hpp create mode 100644 AusRegEPPTK/common/ConfigurationError.hpp create mode 100644 AusRegEPPTK/common/Constants.cpp create mode 100644 AusRegEPPTK/common/Constants.hpp create mode 100644 AusRegEPPTK/common/Deprecated.hpp create mode 100644 AusRegEPPTK/common/EPPException.hpp create mode 100644 AusRegEPPTK/common/EPPExceptionTest.cpp create mode 100644 AusRegEPPTK/common/ErrorPkg.cpp create mode 100644 AusRegEPPTK/common/ErrorPkg.hpp create mode 100644 AusRegEPPTK/common/IllegalStateException.hpp create mode 100644 AusRegEPPTK/common/Logger.cpp create mode 100644 AusRegEPPTK/common/Logger.hpp create mode 100644 AusRegEPPTK/common/ParameterSyntaxException.hpp create mode 100644 AusRegEPPTK/common/Properties.cpp create mode 100644 AusRegEPPTK/common/Properties.hpp create mode 100644 AusRegEPPTK/common/StringUtils.cpp create mode 100644 AusRegEPPTK/common/StringUtils.hpp create mode 100644 AusRegEPPTK/common/SystemProperties.cpp create mode 100644 AusRegEPPTK/common/SystemProperties.hpp create mode 100644 AusRegEPPTK/common/Test.hpp create mode 100644 AusRegEPPTK/common/init.cpp create mode 100644 AusRegEPPTK/common/init.hpp create mode 100644 AusRegEPPTK/config/Makefile create mode 100644 AusRegEPPTK/config/boolean.c create mode 100644 AusRegEPPTK/config/boolean.h create mode 100644 AusRegEPPTK/config/config.c create mode 100644 AusRegEPPTK/config/config.h create mode 100644 AusRegEPPTK/config/log.c create mode 100644 AusRegEPPTK/config/log.h create mode 100644 AusRegEPPTK/config/mem_debug.h create mode 100644 AusRegEPPTK/etc/Doxyfile create mode 100644 AusRegEPPTK/etc/logging.conf create mode 100644 AusRegEPPTK/etc/site.properties create mode 100644 AusRegEPPTK/etc/toolkit2.conf create mode 100644 AusRegEPPTK/resources/aedomain-1.0.xsd create mode 100644 AusRegEPPTK/resources/aeext-1.0.xsd create mode 100644 AusRegEPPTK/resources/ardomain-1.0.xsd create mode 100644 AusRegEPPTK/resources/arext-1.0.xsd create mode 100644 AusRegEPPTK/resources/audomain-1.0.xsd create mode 100644 AusRegEPPTK/resources/auext-1.0.xsd create mode 100644 AusRegEPPTK/resources/auext-1.1.xsd create mode 100644 AusRegEPPTK/resources/contact-1.0.xsd create mode 100644 AusRegEPPTK/resources/domain-1.0.xsd create mode 100644 AusRegEPPTK/resources/e164epp-1.0.xsd create mode 100644 AusRegEPPTK/resources/epp-1.0.xsd create mode 100644 AusRegEPPTK/resources/eppcom-1.0.xsd create mode 100644 AusRegEPPTK/resources/host-1.0.xsd create mode 100644 AusRegEPPTK/resources/idnadomain-1.0.xsd create mode 100644 AusRegEPPTK/resources/idnahost-1.0.xsd create mode 100644 AusRegEPPTK/resources/kv-1.0.xsd create mode 100644 AusRegEPPTK/resources/messages.properties create mode 100644 AusRegEPPTK/resources/registrant-1.0.xsd create mode 100644 AusRegEPPTK/resources/secDNS-1.1.xsd create mode 100644 AusRegEPPTK/resources/sync-1.0.xsd create mode 100644 AusRegEPPTK/se/AddRemType.cpp create mode 100644 AusRegEPPTK/se/AddRemType.hpp create mode 100644 AusRegEPPTK/se/AeDomainCreateCommand.cpp create mode 100644 AusRegEPPTK/se/AeDomainCreateCommand.hpp create mode 100644 AusRegEPPTK/se/AeDomainCreateCommandTest.cpp create mode 100644 AusRegEPPTK/se/AeDomainInfoResponse.cpp create mode 100644 AusRegEPPTK/se/AeDomainInfoResponse.hpp create mode 100644 AusRegEPPTK/se/AeDomainModifyRegistrantCommand.cpp create mode 100644 AusRegEPPTK/se/AeDomainModifyRegistrantCommand.hpp create mode 100644 AusRegEPPTK/se/AeDomainObjectType.cpp create mode 100644 AusRegEPPTK/se/AeDomainObjectType.hpp create mode 100644 AusRegEPPTK/se/AeDomainTransferRegistrantCommand.cpp create mode 100644 AusRegEPPTK/se/AeDomainTransferRegistrantCommand.hpp create mode 100644 AusRegEPPTK/se/AeDomainTransferRegistrantResponse.cpp create mode 100644 AusRegEPPTK/se/AeDomainTransferRegistrantResponse.hpp create mode 100644 AusRegEPPTK/se/AeExtension.cpp create mode 100644 AusRegEPPTK/se/AeExtension.hpp create mode 100644 AusRegEPPTK/se/Appendable.hpp create mode 100644 AusRegEPPTK/se/ArDomainObjectType.cpp create mode 100644 AusRegEPPTK/se/ArDomainObjectType.hpp create mode 100644 AusRegEPPTK/se/ArDomainPolicyDeleteCommand.cpp create mode 100644 AusRegEPPTK/se/ArDomainPolicyDeleteCommand.hpp create mode 100644 AusRegEPPTK/se/ArDomainPolicyDeleteCommandTest.cpp create mode 100644 AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.cpp create mode 100644 AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.hpp create mode 100644 AusRegEPPTK/se/ArDomainPolicyUndeleteCommandTest.cpp create mode 100644 AusRegEPPTK/se/ArDomainUndeleteCommand.cpp create mode 100644 AusRegEPPTK/se/ArDomainUndeleteCommand.hpp create mode 100644 AusRegEPPTK/se/ArDomainUndeleteCommandTest.cpp create mode 100644 AusRegEPPTK/se/ArDomainUnrenewCommand.cpp create mode 100644 AusRegEPPTK/se/ArDomainUnrenewCommand.hpp create mode 100644 AusRegEPPTK/se/ArDomainUnrenewCommandTest.cpp create mode 100644 AusRegEPPTK/se/ArDomainUnrenewResponse.cpp create mode 100644 AusRegEPPTK/se/ArDomainUnrenewResponse.hpp create mode 100644 AusRegEPPTK/se/ArDomainUnrenewResponseTest.cpp create mode 100644 AusRegEPPTK/se/ArExtension.cpp create mode 100644 AusRegEPPTK/se/ArExtension.hpp create mode 100644 AusRegEPPTK/se/ArUnrenewCommandType.cpp create mode 100644 AusRegEPPTK/se/ArUnrenewCommandType.hpp create mode 100644 AusRegEPPTK/se/AuDomainCreateCommand.cpp create mode 100644 AusRegEPPTK/se/AuDomainCreateCommand.hpp create mode 100644 AusRegEPPTK/se/AuDomainCreateCommandTest.cpp create mode 100644 AusRegEPPTK/se/AuDomainCreateCommandV1.cpp create mode 100644 AusRegEPPTK/se/AuDomainCreateCommandV1.hpp create mode 100644 AusRegEPPTK/se/AuDomainInfoResponse.cpp create mode 100644 AusRegEPPTK/se/AuDomainInfoResponse.hpp create mode 100644 AusRegEPPTK/se/AuDomainInfoResponseTest.cpp create mode 100644 AusRegEPPTK/se/AuDomainInfoResponseV1.cpp create mode 100644 AusRegEPPTK/se/AuDomainInfoResponseV1.hpp create mode 100644 AusRegEPPTK/se/AuDomainInfoResponsev1Test.cpp create mode 100644 AusRegEPPTK/se/AuDomainModifyRegistrantCommand.cpp create mode 100644 AusRegEPPTK/se/AuDomainModifyRegistrantCommand.hpp create mode 100644 AusRegEPPTK/se/AuDomainModifyRegistrantCommandTest.cpp create mode 100644 AusRegEPPTK/se/AuDomainObjectType.cpp create mode 100644 AusRegEPPTK/se/AuDomainObjectType.hpp create mode 100644 AusRegEPPTK/se/AuDomainTransferRegistrantCommand.cpp create mode 100644 AusRegEPPTK/se/AuDomainTransferRegistrantCommand.hpp create mode 100644 AusRegEPPTK/se/AuDomainTransferRegistrantCommandTest.cpp create mode 100644 AusRegEPPTK/se/AuDomainTransferRegistrantResponse.cpp create mode 100644 AusRegEPPTK/se/AuDomainTransferRegistrantResponse.hpp create mode 100644 AusRegEPPTK/se/AuDomainTransferRegistrantResponseTest.cpp create mode 100644 AusRegEPPTK/se/AuExtension.cpp create mode 100644 AusRegEPPTK/se/AuExtension.hpp create mode 100644 AusRegEPPTK/se/AuExtensionV1.cpp create mode 100644 AusRegEPPTK/se/AuExtensionV1.hpp create mode 100644 AusRegEPPTK/se/CLTRID.cpp create mode 100644 AusRegEPPTK/se/CLTRID.hpp create mode 100644 AusRegEPPTK/se/CheckCommand.hpp create mode 100644 AusRegEPPTK/se/CheckResponse.cpp create mode 100644 AusRegEPPTK/se/CheckResponse.hpp create mode 100644 AusRegEPPTK/se/Command.cpp create mode 100644 AusRegEPPTK/se/Command.hpp create mode 100644 AusRegEPPTK/se/CommandExtension.hpp create mode 100644 AusRegEPPTK/se/CommandType.hpp create mode 100644 AusRegEPPTK/se/ContactCheckCommand.hpp create mode 100644 AusRegEPPTK/se/ContactCheckCommandTest.cpp create mode 100644 AusRegEPPTK/se/ContactCheckResponse.cpp create mode 100644 AusRegEPPTK/se/ContactCheckResponse.hpp create mode 100644 AusRegEPPTK/se/ContactCheckResponseTest.cpp create mode 100644 AusRegEPPTK/se/ContactCreateCommand.cpp create mode 100644 AusRegEPPTK/se/ContactCreateCommand.hpp create mode 100644 AusRegEPPTK/se/ContactCreateResponse.cpp create mode 100644 AusRegEPPTK/se/ContactCreateResponse.hpp create mode 100644 AusRegEPPTK/se/ContactDeleteCommand.hpp create mode 100644 AusRegEPPTK/se/ContactDeleteCommandTest.cpp create mode 100644 AusRegEPPTK/se/ContactInfoCommand.hpp create mode 100644 AusRegEPPTK/se/ContactInfoCommandTest.cpp create mode 100644 AusRegEPPTK/se/ContactInfoResponse.cpp create mode 100644 AusRegEPPTK/se/ContactInfoResponse.hpp create mode 100644 AusRegEPPTK/se/ContactInfoResponseTest.cpp create mode 100644 AusRegEPPTK/se/ContactNotificationResponse.cpp create mode 100644 AusRegEPPTK/se/ContactNotificationResponse.hpp create mode 100644 AusRegEPPTK/se/ContactTransferApproveCommand.hpp create mode 100644 AusRegEPPTK/se/ContactTransferCancelCommand.hpp create mode 100644 AusRegEPPTK/se/ContactTransferCommand.hpp create mode 100644 AusRegEPPTK/se/ContactTransferQueryCommand.hpp create mode 100644 AusRegEPPTK/se/ContactTransferRejectCommand.hpp create mode 100644 AusRegEPPTK/se/ContactTransferRequestCommand.hpp create mode 100644 AusRegEPPTK/se/ContactTransferRequestCommandTest.cpp create mode 100644 AusRegEPPTK/se/ContactTransferResponse.cpp create mode 100644 AusRegEPPTK/se/ContactTransferResponse.hpp create mode 100644 AusRegEPPTK/se/ContactUpdateCommand.cpp create mode 100644 AusRegEPPTK/se/ContactUpdateCommand.hpp create mode 100644 AusRegEPPTK/se/CreateCommand.hpp create mode 100644 AusRegEPPTK/se/CreateResponse.cpp create mode 100644 AusRegEPPTK/se/CreateResponse.hpp create mode 100644 AusRegEPPTK/se/DataResponse.cpp create mode 100644 AusRegEPPTK/se/DataResponse.hpp create mode 100644 AusRegEPPTK/se/DeleteCommand.hpp create mode 100644 AusRegEPPTK/se/Disclose.cpp create mode 100644 AusRegEPPTK/se/Disclose.hpp create mode 100644 AusRegEPPTK/se/DiscloseItem.hpp create mode 100644 AusRegEPPTK/se/DomainAdd.hpp create mode 100644 AusRegEPPTK/se/DomainAddRem.cpp create mode 100644 AusRegEPPTK/se/DomainAddRem.hpp create mode 100644 AusRegEPPTK/se/DomainCheckCommand.hpp create mode 100644 AusRegEPPTK/se/DomainCheckCommandTest.cpp create mode 100644 AusRegEPPTK/se/DomainCheckResponse.cpp create mode 100644 AusRegEPPTK/se/DomainCheckResponse.hpp create mode 100644 AusRegEPPTK/se/DomainCheckResponseTest.cpp create mode 100644 AusRegEPPTK/se/DomainCreateCommand.cpp create mode 100644 AusRegEPPTK/se/DomainCreateCommand.hpp create mode 100644 AusRegEPPTK/se/DomainCreateResponse.cpp create mode 100644 AusRegEPPTK/se/DomainCreateResponse.hpp create mode 100644 AusRegEPPTK/se/DomainDeleteCommand.hpp create mode 100644 AusRegEPPTK/se/DomainDeleteCommandTest.cpp create mode 100644 AusRegEPPTK/se/DomainInfoCommand.hpp create mode 100644 AusRegEPPTK/se/DomainInfoCommandTest.cpp create mode 100644 AusRegEPPTK/se/DomainInfoKVResponseExtension.cpp create mode 100644 AusRegEPPTK/se/DomainInfoKVResponseExtension.hpp create mode 100644 AusRegEPPTK/se/DomainInfoKVResponseExtensionTest.cpp create mode 100644 AusRegEPPTK/se/DomainInfoResponse.cpp create mode 100644 AusRegEPPTK/se/DomainInfoResponse.hpp create mode 100644 AusRegEPPTK/se/DomainKVCommandExtension.cpp create mode 100644 AusRegEPPTK/se/DomainKVCommandExtension.hpp create mode 100644 AusRegEPPTK/se/DomainKVCommandExtensionTest.cpp create mode 100644 AusRegEPPTK/se/DomainNotificationResponse.cpp create mode 100644 AusRegEPPTK/se/DomainNotificationResponse.hpp create mode 100644 AusRegEPPTK/se/DomainRegistrantTransferCommand.cpp create mode 100644 AusRegEPPTK/se/DomainRegistrantTransferCommand.hpp create mode 100644 AusRegEPPTK/se/DomainRegistrantTransferCommandTest.cpp create mode 100644 AusRegEPPTK/se/DomainRegistrantTransferResponse.cpp create mode 100644 AusRegEPPTK/se/DomainRegistrantTransferResponse.hpp create mode 100644 AusRegEPPTK/se/DomainRegistrantTransferResponseTest.cpp create mode 100644 AusRegEPPTK/se/DomainRem.hpp create mode 100644 AusRegEPPTK/se/DomainRenewCommand.cpp create mode 100644 AusRegEPPTK/se/DomainRenewCommand.hpp create mode 100644 AusRegEPPTK/se/DomainRenewResponse.cpp create mode 100644 AusRegEPPTK/se/DomainRenewResponse.hpp create mode 100644 AusRegEPPTK/se/DomainTransferApproveCommand.hpp create mode 100644 AusRegEPPTK/se/DomainTransferCancelCommand.hpp create mode 100644 AusRegEPPTK/se/DomainTransferCommand.hpp create mode 100644 AusRegEPPTK/se/DomainTransferQueryCommand.hpp create mode 100644 AusRegEPPTK/se/DomainTransferQueryCommandTest.cpp create mode 100644 AusRegEPPTK/se/DomainTransferRejectCommand.hpp create mode 100644 AusRegEPPTK/se/DomainTransferRequestCommand.hpp create mode 100644 AusRegEPPTK/se/DomainTransferResponse.cpp create mode 100644 AusRegEPPTK/se/DomainTransferResponse.hpp create mode 100644 AusRegEPPTK/se/DomainUpdateCommand.cpp create mode 100644 AusRegEPPTK/se/DomainUpdateCommand.hpp create mode 100644 AusRegEPPTK/se/DomainUpdateCommandTest.cpp create mode 100644 AusRegEPPTK/se/DomainUpdateSyncCommandExtension.cpp create mode 100644 AusRegEPPTK/se/DomainUpdateSyncCommandExtension.hpp create mode 100644 AusRegEPPTK/se/E164Extension.cpp create mode 100644 AusRegEPPTK/se/E164Extension.hpp create mode 100644 AusRegEPPTK/se/EPPDateFormatter.cpp create mode 100644 AusRegEPPTK/se/EPPDateFormatter.hpp create mode 100644 AusRegEPPTK/se/EPPDateFormatterTest.cpp create mode 100644 AusRegEPPTK/se/EnumDomainCreateCommand.cpp create mode 100644 AusRegEPPTK/se/EnumDomainCreateCommand.hpp create mode 100644 AusRegEPPTK/se/EnumDomainInfoResponse.cpp create mode 100644 AusRegEPPTK/se/EnumDomainInfoResponse.hpp create mode 100644 AusRegEPPTK/se/EnumDomainInfoResponseTest.cpp create mode 100644 AusRegEPPTK/se/EnumDomainUpdateCommand.cpp create mode 100644 AusRegEPPTK/se/EnumDomainUpdateCommand.hpp create mode 100644 AusRegEPPTK/se/EnumType.cpp create mode 100644 AusRegEPPTK/se/EnumType.hpp create mode 100644 AusRegEPPTK/se/Error.hpp create mode 100644 AusRegEPPTK/se/Extension.hpp create mode 100644 AusRegEPPTK/se/Greeting.cpp create mode 100644 AusRegEPPTK/se/Greeting.hpp create mode 100644 AusRegEPPTK/se/GreetingError.hpp create mode 100644 AusRegEPPTK/se/Hello.hpp create mode 100644 AusRegEPPTK/se/HelloTest.cpp create mode 100644 AusRegEPPTK/se/HostAddRem.cpp create mode 100644 AusRegEPPTK/se/HostAddRem.hpp create mode 100644 AusRegEPPTK/se/HostCheckCommand.hpp create mode 100644 AusRegEPPTK/se/HostCheckCommandTest.cpp create mode 100644 AusRegEPPTK/se/HostCheckResponse.cpp create mode 100644 AusRegEPPTK/se/HostCheckResponse.hpp create mode 100644 AusRegEPPTK/se/HostCreateCommand.cpp create mode 100644 AusRegEPPTK/se/HostCreateCommand.hpp create mode 100644 AusRegEPPTK/se/HostCreateCommandTest.cpp create mode 100644 AusRegEPPTK/se/HostCreateResponse.cpp create mode 100644 AusRegEPPTK/se/HostCreateResponse.hpp create mode 100644 AusRegEPPTK/se/HostDeleteCommand.hpp create mode 100644 AusRegEPPTK/se/HostDeleteCommandTest.cpp create mode 100644 AusRegEPPTK/se/HostInfoCommand.hpp create mode 100644 AusRegEPPTK/se/HostInfoCommandTest.cpp create mode 100644 AusRegEPPTK/se/HostInfoResponse.cpp create mode 100644 AusRegEPPTK/se/HostInfoResponse.hpp create mode 100644 AusRegEPPTK/se/HostInfoResponseTest.cpp create mode 100644 AusRegEPPTK/se/HostUpdateCommand.cpp create mode 100644 AusRegEPPTK/se/HostUpdateCommand.hpp create mode 100644 AusRegEPPTK/se/IPVersion.cpp create mode 100644 AusRegEPPTK/se/IPVersion.hpp create mode 100644 AusRegEPPTK/se/IPVersionTest.cpp create mode 100644 AusRegEPPTK/se/IllegalArgException.hpp create mode 100644 AusRegEPPTK/se/InetAddress.cpp create mode 100644 AusRegEPPTK/se/InetAddress.hpp create mode 100644 AusRegEPPTK/se/InfoCommand.hpp create mode 100644 AusRegEPPTK/se/InfoResponse.cpp create mode 100644 AusRegEPPTK/se/InfoResponse.hpp create mode 100644 AusRegEPPTK/se/IntPostalInfo.hpp create mode 100644 AusRegEPPTK/se/ItemNotFoundException.hpp create mode 100644 AusRegEPPTK/se/KVDefs.hpp create mode 100644 AusRegEPPTK/se/KVExtension.cpp create mode 100644 AusRegEPPTK/se/KVExtension.hpp create mode 100644 AusRegEPPTK/se/LocalPostalInfo.hpp create mode 100644 AusRegEPPTK/se/LoginCommand.cpp create mode 100644 AusRegEPPTK/se/LoginCommand.hpp create mode 100644 AusRegEPPTK/se/LoginCommandTest.cpp create mode 100644 AusRegEPPTK/se/LogoutCommand.hpp create mode 100644 AusRegEPPTK/se/LogoutCommandTest.cpp create mode 100644 AusRegEPPTK/se/NAPTR.cpp create mode 100644 AusRegEPPTK/se/NAPTR.hpp create mode 100644 AusRegEPPTK/se/NotificationResponse.cpp create mode 100644 AusRegEPPTK/se/NotificationResponse.hpp create mode 100644 AusRegEPPTK/se/ObjectCommand.cpp create mode 100644 AusRegEPPTK/se/ObjectCommand.hpp create mode 100644 AusRegEPPTK/se/ObjectType.hpp create mode 100644 AusRegEPPTK/se/Period.cpp create mode 100644 AusRegEPPTK/se/Period.hpp create mode 100644 AusRegEPPTK/se/PeriodUnit.cpp create mode 100644 AusRegEPPTK/se/PeriodUnit.hpp create mode 100644 AusRegEPPTK/se/PollAckCommand.hpp create mode 100644 AusRegEPPTK/se/PollAckCommandTest.cpp create mode 100644 AusRegEPPTK/se/PollCommand.hpp create mode 100644 AusRegEPPTK/se/PollOperation.cpp create mode 100644 AusRegEPPTK/se/PollOperation.hpp create mode 100644 AusRegEPPTK/se/PollRequestCommand.hpp create mode 100644 AusRegEPPTK/se/PollResponse.cpp create mode 100644 AusRegEPPTK/se/PollResponse.hpp create mode 100644 AusRegEPPTK/se/PollResponseTest.cpp create mode 100644 AusRegEPPTK/se/PostalInfo.cpp create mode 100644 AusRegEPPTK/se/PostalInfo.hpp create mode 100644 AusRegEPPTK/se/PostalInfoType.cpp create mode 100644 AusRegEPPTK/se/PostalInfoType.hpp create mode 100644 AusRegEPPTK/se/ProtocolExtensionCommand.cpp create mode 100644 AusRegEPPTK/se/ProtocolExtensionCommand.hpp create mode 100644 AusRegEPPTK/se/ReceiveSE.cpp create mode 100644 AusRegEPPTK/se/ReceiveSE.hpp create mode 100644 AusRegEPPTK/se/RegistrantObjectType.cpp create mode 100644 AusRegEPPTK/se/RegistrantObjectType.hpp create mode 100644 AusRegEPPTK/se/RegistrantTransferCommandType.cpp create mode 100644 AusRegEPPTK/se/RegistrantTransferCommandType.hpp create mode 100644 AusRegEPPTK/se/Response.cpp create mode 100644 AusRegEPPTK/se/Response.hpp create mode 100644 AusRegEPPTK/se/ResponseError.hpp create mode 100644 AusRegEPPTK/se/ResponseExtension.cpp create mode 100644 AusRegEPPTK/se/ResponseExtension.hpp create mode 100644 AusRegEPPTK/se/Result.cpp create mode 100644 AusRegEPPTK/se/Result.hpp create mode 100644 AusRegEPPTK/se/ResultCode.hpp create mode 100644 AusRegEPPTK/se/SendSE.cpp create mode 100644 AusRegEPPTK/se/SendSE.hpp create mode 100644 AusRegEPPTK/se/StandardCommandType.cpp create mode 100644 AusRegEPPTK/se/StandardCommandType.hpp create mode 100644 AusRegEPPTK/se/StandardObjectType.cpp create mode 100644 AusRegEPPTK/se/StandardObjectType.hpp create mode 100644 AusRegEPPTK/se/Status.hpp create mode 100644 AusRegEPPTK/se/SyncExtension.cpp create mode 100644 AusRegEPPTK/se/SyncExtension.hpp create mode 100644 AusRegEPPTK/se/TransferCommand.cpp create mode 100644 AusRegEPPTK/se/TransferCommand.hpp create mode 100644 AusRegEPPTK/se/TransferOp.cpp create mode 100644 AusRegEPPTK/se/TransferOp.hpp create mode 100644 AusRegEPPTK/se/TransferResponse.cpp create mode 100644 AusRegEPPTK/se/TransferResponse.hpp create mode 100644 AusRegEPPTK/se/UpdateCommand.hpp create mode 100644 AusRegEPPTK/se/XMLGregorianCalendar.cpp create mode 100644 AusRegEPPTK/se/XMLGregorianCalendar.hpp create mode 100644 AusRegEPPTK/se/XMLGregorianCalendarTest.cpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.cpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.hpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtensionTest.cpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.cpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.hpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtensionTest.cpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.cpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.hpp create mode 100644 AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtensionTest.cpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSChgType.cpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSChgType.hpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSDSData.cpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSDSData.hpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.cpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.hpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSExtension.cpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSExtension.hpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSKeyData.cpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSKeyData.hpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSMaxSigLifeType.hpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSRemType.cpp create mode 100644 AusRegEPPTK/se/secDNS/SecDNSRemType.hpp create mode 100644 AusRegEPPTK/session/CertificateUserMismatchException.cpp create mode 100644 AusRegEPPTK/session/CertificateUserMismatchException.hpp create mode 100644 AusRegEPPTK/session/CommandCounter.cpp create mode 100644 AusRegEPPTK/session/CommandCounter.hpp create mode 100644 AusRegEPPTK/session/CommandCounterTest.cpp create mode 100644 AusRegEPPTK/session/CommandFailedException.hpp create mode 100644 AusRegEPPTK/session/ConfigurationException.hpp create mode 100644 AusRegEPPTK/session/EPPIOException.hpp create mode 100644 AusRegEPPTK/session/EPPInterruptedException.hpp create mode 100644 AusRegEPPTK/session/FactoryConfigurationException.hpp create mode 100644 AusRegEPPTK/session/FatalSessionException.hpp create mode 100644 AusRegEPPTK/session/GreetingException.hpp create mode 100644 AusRegEPPTK/session/LoginException.hpp create mode 100644 AusRegEPPTK/session/LogoutException.hpp create mode 100644 AusRegEPPTK/session/ResultCounter.cpp create mode 100644 AusRegEPPTK/session/ResultCounter.hpp create mode 100644 AusRegEPPTK/session/SSLException.cpp create mode 100644 AusRegEPPTK/session/SSLException.hpp create mode 100644 AusRegEPPTK/session/Session.hpp create mode 100644 AusRegEPPTK/session/SessionConfigurationException.hpp create mode 100644 AusRegEPPTK/session/SessionFactory.cpp create mode 100644 AusRegEPPTK/session/SessionFactory.hpp create mode 100644 AusRegEPPTK/session/SessionLimitExceededException.hpp create mode 100644 AusRegEPPTK/session/SessionManager.hpp create mode 100644 AusRegEPPTK/session/SessionManagerFactory.cpp create mode 100644 AusRegEPPTK/session/SessionManagerFactory.hpp create mode 100644 AusRegEPPTK/session/SessionManagerImpl.cpp create mode 100644 AusRegEPPTK/session/SessionManagerImpl.hpp create mode 100644 AusRegEPPTK/session/SessionManagerProperties.hpp create mode 100644 AusRegEPPTK/session/SessionManagerPropertiesImpl.cpp create mode 100644 AusRegEPPTK/session/SessionManagerPropertiesImpl.hpp create mode 100644 AusRegEPPTK/session/SessionManagerTest.cpp create mode 100644 AusRegEPPTK/session/SessionOpenException.hpp create mode 100644 AusRegEPPTK/session/SessionPool.hpp create mode 100644 AusRegEPPTK/session/SessionPoolImpl.cpp create mode 100644 AusRegEPPTK/session/SessionPoolImpl.hpp create mode 100644 AusRegEPPTK/session/SessionPoolProperties.hpp create mode 100644 AusRegEPPTK/session/SessionProperties.hpp create mode 100644 AusRegEPPTK/session/SessionTest.cpp create mode 100644 AusRegEPPTK/session/StatsManager.hpp create mode 100644 AusRegEPPTK/session/StatsViewer.hpp create mode 100644 AusRegEPPTK/session/TLSContext.cpp create mode 100644 AusRegEPPTK/session/TLSContext.hpp create mode 100644 AusRegEPPTK/session/TLSSession.cpp create mode 100644 AusRegEPPTK/session/TLSSession.hpp create mode 100644 AusRegEPPTK/session/TLSSocket.cpp create mode 100644 AusRegEPPTK/session/TLSSocket.hpp create mode 100644 AusRegEPPTK/session/TestEnvironment.hpp create mode 100644 AusRegEPPTK/session/Timer.cpp create mode 100644 AusRegEPPTK/session/Timer.hpp create mode 100644 AusRegEPPTK/session/TimerTest.cpp create mode 100644 AusRegEPPTK/session/Transaction.hpp create mode 100644 AusRegEPPTK/session/UninitialisedSessionException.hpp create mode 100644 AusRegEPPTK/session/UserPassMismatchException.cpp create mode 100644 AusRegEPPTK/session/UserPassMismatchException.hpp create mode 100644 AusRegEPPTK/xml-deps.mk create mode 100644 AusRegEPPTK/xml/EPPWriter.cpp create mode 100644 AusRegEPPTK/xml/EPPWriter.hpp create mode 100644 AusRegEPPTK/xml/NamespaceResolver.cpp create mode 100644 AusRegEPPTK/xml/NamespaceResolver.hpp create mode 100644 AusRegEPPTK/xml/ParsingException.hpp create mode 100644 AusRegEPPTK/xml/Schema.hpp create mode 100644 AusRegEPPTK/xml/Source.hpp create mode 100644 AusRegEPPTK/xml/XMLDocument.cpp create mode 100644 AusRegEPPTK/xml/XMLDocument.hpp create mode 100644 AusRegEPPTK/xml/XMLHelper.hpp create mode 100644 AusRegEPPTK/xml/XMLInit.hpp create mode 100644 AusRegEPPTK/xml/XMLParser.cpp create mode 100644 AusRegEPPTK/xml/XMLParser.hpp create mode 100644 AusRegEPPTK/xml/XMLWriter.cpp create mode 100644 AusRegEPPTK/xml/XMLWriter.hpp create mode 100644 AusRegEPPTK/xml/XStr.hpp create mode 100644 AusRegEPPTK/xml/XalanMemoryManagerImpl.hpp diff --git a/AusRegEPPTK/Makefile b/AusRegEPPTK/Makefile new file mode 100644 index 0000000..e7b5206 --- /dev/null +++ b/AusRegEPPTK/Makefile @@ -0,0 +1,120 @@ +################################################## +# Makefile for building lib and main test routine# +################################################## +# operating system +SYSTEM = $(shell uname -s) + +CXX = g++ +CC = gcc + +#SHARED_CXXFLAGS += -O2 +SHARED_CXXFLAGS += -g + +CXXFLAGS = $(SHARED_CXXFLAGS) -Wall -Wpointer-arith -Wcast-qual -D_REENTRANT -fPIC +CPPFLAGS = -fPIC -D_GNU_SOURCE +CXXFLAGS += -D_GNU_SOURCE -O0 + +#XERCES_HOME = /usr/local/xerces-c-src_2_7_0 +#XERCES_LIB_DIR = ${XERCES_HOME}/lib +#XERCES_LIB = xerces-c2_7_0 + +#XALAN_HOME = /usr/local/xalan-c_1_10_0 +#XALAN_LIB_DIR = $(XALAN_HOME)/lib + +include xml-deps.mk + +##### Set this to the location of the library to be produced + +BUILD_LIB_DIR = lib +BUILD_OBJ_DIR = build + +###### Include Paths + +INCLUDE_DIR = -I . -I $(XERCES_INC_DIR) -I $(XALAN_INC_DIR) + +build_obj_dir = $(BUILD_OBJ_DIR) + +src_dirs_cpp = se se/secDNS common session xml +src_dirs_c = config +srcs_all = $(foreach dir,$(src_dirs_cpp),$(wildcard $(dir)/*.cpp)) +srcs_all += $(foreach dir,$(src_dirs_c),$(wildcard $(dir)/*.c)) + +srcs = $(filter-out %Test.cpp,$(srcs_all)) +objs = $(foreach file,$(srcs),$(build_obj_dir)/$(basename $(notdir $(file))).o) +test_srcs = $(filter %Test.cpp,$(srcs_all)) +test_objs = $(foreach file,$(test_srcs),$(build_obj_dir)/$(basename $(notdir $(file))).o) +test_execs = $(subst .o,,$(test_objs)) + +calc_deps = \ + $(CC) -MT '$(build_obj_dir)/$(basename $(notdir $@)).o $@' -MF $@ -MM $(CPPFLAGS) $(INCLUDE_DIR) $< + +all: dirs $(objs) $(BUILD_LIB_DIR)/libAusreg_EPP_toolkit.so + +%.d: %.c + $(calc_deps) +%.d: %.cpp + $(calc_deps) +include $(foreach name,$(srcs_all),$(basename $(name)).d) + +vpath %.cpp ./ \ + ./se\ + ./se/secDNS\ + ./xml\ + ./common\ + ./session\ + +vpath %.c ./config + +vpath %.o ../build + +####### Implicit rules + +.SUFFIXES: .cpp .c + +$(BUILD_OBJ_DIR)/%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $(INCLUDE_DIR) $< + +$(BUILD_OBJ_DIR)/%.o: %.c + $(CC) $(CPPFLAGS) -c -o $@ $(INCLUDE_DIR) $< + + +LDFLAGS_TESTS = -L$(BUILD_LIB_DIR) -lAusreg_EPP_toolkit \ + -L$(XALAN_LIB_DIR) -lxalan-c -lxalanMsg\ + -L$(XERCES_LIB_DIR) -lxerces-c \ + -lssl \ + -lrt + +$(BUILD_OBJ_DIR)/%: $(BUILD_OBJ_DIR)/%.o + $(CXX) $(LDFLAGS_TESTS) -o $@ $< + +.PHONY: doc clean dclean +####### Build rules + +#libAusreg_EPP_toolkit.a: $(OBJECTS) +# $(LIB_ARCHIVER) $(LIB_FLAGS) $(BUILD_LIB_DIR)/$@ $^ + + +.PHONY: tests +tests: all $(test_execs) + + +.PHONY: dirs +dirs: + -mkdir -p $(BUILD_LIB_DIR) + -mkdir -p $(BUILD_OBJ_DIR) + +$(BUILD_LIB_DIR)/libAusreg_EPP_toolkit.so: $(objs) + $(CXX) $(LDFLAGS) $(SHARED_CXXFLAGS) -shared $^ -o $@ + +doc: + doxygen etc/Doxyfile + +clean: + $(RM) $(objs) $(BUILD_LIB_DIR)/libAusreg_EPP_toolkit.so *~ + $(RM) -r $(BUILD_OBJ_DIR) + $(RM) -r $(BUILD_LIB_DIR) + +dclean: + $(MAKE) clean + $(RM) */*.d + diff --git a/AusRegEPPTK/README.txt b/AusRegEPPTK/README.txt new file mode 100644 index 0000000..1869779 --- /dev/null +++ b/AusRegEPPTK/README.txt @@ -0,0 +1,146 @@ +A. Software Requirements +------------------------ + +1. GNU Make 3.80 or later +2. GCC 3.4.6 (for gcc and g++) +3. Xerces C++ 2.7.0 +4. Xalan C++ 1.0 +5. OpenSSL 0.9.7a or later +6. Doxygen 1.3.9.1 (required to produce API documentation) + +Notes +The software library may build with an earlier GCC release, but has only been +verified on GCC 3.4.6. It was developed on 64-bit Redhat Enterprise Linux ES +4 using 64-bit supporting libraries (Xerces, Xalan, OpenSSL). + + +B. Build Instructions +--------------------- + +1. Set the values of the following environment variables: +XALAN_LIB_DIR +XALAN_LIB +XALAN_INC_DIR +XERCES_LIB_DIR +XERCES_LIB +XERCES_INC_DIR +Examples: +$ XALAN_LIB_DIR=/usr/local/xalan-c/lib +$ XALAN_LIB=xalan-c +$ XALAN_INC_DIR=/usr/local/xalan-c/include +$ XERCES_LIB_DIR=/usr/lib +$ XERCES_LIB=xerces-c +$ XERCES_INC_DIR=/usr/include/xercesc +$ export XALAN_LIB_DIR XALAN_LIB XALAN_INC_DIR XERCES_LIB_DIR XERCES_LIB XERCES_INC_DIR + +2. Verify version of tools. +$ make --version$ make --version +GNU Make 3.80 +Copyright (C) 2002 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. + +$ gcc --version +gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-8) +Copyright (C) 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +$ openssl version +OpenSSL 0.9.7a Feb 19 2003 + +$ doxygen --version +1.3.9.1 + +2. Unpack the toolkit source (one of the following): +> tar xf cpptk2_release.tar +> tar zxf cpptk2_release.tar.gz +> tar jxf cpptk2_release.tar.bz2 + +3. Build the C++ Toolkit shared library: +> make + +4. The previous command will leave object files in the bin directory and, most +importantly, the shared object file (libAusreg_EPP_toolkit.so) in the lib +directory. + + +C. Usage Information and Advice +------------------------------- + +1. When using the toolkit, the LD_LIBRARY_PATH should contain the lib +directory, or else the libAusreg_EPP_toolkit.so file shold be placed in a +system library directory, or the linker should otherwise be made aware of the +location of the libAusreg_EPP_toolkit.so file (such as by using ldconfig). +Also, the linker will need to find the Xalan and Xerces libraries (by similar +means). + +2. A configuration file (see toolkit2.conf for a sample file) must be available +to the toolkit at startup. It is recommended that this file be named +absolutely. This file directs the library to the location of other resources +required for correct operation. The user should ensure that each resource +named in the configuration file resolves to an available file on the system +(such as .xsd files). The sample configuration file is in the 'etc' directory. + +4. XML schema definition files are in the 'resources' directory. They may be +copied to another location as appropriate to the client's environment, but such +a location must be defined as described in step C.2. + + +D. Running Bundled Tests +------------------------ + +There are a set of unit tests provided with the source release of the C++ +toolkit. Follow the steps below to run these tests. In the examples, phrases +delimited by < and > should be replaced by suitable values, such as: +ORG= +to be replaced with: +ORG="AusRegistry Pty Ltd" + +1. Ensure the system requirements are met. + +2. Obtain the latest C++ toolkit source release. + +3. Obtain a valid username/password combination from the Registry server. + +4. Generate a private key and corresponding public certificate signing request, +as documented in the Registrar Help Centre (www.ausregistry.net.au). Define +the location of the private key and the certificate file returned by Registry +support staff in the toolkit configuration file. You will also receive a +CAfile from the Registry operator. The location of this must be specified by +the ssl.ca.location configuration parameter. The other parameters are +ssl.cert.location, ssl.privatekey.location and ssl.privatekey.pass for the +location of the public certificate and private key files and the passphrase of +the private key, respectively. + +5. Copy or modify the site.properties file from the 'etc' directory of the +Toolkit source release, and modify the parameters to suit your requirements. +The username and password are as obtained in (3) above. Registry support +should provide the location (hostname and port) of a suitable EPP server for +testing. +Note: the environment variable EPP_SITE_PROPERTIES defines the location of the +modified site.properties file and should be stated as an absolute filename. + +Example: +export EPP_SITE_PROPERTIES=/home/eppclient/etc/site-test.properties + +6. Run the supplied tests (will build the Toolkit library if not already built). +$ make tests + +9. Verify the results of the test run. If the test run is successful, then +there will be no output, otherwise each failed test will be reported to the +screen. Failure details are available in the target/test_reports directory. +Log messages are written by default to a file name 'log' in the working +directory. Only the messages from the last test class are available after the +test run completes. + +If the tests passed, congratulations! You have successfully configured the +dependencies of the toolkit. The next step is to consult the user manual, +which is available from the Registry Portal. Keep track of the resources +created during this procedure, especially the private key and public +certificate, as these will be required by the toolkit when integrated into your +application. + + +--- End of README.txt --- diff --git a/AusRegEPPTK/RELEASE_NOTES.txt b/AusRegEPPTK/RELEASE_NOTES.txt new file mode 100644 index 0000000..f9e11c8 --- /dev/null +++ b/AusRegEPPTK/RELEASE_NOTES.txt @@ -0,0 +1,20 @@ +AusRegistry's EPP Client Library for the C++ Programming Language. + +Changes in version 1.3.2 +* Change API on TLSSocket. writeInt(int i) now throws SSLException. +* Blocked SIGPIPE signal as work around fix for OpenSSL bug in version (openssl-0.9.8e-22.el5). +* Fixed exception handling mismatches in TLSSession class. + +Changes in version 1.3.1 +* Corrected sample hostname value in toolkit2.conf. + +Changes in version 1.3 +* Added classes to support DNSSEC through SecDNS-1.1 schema + +Changes in version 1.2 +* Added classes to support Key Value extensions (DomainInfoKVResponseExtension, DomainKVCommandExtension, KVExtension) +* Added classes to support generic Domain Registrant Transfer command (DomainRegistrantTransfer) + +Changes in version 1.1 +* Added classes to support Domain Expiry Synchronisation (DomainUpdateSyncCommandExtension) +* Fixed memory leaks diff --git a/AusRegEPPTK/common/AutoMutex.hpp b/AusRegEPPTK/common/AutoMutex.hpp new file mode 100644 index 0000000..2a684e2 --- /dev/null +++ b/AusRegEPPTK/common/AutoMutex.hpp @@ -0,0 +1,29 @@ +#ifndef __AUTO_MUTEX_HPP +#define __AUTO_MUTEX_HPP + +#include + +/** + * Wrapper to ensure mutex lock/unlock matching in the presence of exceptions. + */ +class AutoMutex +{ +public: + AutoMutex(pthread_mutex_t* mutex) + : mtx(mutex) + { + // XXX errors + pthread_mutex_lock(mtx); + } + + ~AutoMutex() + { + // XXX errors + pthread_mutex_unlock(mtx); + } + +private: + pthread_mutex_t* mtx; +}; +#endif // __AUTO_MUTEX_HPP + diff --git a/AusRegEPPTK/common/ConfigurationError.hpp b/AusRegEPPTK/common/ConfigurationError.hpp new file mode 100644 index 0000000..99b4186 --- /dev/null +++ b/AusRegEPPTK/common/ConfigurationError.hpp @@ -0,0 +1,17 @@ +#ifndef __CONFIGURATION_ERROR_HPP +#define __CONFIGURATION_ERROR_HPP + +#include "common/EPPException.hpp" + +class ConfigurationError : public EPPException +{ +public: + ConfigurationError (const std::string &msg) + : EPPException (msg) {}; + + ConfigurationError (const EPPException &other) + : EPPException (other.getMessage()) {}; + EPP_EXCEPTION(ConfigurationError); +}; + +#endif // __CONFIGURATION_ERROR_HPP diff --git a/AusRegEPPTK/common/Constants.cpp b/AusRegEPPTK/common/Constants.cpp new file mode 100644 index 0000000..d1d7a50 --- /dev/null +++ b/AusRegEPPTK/common/Constants.cpp @@ -0,0 +1,7 @@ +#include "common/Constants.hpp" + +bool Constants::useObjectPrefixes(true); +bool Constants::useRealTime(false); +bool Constants::isValidating(true); +const std::string Constants::DEFAULT_LANG("en"); + diff --git a/AusRegEPPTK/common/Constants.hpp b/AusRegEPPTK/common/Constants.hpp new file mode 100644 index 0000000..b96e2e6 --- /dev/null +++ b/AusRegEPPTK/common/Constants.hpp @@ -0,0 +1,13 @@ +#ifndef __CONSTANTS_HPP +#define __CONSTANTS_HPP + +#include + +class Constants +{ +public: + static bool useObjectPrefixes, useRealTime, isValidating; + static const std::string DEFAULT_LANG; +}; + +#endif // __CONSTANTS_HPP diff --git a/AusRegEPPTK/common/Deprecated.hpp b/AusRegEPPTK/common/Deprecated.hpp new file mode 100644 index 0000000..2b25923 --- /dev/null +++ b/AusRegEPPTK/common/Deprecated.hpp @@ -0,0 +1,22 @@ +#ifndef DEPRECATED_HPP_ +#define DEPRECATED_HPP_ + +/* + * Platform independent way of deprecating methods, as referenced from + * http://stackoverflow.com/questions/295120/c-mark-as-deprecated. + */ + +#ifdef __GNUC__ +/* Deprecating classes and constructors by using this attribute may have some + * issues in versions older than 4.5.0, as reported in this gcc bug + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43797 + */ +#define DEPRECATED(func) func __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED(func) __declspec(deprecated) func +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define DEPRECATED(func) func +#endif + +#endif /* DEPRECATED_HPP_ */ diff --git a/AusRegEPPTK/common/EPPException.hpp b/AusRegEPPTK/common/EPPException.hpp new file mode 100644 index 0000000..f0bcc28 --- /dev/null +++ b/AusRegEPPTK/common/EPPException.hpp @@ -0,0 +1,54 @@ +#ifndef __EPP_EXCEPTION_H +#define __EPP_EXCEPTION_H + +#include +#include +#include + +#include + +#define EPP_EXCEPTION(className) virtual EPPException* clone() const { return new className (*this); } + +/** + * Root exception class for exception reporting within the EPP toolkit. + */ +class EPPException +{ +public: + + // constructor. + EPPException(const std::string& message) + : msg(message), cause(NULL) + { } + + // copy constructor. + EPPException(const EPPException& other) + : msg(other.msg) + { + if (other.cause) cause = other.cause->clone(); + else cause = NULL; + } + + virtual ~EPPException() { if (cause) delete cause; } + + const std::string getMessage() const + { + return msg + (cause != NULL ? "\nCaused by\n" + cause->getMessage() : ""); + } + + /// Indicate that this exception was caused by another exception. + virtual void causedBy(const EPPException& ex) + { + cause = ex.clone(); + } + + EPPException* getCause() const { return cause; } + EPP_EXCEPTION(EPPException); + +private: + + std::string msg; + EPPException* cause; +}; + +#endif //__EPP_EXCEPTION_H diff --git a/AusRegEPPTK/common/EPPExceptionTest.cpp b/AusRegEPPTK/common/EPPExceptionTest.cpp new file mode 100644 index 0000000..c77550e --- /dev/null +++ b/AusRegEPPTK/common/EPPExceptionTest.cpp @@ -0,0 +1,14 @@ +#include "common/EPPException.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +int main(int argc, char* argv[]) +{ + EPPException a("whoops"); + EPPException b("there was a problem"); + a.causedBy(b); + ASSERT_EQ(a.getMessage(), "whoops\nCaused by\nthere was a problem"); +} diff --git a/AusRegEPPTK/common/ErrorPkg.cpp b/AusRegEPPTK/common/ErrorPkg.cpp new file mode 100644 index 0000000..22dadb1 --- /dev/null +++ b/AusRegEPPTK/common/ErrorPkg.cpp @@ -0,0 +1,104 @@ +#include "common/ErrorPkg.hpp" +#include "common/Logger.hpp" +#include "common/StringUtils.hpp" +#include "common/SystemProperties.hpp" + +#include + +#include +#include + +using namespace std; + +Properties ErrorPkg::properties; +static std::string pname; + + +void ErrorPkg::init() throw (PropertyConfigException) +{ + pname = "com.ausregistry.cpptoolkit"; + try + { + string msgsFile = SystemProperties::getProperty("epp.client.messages.file"); + Logger::getLogger(pname + ".debug")->fine("Using message file: " + msgsFile); + + Logger::getLogger(pname + ".debug")->fine("Loading messages file: " + msgsFile); + properties.load(msgsFile); + } + catch (PropertyNotFoundException& e) + { + PropertyConfigException pc("ErrPkg::init failed."); + pc.causedBy(e); + throw pc; + } +} + +string ErrorPkg::getMessage (const string &key) +{ + try + { + return properties.getProperty(key); + } + catch (PropertyNotFoundException) + { + Logger::getLogger(pname+".support")->warning + ("Message definition not found for name: " + key); + return ""; + } +} + + +string ErrorPkg::getMessage (const string &name, + const string &arg, + const string &val) +{ + try + { + string msg = getMessage(name); + + Logger::getLogger(pname+".debug")->finer + (name + ": " + arg + "= " + val); + + return StringUtils::replaceAll(msg, arg, val); + } + catch (ConfigurationError) + { + Logger::getLogger(pname+".support")->warning + ("Message definition not found for name: " + name); + return ""; + } +} + + +string ErrorPkg::getMessage(const string &name, + const vector &args, + const vector &vals) +{ + try + { + string msg = getMessage (name); + + for (unsigned int i = 0; i < args.size() && i < vals.size(); i++) + { + Logger::getLogger(pname+".debug")->fine("replace: " + args[i]); + Logger::getLogger(pname+".debug")->fine("with: " + vals[i]); + msg = StringUtils::replaceAll (msg, args[i], vals[i]); + } + + return msg; + } + catch (ConfigurationError) + { + Logger::getLogger(pname+".support")->warning + ("Message definition not found for name: " + name); + + return ""; + } +} + +string ErrorPkg::findMessageFile() +{ + string msgsFile = SystemProperties::getProperty("epp.client.messages.file"); + Logger::getLogger(pname+".debug")->config("Using message file: " + msgsFile); + return msgsFile; +} diff --git a/AusRegEPPTK/common/ErrorPkg.hpp b/AusRegEPPTK/common/ErrorPkg.hpp new file mode 100644 index 0000000..87a2b37 --- /dev/null +++ b/AusRegEPPTK/common/ErrorPkg.hpp @@ -0,0 +1,32 @@ +#ifndef __ERROR_PKG_HPP +#define __ERROR_PKG_HPP + +#include "common/Properties.hpp" +#include "common/ConfigurationError.hpp" +#include "common/Logger.hpp" +#include +#include + +class ErrorPkg +{ +public: + static std::string getMessage(const std::string& msg); + + static std::string getMessage(const std::string& msg, + const std::string& arg, + const std::string& val); + + static std::string getMessage(const std::string& msg, + const std::vector& args, + const std::vector& vals); + static void init() throw (PropertyConfigException); +private: + + static std::string getMessageInternal(const std::string& msg); + + static Properties properties; + + static std::string findMessageFile(); +}; + +#endif // __ERROR_PKG_HPP diff --git a/AusRegEPPTK/common/IllegalStateException.hpp b/AusRegEPPTK/common/IllegalStateException.hpp new file mode 100644 index 0000000..70a1e64 --- /dev/null +++ b/AusRegEPPTK/common/IllegalStateException.hpp @@ -0,0 +1,15 @@ +#ifndef __ILLEGAL_STATE_EXCEPTION_HPP +#define __ILLEGAL_STATE_EXCEPTION_HPP + +#include "common/EPPException.hpp" + +class IllegalStateException : public EPPException +{ +public: + IllegalStateException(const std::string &msg) + : EPPException (msg) + { } + EPP_EXCEPTION(IllegalStateException); +}; + +#endif // __ILLEGAL_ARGUMENT_EXCEPTION_HPP diff --git a/AusRegEPPTK/common/Logger.cpp b/AusRegEPPTK/common/Logger.cpp new file mode 100644 index 0000000..220d64c --- /dev/null +++ b/AusRegEPPTK/common/Logger.cpp @@ -0,0 +1,237 @@ +#include "SystemProperties.hpp" +#include "common/Logger.hpp" +#include +#include +#include "common/AutoMutex.hpp" + +#include +#include +#include + +using namespace std; + +namespace { + +// s_loggerMap and s_loggerProperties are protected by s_logPoolLock +class LoggerMap +{ +public: + + // This is primarily a thin wrapper around std::map to release the heap + // allocated Logger objects. (Bring on map ... ). + ~LoggerMap() + { + for (Map::iterator i = loggerMap.begin(); i != loggerMap.end(); ++i) + { + delete i->second; + } + } + typedef map Map; + typedef Map::const_iterator const_iterator; + + Map::const_iterator find(const string& name) const + { + return loggerMap.find(name); + } + + Map::const_iterator end() const { return loggerMap.end(); } + + void addLog(const string& name, Logger::LoggerLevel lvl, const string& fname) + { + loggerMap.insert(make_pair(name, new Logger(name, lvl, fname))); + } + +private: + Map loggerMap; +}; +static LoggerMap s_loggerMap; +static auto_ptr s_loggerProperties; + +pthread_mutex_t s_logPoolLock = PTHREAD_MUTEX_INITIALIZER; + +const char * LoggerLevelStringReps[Logger::__INVALID_LEVEL + 1] = +{ + "OFF", + "FINEST", + "FINER", + "FINE", + "CONFIG", + "INFO", + "WARNING", + "SEVERE", + "__INVALID_LEVEL" +}; + +string findKey(const string& parent, const string& key, const string& def) +{ + const string delim("."); + string::size_type i; + for (i = parent.size(); i != string::npos; i = parent.rfind(delim, i)) + { + try + { + return s_loggerProperties->getProperty(parent.substr(0, i) + delim + key); + } + catch (PropertyNotFoundException& e) + { } + if (i == 0) break; + i -= delim.size(); + } + return def; +} + +string getFileNameForLogger(const string& logName) +{ + try + { + return findKey(logName, "file", ""); + } + catch (EPPException& e) + { + return ""; + } +} + +Logger::LoggerLevel getLevelForLogger( + const string& logName, + const Logger::LoggerLevel defaultLevel) +{ + try + { + const string lvl(findKey(logName, "level", "WARNING")); + for (int i = 0; i < Logger::__INVALID_LEVEL; i++) + { + if (lvl == LoggerLevelStringReps[i]) + { + return (Logger::LoggerLevel)i; + } + } + return defaultLevel; + } + catch (EPPException& e) + { + return defaultLevel; + } +} + +// Add a time string to str. +ostream& logTime(ostream& str) +{ + struct timeval tv; + struct tm tm; + const char BUFSZ=32; + char tmpbuf[BUFSZ]; + + gettimeofday(&tv, NULL); + gmtime_r(&(tv.tv_sec), &tm); + + strftime(tmpbuf, BUFSZ, "%Y%m%d %H:%M:%S", &tm); + str << tmpbuf; + snprintf(tmpbuf, BUFSZ, ".%03ld", tv.tv_usec / 1000); + str << tmpbuf; + return str; +} + +} // anonymous namespace + + +Logger::Logger(const string& name, const LoggerLevel ll, const string& fileName) + : myName(name), level(ll), stream(NULL) +{ + pthread_mutex_init(&mtx, NULL); + if (fileName.size() > 0) + { + stream = new ofstream(fileName.c_str(), ios_base::app); + if (!stream->good()) + { + cerr << "Logger: failed open file '" << fileName + << "' for logger '" << name << "'." << endl; + + // Note if the new worked, but the stream is 'invalid', the object + // still exists but is of no use. Let's delete it and treat it as + // for the default logging case. + delete stream; + stream = NULL; + } + } +} + +Logger::~Logger() +{ + pthread_mutex_destroy(&mtx); + if (stream) delete stream; +} + +void Logger::init() throw (PropertyConfigException) +{ + s_loggerMap = LoggerMap(); + s_loggerProperties = auto_ptr(new Properties); + try + { + s_loggerProperties->load(SystemProperties::getProperty("logging.config.file")); + } + catch (PropertyConfigException& e) + { + // We explicitly send this to cerr as the logging system itself is not working! + cerr << "Logger::init failed to load config: " + << e.getMessage() << endl; + throw; + } + catch (PropertyNotFoundException& e) + { + PropertyConfigException pce("Could not initialise the logging system."); + pce.causedBy(e); + + // We explicitly send this to cerr as the logging system itself is not + // working! + cerr << e.getMessage() << endl; + throw pce; + } +} + +Logger* Logger::getLogger(const string &name) +{ + AutoMutex lock(&s_logPoolLock); + + LoggerMap::const_iterator p = s_loggerMap.find(name); + if (p != s_loggerMap.end()) return p->second; + + const string fname = getFileNameForLogger(name); + const LoggerLevel ll = getLevelForLogger(name, WARNING); + s_loggerMap.addLog(name, ll, fname); + + // Redundant find, but this only happens once per log name. + return s_loggerMap.find(name)->second; +} + + +void Logger::log(LoggerLevel lvl, + const string& msg, + const string& unit, + int line) +{ + if (lvl >= this->level) + { + ostringstream str; + logTime(str) << " | " << myName << " | "; + if (unit != "") + { + str << unit; + if (line > 0) str << "[" << line << "]"; + str << " | "; + } + str << LoggerLevelStringReps[lvl] << ": " << msg << "\n"; + + AutoMutex lock(&mtx); + if (stream) + { + *stream << str.str(); + stream->flush(); + } + else + { + clog << str.str(); + clog.flush(); + } + } +} diff --git a/AusRegEPPTK/common/Logger.hpp b/AusRegEPPTK/common/Logger.hpp new file mode 100644 index 0000000..cde46cf --- /dev/null +++ b/AusRegEPPTK/common/Logger.hpp @@ -0,0 +1,92 @@ +#ifndef __LOGGER_HPP +#define __LOGGER_HPP + +#include "common/Properties.hpp" +#include "common/ConfigurationError.hpp" + +#include +#include +#include +#include + +#define LOG_FINEST(msg) log(Logger::FINEST, msg, __FILE__, __LINE__) +#define LOG_FINER(msg) log(Logger::FINER, msg, __FILE__, __LINE__) +#define LOG_FINE(msg) log(Logger::FINE, msg, __FILE__, __LINE__) +#define LOG_CONFIG(msg) log(Logger::CONFIG, msg, __FILE__, __LINE__) +#define LOG_INFO(msg) log(Logger::INFO, msg, __FILE__, __LINE__) +#define LOG_WARNING(msg) log(Logger::WARNING, msg, __FILE__, __LINE__) +#define LOG_SEVERE(msg) log(Logger::SEVERE, msg, __FILE__, __LINE__) + +/** + * An interface that support logging at various severity levels and + * to various logging sinks. The toolkit uses a number of well known + * logging sinks as defined in the shipped 'logging.conf' property + * file. The Logging interface needs to be initialised before any + * toolkit application objects are constructed to ensure the settings + * present in the configuration have an effect. + * Note: SystemProperties::init() must have been run before using this + * interface. Logger::init() must be called first. + * The SystemProperty 'logging.config.file' must refer to a file contain + * the logging configuration. + */ +class Logger +{ +public: + enum LoggerLevel + { + OFF, + FINEST, + FINER, + FINE, + CONFIG, + INFO, + WARNING, + SEVERE, + __INVALID_LEVEL + }; + + /// @note Use the getLogger function exclusively to create loggers. + ~Logger(); + Logger(const std::string& name, const LoggerLevel ll, const std::string& fileName); + + + static void init() throw (PropertyConfigException); + + // Return the logger object from the configuration. + // @param name The logger identity. + static Logger* getLogger(const std::string &name); + + void severe(const std::string &str) { log(SEVERE,str); } + void warning(const std::string &str){ log(WARNING, str); } + void finest(const std::string &str) { log(FINEST, str); } + void finer(const std::string &str) { log(FINER, str); } + void fine(const std::string &str) { log(FINE, str); } + void info(const std::string &str) { log(INFO, str); } + void config(const std::string &str) { log(CONFIG, str); } + + /// Return true if a log message of the given level will be recorded + // by this logger. + // This may be useful in cases where it is considered comparatively + // expensive to construct a specific diagnostic--constuction can be + // predicated on whether or not the message will in fact be logged. + // @param lvl The log level importance level to test. + bool enabled(const LoggerLevel& lvl) { return lvl >= level; } + + void log(LoggerLevel lvl, + const std::string &str, + const std::string &unit = "", + int line = 0); + +private: + Logger(const Logger&); + Logger& operator=(Logger&); + + pthread_mutex_t mtx; + + std::string myName; + LoggerLevel level; + std::ostream* stream; + + void logMessage(const std::string& msg, LoggerLevel lvl); +}; +#endif // __LOGGER_HPP diff --git a/AusRegEPPTK/common/ParameterSyntaxException.hpp b/AusRegEPPTK/common/ParameterSyntaxException.hpp new file mode 100644 index 0000000..0ab0f6d --- /dev/null +++ b/AusRegEPPTK/common/ParameterSyntaxException.hpp @@ -0,0 +1,14 @@ +#ifndef __PARAMETER_SYNTAX_EXCEPTION_HPP +#define __PARAMETER_SYNTAX_EXCEPTION_HPP + +#include "common/EPPException.hpp" + +class ParameterSyntaxException : public EPPException +{ +public: + ParameterSyntaxException (const std::string &msg) + : EPPException (msg) {}; + EPP_EXCEPTION(ParameterSyntaxException); +}; + +#endif // __PARAMETER_SYNTAX_EXCEPTION_HPP diff --git a/AusRegEPPTK/common/Properties.cpp b/AusRegEPPTK/common/Properties.cpp new file mode 100644 index 0000000..a22900e --- /dev/null +++ b/AusRegEPPTK/common/Properties.cpp @@ -0,0 +1,212 @@ +#include "common/Properties.hpp" +#include "config/boolean.h" +#include +#include + +using namespace std; + +Properties::Properties(const string &filename) + throw (PropertyConfigException) + : theConfig(NULL), _initFailed(false) +{ + load(filename); +} + +Properties::~Properties() +{ + if (theConfig) + { + config_destroy(theConfig); + } +} + +void Properties::load(const string& filename) + throw (PropertyConfigException) +{ + if (theConfig) + { + config_destroy(theConfig); + theConfig = NULL; + } + + if ((theConfig = config_open(filename.c_str())) == NULL) + { + _initFailed = true; + throw PropertyConfigException("Properties::load: failed to open '" + filename + "'."); + } + _initFailed = false; +} + +void Properties::store(const string &filename) const + throw (PropertyConfigException, PropertyIoException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + + if (config_save(theConfig, filename.c_str()) == FALSE) + throw PropertyIoException("Could not write properties to file '" + filename + "'."); +} + +string Properties::getProperty(const string &prop) const + throw (PropertyNotFoundException, PropertyConfigException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + + char *value = config_get_str(theConfig, prop.c_str()); + + if (value) + { + string str_value (value); + free(value); + return str_value; + } + else + throw PropertyNotFoundException(prop); +} + +string Properties::getProperty(const string &prop, const string &def) const + throw (PropertyConfigException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + try + { + return getProperty(prop); + } + catch (PropertyNotFoundException&) + { + return def; + } +} + +vector > +Properties::getProperties(const string &prop_prefix) const +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + vector > result; + config_iter_t *i = config_iter_create(theConfig,prop_prefix.c_str()); + while(i->key!=NULL) + { + result.push_back(make_pair(i->key,i->value)); + config_iter_next(i); + } + config_iter_destroy(i); + + return result; +} + + +void Properties::setProperty(const string &prop, + const string &value) + throw (PropertyConfigException, PropertyIoException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + if (config_put_str (theConfig, prop.c_str(), value.c_str()) == NULL) + throw PropertyIoException("Could not set property '" + prop + "' to value '" + value + "'."); +} + + +bool Properties::getBooleanProperty(const string &prop) const + throw (PropertyConfigException, PropertyNotFoundException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + int value; + if (config_get_bool (theConfig, prop.c_str(), &value) == FALSE) + throw PropertyNotFoundException(prop); + + return (value == TRUE ? true : false); +} + +bool Properties::getBooleanProperty (const string &prop, + bool defaultValue) const + throw (PropertyConfigException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + try + { + return getBooleanProperty(prop); + } + catch (PropertyNotFoundException) + { + return defaultValue; + } +} + + +int Properties::getIntProperty (const string &prop) const + throw (PropertyNotFoundException, PropertyConfigException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + int value; + if (config_get_int(theConfig, prop.c_str(), &value) == FALSE) + throw PropertyNotFoundException(prop); + + return value; +} + + +int Properties::getIntProperty(const string &prop, + int defaultValue) const + throw (PropertyConfigException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + try + { + return getIntProperty(prop); + } + catch (PropertyNotFoundException) + { + return defaultValue; + } +} + + +long Properties::getLongProperty (const string &prop) const + throw (PropertyConfigException, PropertyNotFoundException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + long value; + if (config_get_long (theConfig, prop.c_str(), &value) == FALSE) + throw PropertyNotFoundException(prop); + + return value; +} + + +long Properties::getLongProperty (const string &prop, + long defaultValue) const + throw (PropertyConfigException) +{ + if (theConfig == NULL) + throw PropertyConfigException("Properties are not loaded."); + try + { + return getLongProperty (prop); + } + catch (PropertyNotFoundException) + { + return defaultValue; + } +} + +#if 0 +void Properties::splitString (const string &in, + char delim, + vector &out) +{ + out.clear(); + + istringstream iss(in); + string token; + while (getline (iss, token, delim)) + out.push_back (token); +} +#endif diff --git a/AusRegEPPTK/common/Properties.hpp b/AusRegEPPTK/common/Properties.hpp new file mode 100644 index 0000000..5ae39e4 --- /dev/null +++ b/AusRegEPPTK/common/Properties.hpp @@ -0,0 +1,110 @@ +#ifndef __PROPERTIES_HPP +#define __PROPERTIES_HPP + +#include "config/config.h" +#include "common/EPPException.hpp" + +#include +#include +#include + + +/// This is throw when a Properties instance can not be loaded or saved +// or when a property is accessed prior to the instance being initialised. +class PropertyConfigException : public EPPException +{ +public: + PropertyConfigException() + : EPPException("Property configuration error.") + { } + PropertyConfigException(const std::string &msg) + : EPPException(msg) { } + EPP_EXCEPTION(PropertyConfigException); +}; + +/// Indicates that the request property name can not be found. +class PropertyNotFoundException : public EPPException +{ +public: + PropertyNotFoundException(const std::string &property) + : EPPException("Property not found: " + property) { } + EPP_EXCEPTION(PropertyNotFoundException); +}; + +/// Thrown when a Properties file encounters an error when writing changes +// to the underlying property file. +class PropertyIoException : public EPPException +{ +public: + PropertyIoException(const std::string &msg) + : EPPException(msg) { } + EPP_EXCEPTION(PropertyIoException); +}; + +/** + * Instances of these class manage a file containing 'name=value' lines. + * A number of function are available with can allow the value to be + * transformed into a specific type, or for a default value to be returned + * if the 'name' can not be found (or of the value is malformed). + */ +class Properties +{ +public: + + Properties() : theConfig(NULL), _initFailed(false) { }; + Properties(const std::string &filename) throw (PropertyConfigException); + ~Properties(); + + bool isInitialised() const { return (theConfig != NULL); } + bool initFailed() const { return _initFailed; } + + /// This must be called prior to accessing, setting or storing properties. + void load(const std::string &filename) throw (PropertyConfigException); + + void store(const std::string &filename) const + throw (PropertyConfigException, PropertyIoException); + + std::string getProperty(const std::string &prop) const + throw (PropertyNotFoundException, PropertyConfigException); + + std::string getProperty(const std::string &prop, const std::string& def) const + throw (PropertyConfigException); + + std::vector > + getProperties(const std::string& prop_prefix) const; + + bool getBooleanProperty(const std::string &prop) const + throw (PropertyConfigException, PropertyNotFoundException); + + bool getBooleanProperty(const std::string &prop, + bool defaultValue) const + throw (PropertyConfigException); + + int getIntProperty(const std::string &prop) const + throw (PropertyConfigException, PropertyNotFoundException); + + int getIntProperty(const std::string &prop, + int defaultValue) const + throw (PropertyConfigException); + + long getLongProperty(const std::string &prop) const + throw (PropertyNotFoundException, PropertyConfigException); + + long getLongProperty(const std::string &prop, + long defaultValue) const + throw (PropertyConfigException); + + void setProperty(const std::string &prop, + const std::string &value) + throw (PropertyIoException, PropertyConfigException); + +private: + config_t *theConfig; + bool _initFailed; + + static void splitString(const std::string &in, + char delim, + std::vector & out); +}; + +#endif // __PROPERTIES_HPP diff --git a/AusRegEPPTK/common/StringUtils.cpp b/AusRegEPPTK/common/StringUtils.cpp new file mode 100644 index 0000000..8874745 --- /dev/null +++ b/AusRegEPPTK/common/StringUtils.cpp @@ -0,0 +1,73 @@ +#include "common/StringUtils.hpp" + +#include +#include + +using namespace std; + +string StringUtils::replaceAll (const string &theString, + const string &orig, + const string &repl) +{ + string retval (theString); + + int replLen = repl.length(), origLen = orig.length(); + + string::size_type idx = 0; + while ((idx = retval.find (orig, idx)) != string::npos) + retval.replace (idx, origLen, repl, 0, replLen); + + return retval; +} + +string StringUtils::replaceFirst (const string &theString, + const string &orig, + const string &repl) +{ + string retval (theString); + + string::size_type idx = retval.find (orig, 0); + if (idx != string::npos) + retval.replace (idx, orig.length(), repl, 0, repl.length()); + + return retval; +} + + + + +/* + * Create a hash code for the string. + * Uses the java string.hashCode() algorithm: + * + * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] + */ +StringUtils::HashType StringUtils::hashCode (const string &str) +{ + unsigned int n = str.length(); + HashType hash = 0L; + + long double term; + + for (unsigned int i = 0; i < n; i++) + { + term = pow ((long double)31, (int)(n-(i+1))); + hash += str[i] * (HashType)term; + } + + return hash; +} + + + +string StringUtils::makeString (int num) +{ + ostringstream intstr; + intstr << num; + return intstr.str(); +} + +string StringUtils::makeString (bool tf) +{ + return tf ? "true" : "false"; +} diff --git a/AusRegEPPTK/common/StringUtils.hpp b/AusRegEPPTK/common/StringUtils.hpp new file mode 100644 index 0000000..8ca0366 --- /dev/null +++ b/AusRegEPPTK/common/StringUtils.hpp @@ -0,0 +1,25 @@ +#ifndef __STRING_UTILS_HPP +#define __STRING_UTILS_HPP + +#include + +class StringUtils +{ +public: + typedef long long HashType; + + static std::string replaceAll (const std::string &theString, + const std::string &orig, + const std::string &repl); + + static std::string replaceFirst (const std::string &theString, + const std::string &orig, + const std::string &repl); + + static HashType hashCode (const std::string &str); + + static std::string makeString (int num); + static std::string makeString (bool tf); +}; + +#endif // __STRING_UTILS_HPP diff --git a/AusRegEPPTK/common/SystemProperties.cpp b/AusRegEPPTK/common/SystemProperties.cpp new file mode 100644 index 0000000..29e29dd --- /dev/null +++ b/AusRegEPPTK/common/SystemProperties.cpp @@ -0,0 +1,36 @@ +#include "common/SystemProperties.hpp" +#include + +using namespace std; + +namespace { + Properties properties; +} + +void SystemProperties::init(const string& file) +{ + //static string name = "com.ausregistry.cpptoolkit"; + properties.load(file); +} + +string SystemProperties::getProperty(const string &prop) +{ + return properties.getProperty(prop); +} + + +string SystemProperties::getProperty(const string& prop, const string& def) +{ + return properties.getProperty(prop, def); +} + +vector > SystemProperties::getProperties(const string& prefix) +{ + return properties.getProperties(prefix); +} + +bool SystemProperties::getBooleanProperty(const string& prop, bool def) +{ + return properties.getBooleanProperty(prop, def); +} + diff --git a/AusRegEPPTK/common/SystemProperties.hpp b/AusRegEPPTK/common/SystemProperties.hpp new file mode 100644 index 0000000..91e4b77 --- /dev/null +++ b/AusRegEPPTK/common/SystemProperties.hpp @@ -0,0 +1,44 @@ +#ifndef __SYSTEM_PROPERTIES_HPP +#define __SYSTEM_PROPERTIES_HPP + +#include "common/Properties.hpp" + +/** + * Provides a simple interface to a system properties file. + */ +class SystemProperties +{ +public: + + /// Initialise the SystemProperties from the the given configuration file. + /// @param configFile The path to the configuration file. + static void init(const std::string& configFile); + + /// Get a single property value with the given name. + /// @param prop The property to retrieve. + static std::string getProperty(const std::string& prop); + + /// Get a single property value with the given name. + /// @param prop The property to retrieve. + static std::string getProperty(const std::string& prop, const std::string& def); + + + /// Get a set of proerties based upon a key prefix. + /// @param prop The property prefix. + /// @returns The matching property key and value pairs, or an empty array + /// if no key matched. + static std::vector > + getProperties(const std::string& prefix); + + + /// Get a boolean property. i.e. One that has a value of either "TRUE" or "FALSE" + /// @param prop The property. + /// @return The sense of the property. + static bool getBooleanProperty(const std::string& prop, bool def); + +private: + // Must not be instantiated. + SystemProperties(); +}; + +#endif // __SYSTEM_PROPERTIES_HPP diff --git a/AusRegEPPTK/common/Test.hpp b/AusRegEPPTK/common/Test.hpp new file mode 100644 index 0000000..d82607c --- /dev/null +++ b/AusRegEPPTK/common/Test.hpp @@ -0,0 +1,65 @@ +#ifndef __TEST_HPP +#define __TEST_HPP + +#include "common/EPPException.hpp" + +#include +#include + +static int g_numErrors = 0; +int TEST_errorCount() { return g_numErrors; } + +#define ASSERT_STR_EQ(got, expect) ASSERT_EQ(std::string(got), std::string(expect)) + +#define ASSERT(expr) \ + if (!(expr)) { \ + g_numErrors++; \ + std::cerr << __FILE__ << ":" << __LINE__ << ":" << #expr << std::endl;} + +#define ASSERT_EQ(got, expect) \ + if ((got) != (expect)) \ + { g_numErrors++; \ + std::cerr << __FILE__ << ":" << __LINE__ << ": (" \ + << got << " != " << expect \ + << ") for (" << #got" == "#expect")" << std::endl; } + +#define ASSERT_NULL(got) \ + if ((got) != NULL) \ + { g_numErrors++; \ + std::cerr << __FILE__ << ":" << __LINE__ << ": (" \ + << got << " != null" \ + << ") for (" << #got" == null)" << std::endl; } + +#define ASSERT_NEQ(got, expect) \ + if ((got) == (expect)) \ + { g_numErrors++; \ + std::cerr << __FILE__ << ":" << __LINE__ << ": (" \ + << got << " == " << expect \ + << ") for (" << #got" != "#expect")" << std::endl; } + +#define FAIL(msg) std::cerr << __FILE__ << ":" << __LINE__ << ": " << msg << std::endl + +int TEST_run(void (*test)()) +{ + try + { + (*test)(); + } + catch (EPPException& e) + { + std::cerr << "Unexpected EPPException: " << e.getMessage() << std::endl; + g_numErrors++; + } + catch (std::exception& e) + { + std::cerr << "Unexpected std::exception: " << e.what() << std::endl; + g_numErrors++; + } + catch (...) + { + std::cerr << "Unexpected unknown." << std::endl; + g_numErrors++; + } + return g_numErrors; +} +#endif // __TEST_HPP diff --git a/AusRegEPPTK/common/init.cpp b/AusRegEPPTK/common/init.cpp new file mode 100644 index 0000000..d0740d1 --- /dev/null +++ b/AusRegEPPTK/common/init.cpp @@ -0,0 +1,86 @@ +#include "common/SystemProperties.hpp" +#include "common/Logger.hpp" +#include "common/ErrorPkg.hpp" +#include "se/SendSE.hpp" +#include "se/ReceiveSE.hpp" +#include "se/IPVersion.hpp" +#include "se/PostalInfoType.hpp" +#include "se/StandardCommandType.hpp" +#include "se/AddRemType.hpp" +#include "se/StandardObjectType.hpp" +#include "se/PeriodUnit.hpp" +#include "se/PollOperation.hpp" +#include "se/TransferOp.hpp" +#include "xml/XMLParser.hpp" +#include "xml/XMLInit.hpp" +#include +#include + +#include +#include + +namespace { + +void initEnumTypes() +{ + // These classes are decendants of EnumType and so have static storage + // listing valid values. The init() method must be called to establish + // these values. + IPVersion::init(); + PostalInfoType::init(); + StandardCommandType::init(); + AddRemType::init(); + StandardObjectType::init(); + PeriodUnit::init(); + PollOperation::init(); + TransferOp::init(); +} + +class Init +{ +public: + Init(const std::string& system_props_file) + { + try + { + // SystemProperties, Logger and ErrorPkg must be initialised in + // this order. + sigset_t new_set, old_set; + sigemptyset(&new_set); + sigaddset(&new_set,SIGPIPE); + sigprocmask(SIG_BLOCK,&new_set,&old_set); + + SystemProperties::init(system_props_file); + Logger::init(); + ErrorPkg::init(); + + + XMLInit::init(); + XMLParser::init(); + XMLWriter::init(); + ReceiveSE::init(); + SendSE::init(); + + initEnumTypes(); + + } + catch (EPPException& e) + { + std::cerr << "Toolkit initialisation exception: " << e.getMessage() << std::endl; + throw; + } + catch (std::exception& e) + { + std::cerr << "Toolkit initialisation exception: " << e.what() << std::endl; + throw; + } + } +}; + +} // anonymous namepsace + + +void init(const std::string& system_props_file) +{ + static const Init doInit(system_props_file); +} diff --git a/AusRegEPPTK/common/init.hpp b/AusRegEPPTK/common/init.hpp new file mode 100644 index 0000000..aaef8c6 --- /dev/null +++ b/AusRegEPPTK/common/init.hpp @@ -0,0 +1,8 @@ +#ifndef __INIT_HPP +#define __INIT_HPP + +#include + +void init(const std::string& system_props_file); + +#endif diff --git a/AusRegEPPTK/config/Makefile b/AusRegEPPTK/config/Makefile new file mode 100644 index 0000000..3b8a66a --- /dev/null +++ b/AusRegEPPTK/config/Makefile @@ -0,0 +1,28 @@ + +CC = gcc + +CUNIT_INCLUDE = ~/CUnit-2.1-0/include/ + +INCLUDE_DIR = -I ${CUNIT_INCLUDE} + +LIBOBJS = boolean.o \ + config.o \ + log.o + +OBJS = $(LIBOBJS) test_config.o + + +LIBS = ~/CUnit-2.1-0/lib/libcunit.a + +DEPS = boolean.h config.h log.h + +%.o: %.c $(DEPS) + $(CC) -c $< $(CFLAGS) $(INCLUDE_DIR) + +libConfig.so: $(LIBOBJS) + $(CC) -o $@ $^ -shared + +test: $(OBJS) + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + + diff --git a/AusRegEPPTK/config/boolean.c b/AusRegEPPTK/config/boolean.c new file mode 100644 index 0000000..8a9f1ae --- /dev/null +++ b/AusRegEPPTK/config/boolean.c @@ -0,0 +1,10 @@ +#include +#include + +#include "boolean.h" + +const char* const bool_str_g[]={ + "FALSE", + "TRUE", + NULL +}; diff --git a/AusRegEPPTK/config/boolean.h b/AusRegEPPTK/config/boolean.h new file mode 100644 index 0000000..3885cbd --- /dev/null +++ b/AusRegEPPTK/config/boolean.h @@ -0,0 +1,13 @@ +#ifndef __BOOLEAN_H +#define __BOOLEAN_H + +#ifndef TRUE +#define TRUE 1 +#endif /* defined(TRUE) */ +#ifndef FALSE +#define FALSE 0 +#endif /* defined(FALSE) */ +extern const char *const bool_str_g[]; +#define BOOL_STR(x) bool_str_g[x] + +#endif //__BOOLEAN_H diff --git a/AusRegEPPTK/config/config.c b/AusRegEPPTK/config/config.c new file mode 100644 index 0000000..9c67365 --- /dev/null +++ b/AusRegEPPTK/config/config.c @@ -0,0 +1,512 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "log.h" +#include "boolean.h" +#include "string.h" +#include "mem_debug.h" + + +static const int KEYS_PER_BLOCK=64; + + +static char **config_find_entry(config_t *cfg, const char *key); +static int config_rebuild_index (config_t *cfg); +static int config_iter_seek(config_iter_t *iter); +static void config_reset_content(config_t *cfg); + +/* TODO add parsing state info/offsets for better error messages? */ +/* TODO iff this is an ACTUAL performance problem, could qsort cfg->keys at + * completion then bsearch on lookup */ +static int config_build_index(config_t *cfg) +{ + /* we modify cfg->content, NULL-terminating keys and values */ + char *c = cfg->content; + int pair_num=0; + + /* scan through looking for comments and "key=value\n" strings. */ + /* blank lines may contain whitespace, which is ignored (and line may be indented) */ + while (*c!='\0') + { + if (*c=='\n') + { + c++; + continue; + } + if (*c=='#') + { + if((c=strchr(c, '\n'))==NULL) + { + real_log("config_build_index: un-terminated comment.\n"); + return FALSE; + } + c++; /* move past the '\n' */ + continue; + } + if (isalpha(*c)) + { + /* if we have crossed a multiple of KEY_BLOCK_SIZE keys, grow by another 64. */ + if (pair_num && pair_num%KEYS_PER_BLOCK==0) + { + size_t new_size = (pair_num+KEYS_PER_BLOCK)*sizeof(char *); + cfg->keys=(char **)realloc_d(cfg->keys,new_size,"config_build_index: cfg->keys"); /* XXX errors */ + cfg->values=(char **)realloc_d(cfg->values,new_size,"config_build_index: cfg_values"); + } + cfg->keys[pair_num] = c; + if((c=strchr(c,'='))==NULL) + { + real_log("config_build_index: value without '=' found.\n"); + return FALSE; + } + *c='\0'; + c++; + cfg->values[pair_num] = c; + if((c=strchr(c, '\n'))==NULL) + { + real_log("config_build_index: a value was found that was not terminated by new-line.\n"); + return FALSE; + } + *c='\0'; + c++; + pair_num++; + continue; + } + if(isspace(*c)) + { + while(isspace(*c)) c++; + continue; + } + real_log("config_build_index: unexpected char '%c' at offset %d\n", *c, c-cfg->content); + return FALSE; + } + cfg->num_keys=pair_num; + return TRUE; +} + +config_t *config_open_inmem( + const char *data + ) +{ + int success=FALSE; + config_t *cfg=NULL; + + for(;;) + { + if ((cfg=(config_t *)malloc_d(sizeof(config_t),"config_open_inmem: config_t"))==NULL + || !memset(cfg,0,sizeof(config_t)) + || (cfg->content=strdup_d(data, "config_open_inmem: cfg->content")) == NULL + || (cfg->keys=malloc_d(KEYS_PER_BLOCK*sizeof(char *), "config_open_inmem: cfg->keys"))==NULL + || (cfg->values=malloc_d(KEYS_PER_BLOCK*sizeof(char *), "config_open_inmem: cfg->values"))==NULL) + { + real_log("config_open_inmem: memory allocation failed for config_t\n"); + break; + } + if (!config_build_index(cfg)) + { + real_log("config_open_inmem: failed to build config index\n"); + break; + } + cfg->content_bufsz = strlen(data) + 1; + success=TRUE; + break; + } + if(!success) + { + if (cfg) config_destroy(cfg); + return NULL; + } + return cfg; +} + + + +config_t *config_open( + const char *file_name +) +{ + int sz, success=FALSE; + config_t *cfg=NULL; + struct stat stats; + FILE *file=NULL; + + for(;;) + { + if (stat(file_name,&stats)==-1) + { + real_log("config_open: could not get information for '%s': %s\n", file_name, LOG_ERR_STR(errno)); + break; + } + if ((file=fopen(file_name,"r"))==NULL) + { + real_log("config_open: could not open '%s': %s\n", file_name, LOG_ERR_STR(errno)); + break; + } + if ((cfg=(config_t *)malloc_d(sizeof(config_t),"config_open: config_t"))==NULL + || !memset(cfg,0,sizeof(config_t)) + || (cfg->content=malloc_d(stats.st_size+1,"config_open: cfg->content"))==NULL + || (cfg->keys=malloc_d(KEYS_PER_BLOCK*sizeof(char *), "config_open: cfg->keys"))==NULL + || (cfg->values=malloc_d(KEYS_PER_BLOCK*sizeof(char *), "config_open: cfg->values"))==NULL) + { + real_log("config_open: memory allocation failed for config_t\n"); + break; + } + if ((sz=fread(cfg->content,sizeof(char),stats.st_size,file))!=stats.st_size) + { + real_log("config_open: fread return unexpected length (got %d, expected %d)\n", sz, stats.st_size); + break; + } + (cfg->content)[stats.st_size]='\0'; /* terminate file with NULL */ + cfg->content_bufsz = stats.st_size + 1; + if (!config_build_index(cfg)) + { + real_log("config_open: failed to build config index\n"); + break; + } + success=TRUE; + break; + } + if(file) fclose(file); + if(!success) + { + if (cfg) config_destroy(cfg); + return NULL; + } + return cfg; +} + +void config_destroy( + config_t *cfg +) +{ + free_d(cfg->keys,"config_destroy: cfg->keys"); + free_d(cfg->values,"config_destroy: cfg->values"); + free_d(cfg->content,"config_destroy: cfg->content"); + free(cfg); +} + +config_iter_t *config_iter_create( + config_t *cfg, + const char* prefix +) +{ + config_iter_t *iter; + iter=(config_iter_t *)malloc_d(sizeof(config_iter_t),"config_iter_create: iter"); + memset(iter,0,sizeof(config_iter_t)); + iter->cfg=cfg; + if(prefix) iter->prefix=strdup_d(prefix,"config_iter_create: pattern"); + config_iter_seek(iter); + return iter; +} + + +int config_iter_next( + config_iter_t *iter +) +{ + /* if iterator currently valid, increment */ + if(iter->key!=NULL) + { + iter->idx++; + if (config_iter_seek(iter)) + { + return TRUE; + } + /* indicate iter now at end */ + (iter->key)=(iter->value)=NULL; + } + return FALSE; +} + +void config_iter_destroy( + config_iter_t *cfg_iter +) +{ + free_d(cfg_iter->prefix,"config_iter_destroy: pattern"); + free_d(cfg_iter,"config_iter_destroy: cfg_iter"); +} + +/* returns NULL if string not found, or if key is NULL */ +char *config_get_str( + config_t *cfg, + const char *key) +{ + char **entry = config_find_entry(cfg, key); + + if (entry) + return strdup_d (*entry, "config_get_str: cfg->values[i]"); + else + return NULL; +} + +/* reallocates space for the config's content buffer, adjusting the + * existing size by delta. + */ +static void config_realloc_content (config_t *cfg, int delta) +{ + cfg->content = realloc_d (cfg->content, + cfg->content_bufsz + delta, + "config_realloc_content: cfg->content"); +} + +/* Slides the block of memory from 'block' to the end of the content buffer + * by dist bytes (may be negative). + */ +static void config_slide_content (config_t *cfg, char* block, int dist) +{ + size_t block_size = cfg->content_bufsz - (block - cfg->content); + + memmove (block + dist, + block, + block_size); +} + +/* Replaces the entry string with the new_entry string within the + * config's content buffer, adjusting the buffer size accordingly. + */ +void config_replace_entry(config_t *cfg, char *entry, const char *new_entry) +{ + size_t old_length = strlen(entry), new_length = strlen(new_entry); + int delta_size = new_length - old_length; + + /* point into the data directly after to the current entry value. */ + char *next_block = entry + old_length + 1; + + /* We need integer offsets into the buffer, so we can re-find + * the right position after realloc() is called. + */ + size_t next_block_offset = next_block - cfg->content; + size_t entry_offset = entry - cfg->content; + + /* The order we do this in depends on whether we're growing + * or shrinking the existing key's value. */ + if (delta_size > 0) + { + config_realloc_content (cfg, delta_size); + + /* Buffer will have (possibly) moved - point at the (possibly different) + * new location */ + next_block = cfg->content + next_block_offset; + + config_slide_content (cfg, next_block, delta_size); + } + else if (delta_size < 0) + { + config_slide_content (cfg, next_block, delta_size); + config_realloc_content (cfg, delta_size); + } + + cfg->content_bufsz += delta_size; + + entry = cfg->content + entry_offset; + memcpy(entry, new_entry, new_length+1); +} + +/* changes the value of an existing key, returning the new value or NULL + * if the key doesn't exist. + */ +char *config_put_str (config_t *cfg, + const char *key, + const char *new_value) +{ + char **entry = config_find_entry(cfg, key); + char *res = NULL; + + if (entry) + { + config_replace_entry (cfg, *entry, new_value); + if (config_rebuild_index (cfg)) + res = strdup_d (*entry, "config_put_str: value"); + } + + return res; +} + + + +int config_get_enum( + config_t *cfg, + const char *key, + const char* const allowed[], + int *val + ) +{ + int i, success=FALSE; + char *str_val; + if ((str_val=config_get_str(cfg,key))==NULL) return FALSE; + for(i=0;allowed[i]!=NULL;i++) + { + if(strcmp(str_val,allowed[i])==0) + { + *val=i; + success=TRUE; + break; + } + } + if (!success) real_log("config_get_enum: key '%s' has out-of-range enum value '%s'\n", key, str_val); + free_d(str_val,"config_get_enum: val"); + return success; +} + +/* same as config_get_enum, with 'allowed' == {"FALSE", "TRUE", NULL} */ +int config_get_bool( + config_t *cfg, + const char *key, + int *val) +{ + return config_get_enum(cfg, key, bool_str_g, val); +} + +/* return value associated with 'key' through 'val'. returns TRUE if + value found and int-like, or FALSE otherwise. */ +int config_get_int( + config_t *cfg, + const char *key, + int *val) +{ + int res; + int success=TRUE; + char *str_val; + if ((str_val=config_get_str(cfg, key))==NULL) + { + return FALSE; + } + /* we expect a single integer term to match */ + if (sscanf(str_val,"%d",&res)!=1) + { + real_log("config_get_int: key: '%s' not an integer, instead '%s'\n",key,str_val); + success=FALSE; + } + else *val=res; + free_d(str_val, "config_get_int: str_val"); + return success; +} + +int config_get_long (config_t *cfg, const char *key, long *val) +{ + long res; + int success=TRUE; + char *str_val; + if ((str_val=config_get_str(cfg, key))==NULL) + { + return FALSE; + } + /* we expect a single integer term to match */ + if (sscanf(str_val,"%ld",&res)!=1) + { + real_log("config_get_long: key: '%s' not a long, instead '%s'\n",key,str_val); + success=FALSE; + } + else *val=res; + free_d(str_val, "config_get_long: str_val"); + return success; +} + +/* JR */ + +/* Clones a config_t object */ +config_t *config_clone (const config_t * const other_cfg) +{ + config_t *cfg; + + if ((cfg=(config_t *)malloc_d(sizeof(config_t),"config_clone: config_t"))==NULL + || !memset(cfg,0,sizeof(config_t)) + || (cfg->content=malloc_d(other_cfg->content_bufsz,"config_clone: cfg->content"))==NULL + || (cfg->keys=malloc_d(KEYS_PER_BLOCK*sizeof(char *), "config_clone: cfg->keys"))==NULL + || (cfg->values=malloc_d(KEYS_PER_BLOCK*sizeof(char *), "config_clone: cfg->values"))==NULL) + { + real_log("config_open: memory allocation failed for config_t\n"); + return NULL; + } + + memcpy (cfg->content, other_cfg->content, other_cfg->content_bufsz); + if (config_rebuild_index (cfg)) + { + return cfg; + } + else + { + config_destroy (cfg); + return NULL; + } +} + +int config_save (config_t *cfg, + const char *file_name) +{ + int success = FALSE; + + FILE *file = fopen (file_name, "w"); + + if (file) + { + config_reset_content(cfg); + + fputs (cfg->content, file); + + fclose (file); + + config_build_index (cfg); + + success = TRUE; + } + + return success; +} + +/* replaces all the '=' and '\n' characters in the content buffer */ +static void config_reset_content(config_t *cfg) +{ + int i, keyOrValue = 0; + char *c = cfg->content; + + for (i = 0; i < cfg->content_bufsz - 1; i++) + if (cfg->content[i] == '\0') + cfg->content[i] = (keyOrValue = !keyOrValue) ? '=' : '\n'; +} + +static int config_rebuild_index (config_t *cfg) +{ + config_reset_content (cfg); + return config_build_index (cfg); +} + +static char **config_find_entry(config_t *cfg, const char *key) +{ + int i; + + if (key == NULL) + return NULL; + + for (i = 0; i < cfg->num_keys; i++) + if (strcmp (cfg->keys[i], key) == 0) + return &(cfg->values[i]); + + real_log ("config_find_entry: key not found '%s'\n", key); + return NULL; +} + +static int config_iter_seek(config_iter_t *iter) +{ + config_t *cfg=iter->cfg; + int prefix_len=(iter->prefix?strlen(iter->prefix):0); + + while(iter->idxnum_keys) + { + if(iter->prefix==NULL + ||strncmp(cfg->keys[iter->idx],iter->prefix,prefix_len)==0) + { + iter->key=cfg->keys[iter->idx]; + iter->value=cfg->values[iter->idx]; + return TRUE; + } + iter->idx++; + } + return FALSE; +} + diff --git a/AusRegEPPTK/config/config.h b/AusRegEPPTK/config/config.h new file mode 100644 index 0000000..edad40e --- /dev/null +++ b/AusRegEPPTK/config/config.h @@ -0,0 +1,61 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct config_t +{ + int content_bufsz; + char *content; + char **keys; + char **values; + int num_keys; +} config_t; + +config_t *config_open(const char *file_name); +config_t *config_open_inmem(const char *data); +void config_destroy(config_t *); + +int config_save(config_t *cfg, const char *file_name); +config_t *config_clone(const config_t * const other_cfg); + +/* return value associated with 'key', or NULL if key not found. caller + must free returned string */ +char *config_get_str(config_t *,const char *key); + +/* write a new value to the key and return the value string. */ +char *config_put_str(config_t *cfg, const char *key, const char *value); + +/* return through 'val' the integer value associated with 'key'. if found and + * int-like, return TRUE, else FALSE */ +int config_get_int(config_t *cfg,const char *key,int* val); +int config_get_long(config_t *cfg,const char *key,long* val); + +/* return through 'val' the offset within the list of possible values given by + * 'allowed' for the config key 'key'. 'allowed' is NULL terminated. Return TRUE + * if key found and value within range, else FALSE. */ +int config_get_enum(config_t *cfg,const char *key,const char* const allowed[],int *val); + +/* same as config_get_enum, with 'allowed' == {"FALSE", "TRUE", NULL} */ +int config_get_bool(config_t *cfg,const char *key,int *val); + +typedef struct config_iter_t +{ + char *key; + char *value; + char *prefix; + config_t *cfg; + int idx; +} config_iter_t; + +config_iter_t *config_iter_create(config_t *,const char* pattern); +void config_iter_destroy(config_iter_t *); +int config_iter_next(config_iter_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _CONFIG_H */ diff --git a/AusRegEPPTK/config/log.c b/AusRegEPPTK/config/log.c new file mode 100644 index 0000000..2b174ed --- /dev/null +++ b/AusRegEPPTK/config/log.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "boolean.h" + +#define LOG_BUFFER_SIZE 6000 +static void real_log_again( + const char *format, + va_list ap + ); + +/* need a debug flag for this ... */ +static int g_mylog_enabled = FALSE; + +#ifdef __cplusplus +extern "C" { +#endif + +const char *LOG_ERR_STR(int errnum) +{ + /* uses the GNU specific strerror_r which requires a buffer which it + * 'might' use. provide one, but make is zero length */ + char dummy; + return strerror_r(errnum, &dummy, 0); +} + +//TODO this is a workaround for proper logging for now +// NB: Adds a '\n' to message. +void mylog( + const char *const format, + ... + ) +{ + if (!g_mylog_enabled) return; + va_list ap; + + va_start(ap,format); + vfprintf(stderr,format,ap); + fprintf(stderr,"\n"); + va_end(ap); + + return; +} + +void real_log( + const char *const format, + ... + ) +{ + if (!g_mylog_enabled) return; + va_list ap; + + va_start(ap,format); + real_log_again(format,ap); + va_end(ap); + + return; +} + +#ifdef __cplusplus +} +#endif + +static void real_log_again( + const char *format, + va_list ap + ) +{ + char buffer[LOG_BUFFER_SIZE+1]; + struct timeval tv; + struct tm tm; + + gettimeofday(&tv,NULL); + gmtime_r(&(tv.tv_sec),&tm); + snprintf(buffer,LOG_BUFFER_SIZE,"%d%02d%02d %02d:%02d:%02d.%03lu %s",1900+tm.tm_year,1+tm.tm_mon,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec,tv.tv_usec/1000,format); + vfprintf(stderr,buffer,ap); + + return; +} diff --git a/AusRegEPPTK/config/log.h b/AusRegEPPTK/config/log.h new file mode 100644 index 0000000..4b1c92b --- /dev/null +++ b/AusRegEPPTK/config/log.h @@ -0,0 +1,27 @@ +#ifndef __LOG_H +#define __LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +const char *LOG_ERR_STR(int errnum); + +void mylog( + const char *const format, + ... + ); + +void real_log( + const char *const format, + ... + ); + +//critical loggin needs to be handled by the thread itself otherwsie we risk exiting before the log is written out +//XXX think about making an on exit to flush and close log files otherwise messages might get lost + +#ifdef __cplusplus +} +#endif + +#endif //__LOG_H diff --git a/AusRegEPPTK/config/mem_debug.h b/AusRegEPPTK/config/mem_debug.h new file mode 100644 index 0000000..18aba43 --- /dev/null +++ b/AusRegEPPTK/config/mem_debug.h @@ -0,0 +1,4 @@ +#define realloc_d(x,y,z) realloc(x,y) +#define malloc_d(x,y) malloc(x) +#define free_d(x,y) free(x) +#define strdup_d(x,y) strdup(x) diff --git a/AusRegEPPTK/etc/Doxyfile b/AusRegEPPTK/etc/Doxyfile new file mode 100644 index 0000000..732ea16 --- /dev/null +++ b/AusRegEPPTK/etc/Doxyfile @@ -0,0 +1,1252 @@ +# Doxyfile 1.5.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = AusRegistry C++ Toolkit (2) + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = session common config se + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/AusRegEPPTK/etc/logging.conf b/AusRegEPPTK/etc/logging.conf new file mode 100644 index 0000000..e652fc4 --- /dev/null +++ b/AusRegEPPTK/etc/logging.conf @@ -0,0 +1,17 @@ +com.ausregistry.cpptoolkit.file=log + +com.ausregistry.cpptoolkit.debug.level=FINEST + +com.ausregistry.cpptoolkit.support.level=FINEST + +com.ausregistry.cpptoolkit.se.maint.level=FINEST +com.ausregistry.cpptoolkit.se.support.level=FINEST +com.ausregistry.cpptoolkit.se.user.level=FINEST +com.ausregistry.cpptoolkit.se.debug.level=FINEST + +com.ausregistry.cpptoolkit.session.debug.level=FINEST +com.ausregistry.cpptoolkit.session.user.level=FINEST +com.ausregistry.cpptoolkit.session.support.level=FINEST + +com.ausregistry.cpptoolkit.xml.debug.level=FINEST +com.ausregistry.cpptoolkit.xml.user.level=FINEST diff --git a/AusRegEPPTK/etc/site.properties b/AusRegEPPTK/etc/site.properties new file mode 100644 index 0000000..4fde468 --- /dev/null +++ b/AusRegEPPTK/etc/site.properties @@ -0,0 +1,17 @@ +# These are site-specific properties used by the test suites. +# The environment variable EPP_SITE_PROPERTIES can be set to the path of a localised +# file for the following variables. The TestEnvironment class will use this env var +# to find the specialised site properties. +# +epp.client.clID=<> +epp.client.password=<> + +epp.server.hostname=<> +epp.server.port=<> + +# Relative paths will be interpreted relative to the cwd of the process using +# the TestEnvironment instance. +ssl.privatekey.location=<> +ssl.privatekey.pass=<> +ssl.cert.location=<> +ssl.ca.location=<> diff --git a/AusRegEPPTK/etc/toolkit2.conf b/AusRegEPPTK/etc/toolkit2.conf new file mode 100644 index 0000000..adc79f8 --- /dev/null +++ b/AusRegEPPTK/etc/toolkit2.conf @@ -0,0 +1,107 @@ +# This may be either exactly "TRUE" or "FALSE". Setting this to TRUE will +# enable strict inbound and outbound schema validations. TRUE is the +# recommended setting. +xml.validation.enable=TRUE + +# This file contains the text for the majority of the error and information +# messages used by the toolkit. +# +epp.client.messages.file=resources/messages.properties + +# Path to the definition of the logging 'sinks' and their respective +# sensitivity. See the shipped version of this file for more details and +# comments. +# +logging.config.file=etc/logging.conf + +# Each URN and entity pair must be separated by a single space character. All +# keys that have the prefix "xml.schema.location." will be considered as a +# schema location hints. +# +xml.schema.location=urn:ietf:params:xml:ns:eppcom-1.0 resources/eppcom-1.0.xsd +xml.schema.location=urn:ietf:params:xml:ns:epp-1.0 resources/epp-1.0.xsd +xml.schema.location=urn:ietf:params:xml:ns:host-1.0 resources/host-1.0.xsd +xml.schema.location=urn:ietf:params:xml:ns:contact-1.0 resources/contact-1.0.xsd +xml.schema.location=urn:ietf:params:xml:ns:domain-1.0 resources/domain-1.0.xsd +xml.schema.location=urn:ietf:params:xml:ns:e164epp-1.0 resources/e164epp-1.0.xsd +xml.schema.location=urn:ietf:params:xml:ns:secDNS-1.1 resources/secDNS-1.1.xsd +xml.schema.location=urn:au:params:xml:ns:auext-1.0 resources/auext-1.0.xsd +xml.schema.location=urn:X-au:params:xml:ns:auext-1.1 resources/auext-1.1.xsd +xml.schema.location=urn:X-au:params:xml:ns:audomain-1.0 resources/audomain-1.0.xsd +#xml.schema.location=urn:X-ae:params:xml:ns:aeext-1.0 resources/aeext-1.0.xsd +#xml.schema.location=urn:X-ae:params:xml:ns:aedomain-1.0 resources/aedomain-1.0.xsd +xml.schema.location=urn:X-ar:params:xml:ns:arext-1.0 resources/arext-1.0.xsd +xml.schema.location=urn:X-ar:params:xml:ns:ardomain-1.0 resources/ardomain-1.0.xsd +xml.schema.location=urn:X-ar:params:xml:ns:sync-1.0 resources/sync-1.0.xsd +xml.schema.location=urn:X-ar:params:xml:ns:kv-1.0 resources/kv-1.0.xsd +xml.schema.location=urn:X-ar:params:xml:ns:registrant-1.0 resources/registrant-1.0.xsd + +# Server hostname or IP address (textual representation). +epp.server.hostname=HOSTNAME + +# EPP login data. +epp.client.clID=MYUSER +epp.client.password=MYPASS +epp.client.options.lang=en + +# The maximum number of sessions which the session pool will allow to open. +epp.client.session.count.max=3 + +# TLS resources. +ssl.privatekey.location=<> +ssl.cert.location=<> +ssl.ca.location=<> +ssl.privatekey.pass=<> + +# Parameters fixed for a given EPP specification. +epp.server.port=700 +epp.client.options.version=1.0 +ssl.protocol=TLSv1 + +# Request management of these objects at login +xml.uri.obj.host=urn:ietf:params:xml:ns:host-1.0 +xml.uri.obj.contact=urn:ietf:params:xml:ns:contact-1.0 +xml.uri.obj.domain=urn:ietf:params:xml:ns:domain-1.0 + +# Request use of these extensions at login +xml.uri.ext.e164epp=urn:ietf:params:xml:ns:e164epp-1.0 +#xml.uri.ext.auext1=urn:X-au:params:xml:ns:auext-1.0 +xml.uri.ext.auext=urn:X-au:params:xml:ns:auext-1.1 +xml.uri.ext.audomain=urn:X-au:params:xml:ns:audomain-1.0 +xml.uri.ext.arext=urn:X-ar:params:xml:ns:arext-1.0 +xml.uri.ext.ardomain=urn:X-ar:params:xml:ns:ardomain-1.0 +xml.uri.ext.sync=urn:X-ar:params:xml:ns:sync-1.0 +xml.uri.ext.kv=urn:X-ar:params:xml:ns:kv-1.0 +xml.uri.ext.registrant=urn:X-ar:params:xml:ns:registrant-1.0 +xml.uri.ext.secDNS=urn:ietf:params:xml:ns:secDNS-1.1 + +# Command Rate Limits +# Match these to the server's published values for optimal performance. +epp.server.command.limit.check=100 +epp.server.command.limit.info=100 +epp.server.command.limit.transfer=100 +epp.server.command.limit.create=100 +epp.server.command.limit.delete=100 +epp.server.command.limit.update=100 +epp.server.command.limit.renew=100 +epp.server.command.limit.unrenew=100 +epp.server.command.limit.undelete=100 +epp.server.command.limit.policyDelete=100 +epp.server.command.limit.policyUndelete=100 +epp.server.command.limit.registrantTransfer=100 + +# The maximum time spent waiting for notification that a session has been +# returned to the pool (in milliseconds). There shouldn't be any reason to +# change this value. +thread.wait.timeout=120000 + +# The session idle time after which the server will disconnect a client (in +# milliseconds). This value should be the same as that published by the +# server. +net.server.timeout=600000 + +# The effective session idle time after which the toolkit should consider a +# session inactive and close it (in milliseconds). This only makes a +# difference if a keep-alive thread is running. +net.client.timeout=12000000 + diff --git a/AusRegEPPTK/resources/aedomain-1.0.xsd b/AusRegEPPTK/resources/aedomain-1.0.xsd new file mode 100644 index 0000000..9ac7443 --- /dev/null +++ b/AusRegEPPTK/resources/aedomain-1.0.xsd @@ -0,0 +1,84 @@ + + + + + + + + + + + + .ae Domain Extensions to the Extensible + Provisioning Protocol v1.0. schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/aeext-1.0.xsd b/AusRegEPPTK/resources/aeext-1.0.xsd new file mode 100644 index 0000000..f435ca1 --- /dev/null +++ b/AusRegEPPTK/resources/aeext-1.0.xsd @@ -0,0 +1,196 @@ + + + + + + + + + + .ae Extensions to the + Extensible Provisioning Protocol v1.0 schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/ardomain-1.0.xsd b/AusRegEPPTK/resources/ardomain-1.0.xsd new file mode 100644 index 0000000..c0b63af --- /dev/null +++ b/AusRegEPPTK/resources/ardomain-1.0.xsd @@ -0,0 +1,79 @@ + + + + + + + + + AusRegistry Domain Extensions to the Extensible + Provisioning Protocol v1.0. schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/arext-1.0.xsd b/AusRegEPPTK/resources/arext-1.0.xsd new file mode 100644 index 0000000..66f977c --- /dev/null +++ b/AusRegEPPTK/resources/arext-1.0.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/audomain-1.0.xsd b/AusRegEPPTK/resources/audomain-1.0.xsd new file mode 100644 index 0000000..11f6c36 --- /dev/null +++ b/AusRegEPPTK/resources/audomain-1.0.xsd @@ -0,0 +1,72 @@ + + + + + + + + + + + .au Domain Extensions to the Extensible + Provisioning Protocol v1.0. schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/auext-1.0.xsd b/AusRegEPPTK/resources/auext-1.0.xsd new file mode 100644 index 0000000..1bfd8fb --- /dev/null +++ b/AusRegEPPTK/resources/auext-1.0.xsd @@ -0,0 +1,176 @@ + + + + + + + + + .au Extensions to the Extensible Provisioning Protocol v1.0. + schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AusRegEPPTK/resources/auext-1.1.xsd b/AusRegEPPTK/resources/auext-1.1.xsd new file mode 100644 index 0000000..57fe615 --- /dev/null +++ b/AusRegEPPTK/resources/auext-1.1.xsd @@ -0,0 +1,201 @@ + + + + + + + + + + .au Extensions to the + Extensible Provisioning + Protocol v1.1 schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/contact-1.0.xsd b/AusRegEPPTK/resources/contact-1.0.xsd new file mode 100644 index 0000000..2fdaed4 --- /dev/null +++ b/AusRegEPPTK/resources/contact-1.0.xsd @@ -0,0 +1,388 @@ + + + + + + + + + Extensible Provisioning Protocol v1.0 + contact provisioning schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/domain-1.0.xsd b/AusRegEPPTK/resources/domain-1.0.xsd new file mode 100644 index 0000000..0c50e7e --- /dev/null +++ b/AusRegEPPTK/resources/domain-1.0.xsd @@ -0,0 +1,432 @@ + + + + + + + + + + Extensible Provisioning Protocol v1.0 + domain provisioning schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/e164epp-1.0.xsd b/AusRegEPPTK/resources/e164epp-1.0.xsd new file mode 100644 index 0000000..d6430ce --- /dev/null +++ b/AusRegEPPTK/resources/e164epp-1.0.xsd @@ -0,0 +1,111 @@ + + + + + Extensible Provisioning Protocol v1.0 + domain name extension schema for E.164 number provisioning. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/epp-1.0.xsd b/AusRegEPPTK/resources/epp-1.0.xsd new file mode 100644 index 0000000..d5a8925 --- /dev/null +++ b/AusRegEPPTK/resources/epp-1.0.xsd @@ -0,0 +1,441 @@ + + + + + + + + Extensible Provisioning Protocol v1.0 schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/eppcom-1.0.xsd b/AusRegEPPTK/resources/eppcom-1.0.xsd new file mode 100644 index 0000000..3ca2655 --- /dev/null +++ b/AusRegEPPTK/resources/eppcom-1.0.xsd @@ -0,0 +1,103 @@ + + + + + Extensible Provisioning Protocol v1.0 + shared structures schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/host-1.0.xsd b/AusRegEPPTK/resources/host-1.0.xsd new file mode 100644 index 0000000..6f57833 --- /dev/null +++ b/AusRegEPPTK/resources/host-1.0.xsd @@ -0,0 +1,241 @@ + + + + + + + + + Extensible Provisioning Protocol v1.0 + host provisioning schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/idnadomain-1.0.xsd b/AusRegEPPTK/resources/idnadomain-1.0.xsd new file mode 100644 index 0000000..3cd1c68 --- /dev/null +++ b/AusRegEPPTK/resources/idnadomain-1.0.xsd @@ -0,0 +1,174 @@ + + + + + + + + + Internationalised Domain Name Extensions to the Extensible + Provisioning Protocol v1.1 schema. Domain-specific types and + attributes. + + + + + + + User and DNS presentation forms of a domain + + + + + + + This should be of type internationalisedLabelType + + + + + + + + + + + + + + + + + + + + + + + + Registration of language with IANA requires the definition + of a Script or Language Designator + (http://www.iana.org/procedures/idn-repository.html). + + The linked document above notes that Language Designators + are defined in BCP 47 + (http://www.rfc-editor.org/rfc/bcp/bcp47.txt), which + satisfies the requirements of the language datatype and + RFC3066 (BCP 47, Section 2.2.8). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Should this be moved directly into the resDataType? - assumes + that userForm of namePair is of type internationalisedLabelType + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/idnahost-1.0.xsd b/AusRegEPPTK/resources/idnahost-1.0.xsd new file mode 100644 index 0000000..f0590a4 --- /dev/null +++ b/AusRegEPPTK/resources/idnahost-1.0.xsd @@ -0,0 +1,55 @@ + + + + + + + + + Internationalised Domain Name Extensions to the Extensible + Provisioning Protocol v1.1 schema. Host-specific types and + attributes. + + + + + + Label and optional U-label + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/kv-1.0.xsd b/AusRegEPPTK/resources/kv-1.0.xsd new file mode 100644 index 0000000..451abbd --- /dev/null +++ b/AusRegEPPTK/resources/kv-1.0.xsd @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AusRegEPPTK/resources/messages.properties b/AusRegEPPTK/resources/messages.properties new file mode 100644 index 0000000..4ae4a38 --- /dev/null +++ b/AusRegEPPTK/resources/messages.properties @@ -0,0 +1,91 @@ +test.msg.1=This is a test message; do not change +UnimplementedMethodError=The method <> is deprecated. +EPPDateFormatter.readDate.0=Invalid date string specified in call to fromDateTimeString; see previous message for details. +Timer.setTime.0=Failed to set the Timer for testing; see previous message for details. +Response.fromXML.0=Failed to extract element values from EPP response; see previous message for details. +Greeting.fromXML.0=Invalid greeting received, see previous message for details. +ARSessionManager.configureSessions.0=Session initialisation failed for <> sessions. +ARSessionManager.startup.0=The session manager failed to open <> session(s). +ARSessionManager.startup.1=The session manager successfully opened <> sessions. +reconfigure.open=Failed to open a session during Session Manager reconfiguration; see previous message for details. +reconfigure.pw.change.init=Attempting to change EPP client password from <> to <>. +reconfigure.pw.change.complete=Changed EPP client password. +reconfigure.pw.change.fail=Failed to establish a session for changing the EPP client password; see previous message for details. +reconfigure.pw.change.reinit.fail=Failed to re-initialise a Session Pool after successfully changing the EPP client password; see previous message for details. +epp.session.open.fatalerr=A request for a session was unable to be serviced. This condition is expected to be persistent and require intervention; see the previous message for details. +epp.session.open.fail=The Session Manager failed to open a session; see the previous message for details. +epp.session.open.fail.limit_exceeded=The maximum number of EPP sessions allowable by the server was exceeded while trying to open <> sessions. Only <> sessions were successfully opened. +epp.session.poll.open.fail=The Session Manager was unable to poll the Registry system after repeated attempts due to failures in opening a Session; see the previous message for details. The keep-alive thread will now terminate. +epp.session.poll.cfg.fail=The Session Manager was unable to poll the Registry system due to client configuration errors; see the previous message for details. The keep-alive thread will now terminate. +epp.server.failure.retry=Login failed due to an internal server condition not related to EPP (<> times). Transaction will be retried. See the previous message for details. +epp.server.cmdfail=EPP command failed due to an internal server error. +epp.keepalive.cmdfail=Attempt to poll the Registry system for session keep-alive failed due to an internal server condition not related to EPP (<> times). Keep-alive will retry. +epp.login.fail.auth.pw=Incorrect password (<>) specified for user <>. +epp.login.fail.auth.match=client ID (<>) does not match certificate common name (<>). +epp.login.fail.loggedin=Attempted to login a session which was already logged in. The session remains logged in. +net.event.socket_closed=Failed to write to socket; already closed. +net.socket.uninitialised=Attempt to use an uninitialised Session failed; invoke Session.open() before Session.write(). +net.socket.open.fail=Failed to receive a Greeting from an EPP server on port <> of host <>. +TLSContext.createSocket.0=Fatal error: unknown_ca. The most common cause of this error is that the system trust keystore does not contain the issuer's CA certificate. If this is the case then import the appropriate CA certificate into <>/lib/security/cacerts. +ssl.cert.validity.expired=SSL Certificate has expired. Contact Registrar Support immediately for instructions on how to renew your certificate. The previous log message contains further details. +ssl.cert.validity.notyet=SSL Certificate is not yet valid. Verify that the system clock is accurate, then contact Registrar Support for further instructions, citing this message and the log message preceding this. +ssl.keystore.npe=Unexpected and unhandled failure in loading a KeyStore from the filesystem. +ssl.keystore.unrecoverable_key=The key could not be recovered from the keystore, possibly due to an incorrect passphrase being supplied for the keystore; see the previous message for further details. +ssl.keystore.initfail=The key manager factory initialisation process failed unexpectedly; see the previous message for further details. +ssl.context.getInstance.fail=Unexpected failure of SSLContext.getInstance(TLSv1). The required system libraries may not be available. See the previous message for further details. +ssl.context.init.fail=A key manager factory was loaded successfully, but initialisation of the SSL context using the key manager factory failed unexpectedly. See the previous message for details. +ssl.context.nsae=The installed security provider seems to be missing support for Transport Layer Security version 1. See the previous message for further details. +ssl.context.kme=The SSL context failed to initialise due to a key management exception. See the previous message for details. + +xml.validation.resolve.begin=Resolving URI <> using filename <>. +xml.validation.resolve.end=Resolved URI <> to file <> using relative named <>. +xml.validation.error=XML parsing/validation error at line <>, column <>. <> +xml.validation.schemaload.success=Loaded XML schema document <>. +xml.validation.schemaload.notfound=Unable to locate XML schema document file <>. +xml.validation.schemaload.ioerr=Failed to read XML schema from file <>; see previous message for details. +xml.validation.schemaload.saxerr=Failed to load XML schemas; see previous message for details. +xml.validation.source.nx=Unable to load an XML Schema Source from the specified resource; the file <> was not found in the search space. +xml.validation.schemaload.transform.disabled=Failed to locate a local resource for schema validation; schema validation will be disabled. +xml.validation.schemaload.saxerr.disabled=A source used to build a required Schema was invalid; schema validation will be disabled. +xml.datatype.config.fail.msg=Failed to load the default DatatypeFactory. Verify that the classpath includes core system libraries and that security settings permit access to the JAXP implementation libraries. +xml.dateTime.null=Attempted to parse an empty dateTime string. + +xml.writer.config.fail.msg=Failed to create an XMLWriter. Verify that the sjsxp.jar and jsr173_api.jar are in the classpath or that your Java version is >= 1.6.0. If either of these conditions are met, contact Registrar Support, citing this message and the message preceding this (logged by the maint handler). +xml.writer.process.fail.msg=An error occurred while generating the textual representation of an XML document using an XMLStreamWriter. Please send this message and the previous message (logged by the maint handler) to Registrar Support to investigate the cause. +EPPWriter.init.0=Failed to create a DocumentBuilder for building EPP documents; see previous message for details. + +xml.parser.operation.unsupported=The XML parsing implementation chosen does not support validation of XML documents using XML schemas set via DocumentBuilderFactory.setSchema; see previous message for details. +xml.parser.feature.unsupported=The XML parsing implementation chosen does not support the secure processing feature; see the previous message for details. + +file.notfound=File <> not found. +param.notnull.curExpDate=The curExpDate parameter may not be null. +thread.sleep.interrupted.ignorable=Thread interrupted while in sleep(). +thread.wakeup.info=A waiting thread awoke. +startup.interruped=Thread interruped while trying to start SessionManager. +se.object.missing_arg=Object type and object identifier(s) must be specified. +se.login.missing_arg=Username, password and EPP version must all be specified in a login command. +se.info.missing_arg=ROID and password must both be specified. +se.domain.create.missing_arg=Domain name and authorisation information are required parameters. +se.domain.create.au.missing_arg=Eligibility type and registrant name are required .au extension parameters. +se.domain.modify.au.missing_arg=Eligibility type and registrant name are required .au extension parameters. +se.domain.registrantTransfer.au.missing_arg=Eligibility type, registrant name and current expiry date are all required .au extension parameters. +se.domain.create.ae.missing_arg=Eligibility type and registrant name are required .ae extension parameters. +se.domain.modify.ae.missing_arg=Eligibility type and registrant name are required .ae extension parameters. +se.domain.registrantTransfer.ae.missing_arg=Eligibility type, registrant name and current expiry date are all required .ae extension parameters. +se.domain.renew.curExpDate.missing=The current expiry date is a required parameter. +se.domain.renew.curExpDate.missing=The current expiry date is a required parameter. +se.domain.update.name.missing=Domain name is a required parameter to identify the domain to update. +se.domain.update.sync.exDate.missing=The expiry date is a required parameter for domain expiry synchronisation. +se.command.type.missing=Command type parameter is required. +se.contact.create.missing_arg=Contact identifier, authorisation information, postal information and email address are all required contact parameters. +se.contact.update.id.missing=Contact identifier is a required parameter to identify the contact to update. +se.poll.ack.msgID.missing=The msgID is a required attribute of a message acknowledgement. +se.poll.op.missing=The op attribue is required. +se.transfer.operation.missing=The transfer operation type is required. +se.transfer.period.missing=The period to extend validity of the object by is required in this usage. +se.transfer.pw_roid.missing=An associated object's ROID and the authorisation information of that object are required. +se.transfer.pw.missing=The authorisation information of the identified object is required. +se.ar.policyDelete.missing_arg=Both name and reason must both be provided. +se.ar.domainUndelete.name.missing=Domain name must be provided. +se.ar.domainUnrenew.missing_arg=Both domain name and current expiry date must be provided. +common.exception.illegal.arg.enum=The enumeration value <> is out of range. diff --git a/AusRegEPPTK/resources/registrant-1.0.xsd b/AusRegEPPTK/resources/registrant-1.0.xsd new file mode 100644 index 0000000..1124db3 --- /dev/null +++ b/AusRegEPPTK/resources/registrant-1.0.xsd @@ -0,0 +1,71 @@ + + + + + + + + + + + + .au Domain Extensions to the Extensible + Provisioning + Protocol v1.0. schema. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/resources/secDNS-1.1.xsd b/AusRegEPPTK/resources/secDNS-1.1.xsd new file mode 100644 index 0000000..185b73a --- /dev/null +++ b/AusRegEPPTK/resources/secDNS-1.1.xsd @@ -0,0 +1,117 @@ + + + + + + Extensible Provisioning Protocol v1.0 + domain name + extension schema + for provisioning DNS security (DNSSEC) extensions. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AusRegEPPTK/resources/sync-1.0.xsd b/AusRegEPPTK/resources/sync-1.0.xsd new file mode 100644 index 0000000..8195035 --- /dev/null +++ b/AusRegEPPTK/resources/sync-1.0.xsd @@ -0,0 +1,32 @@ + + + + + + Extensible Provisioning Protocol v1.0 domain name + extension schema for expiration date synchronisation. + + + + + + + + + + + + + + + + diff --git a/AusRegEPPTK/se/AddRemType.cpp b/AusRegEPPTK/se/AddRemType.cpp new file mode 100644 index 0000000..e22b7fa --- /dev/null +++ b/AusRegEPPTK/se/AddRemType.cpp @@ -0,0 +1,31 @@ +#include "se/AddRemType.hpp" + +// Static member initialisation. +std::vector AddRemType::values; + +const AddRemType* AddRemType::ADD() +{ + static const AddRemType arm("add"); + return value("add"); +} + +const AddRemType* AddRemType::REM() +{ + static const AddRemType arm("rem"); + return value("rem"); +} + +AddRemType::AddRemType(const std::string& typeVal) + : EnumType (values, typeVal) +{ } + +const AddRemType* AddRemType::value(const std::string &name) +{ + return (const AddRemType *)EnumType::value (name, values); +} + +void AddRemType::init() +{ + ADD(); + REM(); +} diff --git a/AusRegEPPTK/se/AddRemType.hpp b/AusRegEPPTK/se/AddRemType.hpp new file mode 100644 index 0000000..6a12a2b --- /dev/null +++ b/AusRegEPPTK/se/AddRemType.hpp @@ -0,0 +1,28 @@ +#ifndef __ADDREMTYPE_HPP +#define __ADDREMTYPE_HPP + +#include "se/EnumType.hpp" + +/** + * Represents add or remove in EPP domain update commands. This is used + * internally by the DomainAdd and DomainRem classes to control the behaviour + * of their superclass DomainAddRem. + * + */ +class AddRemType : public EnumType +{ +public: + AddRemType(const std::string &typeVal); + + static const AddRemType* ADD(); + static const AddRemType* REM(); + + static const AddRemType* value(const std::string &name); + + static void init(); + +private: + static std::vector values; +}; + +#endif // __ADDREMTYPE_HPP diff --git a/AusRegEPPTK/se/AeDomainCreateCommand.cpp b/AusRegEPPTK/se/AeDomainCreateCommand.cpp new file mode 100644 index 0000000..8b146f7 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainCreateCommand.cpp @@ -0,0 +1,132 @@ +#include "se/AeDomainCreateCommand.hpp" +#include "xml/XMLHelper.hpp" +#include "se/AeExtension.hpp" +#include "common/ErrorPkg.hpp" + +namespace { + Extension& aeExtension() { + static Extension* aeExtension = new AeExtension(); + return *aeExtension; + } +}; // anonymous namespace + +AeDomainCreateCommand::AeDomainCreateCommand ( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::string &aeEligibilityType, + int aePolicyReason, + const std::string &aeRegistrantName) : DomainCreateCommand ( + name, pw, registrantID, techContacts) +{ + setExtension (aeEligibilityType, aePolicyReason, aeRegistrantName); +} + +AeDomainCreateCommand::AeDomainCreateCommand ( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::vector* adminContacts, + const std::vector* billingContacts, + const std::vector* nameservers, + const Period* period, + const std::string &aeEligibilityType, + int aePolicyReason, + const std::string &aeRegistrantName, + const std::string *aeRegistrantID, + const std::string *aeRegistrantIDType, + const std::string *aeEligibilityName, + const std::string *aeEligibilityID, + const std::string *aeEligibilityIDType) : DomainCreateCommand ( + name, pw, registrantID, techContacts, nameservers, + adminContacts, billingContacts, period) +{ + setExtension (aeEligibilityType, aePolicyReason, + aeRegistrantName, aeRegistrantID, aeRegistrantIDType, + aeEligibilityName, aeEligibilityID, aeEligibilityIDType); +} + +void AeDomainCreateCommand::setExtension (const std::string& eligibilityType, + int policyReason, + const std::string& registrantName) +{ + setExtension (eligibilityType, policyReason, registrantName, + NULL, NULL, NULL, NULL, NULL); +} + +void AeDomainCreateCommand::setExtension ( + const std::string& eligibilityType, + int policyReason, + const std::string ®istrantName, + const std::string* registrantID, + const std::string ®istrantIDType) +{ + setExtension (eligibilityType, policyReason, registrantName, + registrantID, ®istrantIDType, NULL, NULL, NULL); +} + +void AeDomainCreateCommand::setExtension ( + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType) +{ + if ((registrantID && registrantIDType == NULL) + || (registrantID == NULL && registrantIDType) + || (eligibilityID && eligibilityIDType == NULL) + || (eligibilityID == NULL && eligibilityIDType)) + { + throw IllegalArgException(ErrorPkg::getMessage( + "se.domaincreate.ae.missing_ar")); + } + + DOMElement *aeextCreate = xmlWriter->appendChild( + xmlWriter->appendChild( + command, + "extension"), + "create", + aeExtension().getURI()); + + XMLHelper::setAttribute(aeextCreate, + "xsi:schemaLocation", + aeExtension().getSchemaLocation()); + + DOMElement* aeProperties = xmlWriter->appendChild( + aeextCreate, "aeProperties"); + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "registrantName"), + registrantName); + + if (registrantID && registrantIDType) + xmlWriter->appendChild (aeProperties, + "registrantID", *registrantID, + "type", *registrantIDType); + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "eligibilityType"), + eligibilityType); + + if (eligibilityName) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "eligibilityName"), + *eligibilityName); + + if (eligibilityID && eligibilityIDType) + xmlWriter->appendChild(aeProperties, + "eligibilityID", *eligibilityID, + "type", *eligibilityIDType); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "policyReason"), + policyReason); +} + diff --git a/AusRegEPPTK/se/AeDomainCreateCommand.hpp b/AusRegEPPTK/se/AeDomainCreateCommand.hpp new file mode 100644 index 0000000..efecd96 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainCreateCommand.hpp @@ -0,0 +1,150 @@ +#ifndef __AEDOMAINCREATECOMMAND_HPP +#define __AEDOMAINCREATECOMMAND_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainCreateCommand.hpp" + +/** + * Extension of EPP urn:ietf:params:xml:ns:domain-1.0 create command specified + * in RFC3731 to urn:X-ae:params:xml:ns:aeext-1.0. .ae domains must be + * provisioned using this class rather than {@link DomainCreateCommand}, as the + * ae extension data is mandatory. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + * The response expected from a server should be handled by a {@link + * DomainCreateResponse} object. + * + * @deprecated AE eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainCreateCommand and + * appending a @c DomainKVCommandExtension object containing + * the AE eligibility extensions. + * + * See + * {@link DomainCreateCommand.appendExtension(CommandExtension)} + * and + * {@link DomainKVCommandExtension}. + */ +class AeDomainCreateCommand : public DomainCreateCommand +{ +public: + /** + * Minimal constructor for creating a domain:create + aeext:create + * EPP command. These parameters are the least required for a valid + * .ae domain create command. + */ + DEPRECATED( + AeDomainCreateCommand (const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::string &aeEligibilityType, + int aePolicyReason, + const std::string& aeRegistrantName)); + /** + * Full data specification constructor for a domain:create + aeext:create + * EPP command. Please refer to the urn:X-ae:params:xml:ns:aeext-1.0 schema + * for specification of the required fields. + * The mapping of parameter names to ae extension fields is given in the + * parameter documentation. + * + * @param name The name of the new domain. + * + * @param pw The password to assign to the domain (also known as authInfo + * or authorisation information). + * + * @param registrantID The identifier of an existing contact to assign as + * the registrant contact for this domain. Failure to ensure the contact + * exists prior to using them in this way will result in an EPP result of + * '2303 "Object does not exist"'. + * + * @param techContacts The identifiers of existing contacts to assign as + * technical contacts for this domain. Failure to ensure the contacts + * exist prior to using them in this way will result in an EPP result of + * '2303 "Object does not exist"'. + * + * @param adminContacts See techContacts (substitute administrative for + * technical). + * + * @param billingContacts See techContacts (substitute billing for + * technical). + * + * @param nameservers The names of existing hosts to delegate the domain + * being created to. Failure to ensure the hosts exist prior to using them + * in this way will result in an EPP result of '2303 "Object does not + * exist"'. + * + * @param period The initial registration period of the domain object. A + * server may define a default initial registration period if not specified + * by the client. + * + * @param aeEligibilityType aeext:eligType. + * + * @param aePolicyReason aeext:policyReason. + * + * @param aeRegistrantName aeext:registrantName. + * + * @param aeRegistrantID aeext:registrantID. + * + * @param aeRegistrantIDType aeext:registrantID type attribute. + * + * @param aeEligibilityName aeext:eligibilityName. + * + * @param aeEligibilityID aeext:eligibilityID. + * + * @param aeEligibilityIDType aeext:eligibilityID type attribute. + */ + DEPRECATED( + AeDomainCreateCommand (const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::vector* adminContacts, + const std::vector* billingContacts, + const std::vector* nameservers, + const Period *period, + const std::string &aeEligibilityType, + int aePolicyReason, + const std::string& aeRegistrantName, + const std::string* aeRegistrantID, + const std::string* aeRegistrantIDType, + const std::string* aeEligibilityName, + const std::string* aeEligibilityID, + const std::string* aeEligibilityIDType)); +private: + void setExtension (const std::string& eligibilityType, + int PolicyReason, + const std::string& registrantName); + + void setExtension (const std::string& eligibilityType, + int PolicyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string& registrantIDType); + + /** + * <extension> + *  <create xmlns="urn:X-ae:params:xml:ns:aeext-1.0"> + *   <registrantName>registrantName</registrantName> + *   <registrantID type="registrantIDType">registrantID</registrantID> + *   <eligibilityType>eligibilityType</eligibilityType> + *   <eligibilityName>eligibilityName</eligibilityName> + *   <eligibilityID type="eligibilityIDType">eligibilityID</eligibilityID> + *   <policyReason>policyReason</policyReason> + *  </create> + * </extension> + */ + void setExtension (const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType); +}; + + +#endif // __AEDOMAINCREATECOMMAND_HPP diff --git a/AusRegEPPTK/se/AeDomainCreateCommandTest.cpp b/AusRegEPPTK/se/AeDomainCreateCommandTest.cpp new file mode 100644 index 0000000..7414bfa --- /dev/null +++ b/AusRegEPPTK/se/AeDomainCreateCommandTest.cpp @@ -0,0 +1,86 @@ +#include "se/ContactCheckCommand.hpp" +#include "se/AeDomainCreateCommand.hpp" +#include "se/CLTRID.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string registrantName = "AusRegistry"; + const string registrantID = "01241326211"; + const string registrantIDType = "Trade License"; + const string eligibilityType = "Trade License (IT)"; + const int policyReason = 1; + const string eligibilityName = "Blah"; + const string eligibilityID = "1231239523"; + const string eligibilityIDType = "Trademark"; + + /** + * Test that the XML string generated for a minimal create domain command + * matches the expected XML for an EPP create domain command with those + * parameters. + */ + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + vector techIds; + techIds.push_back("JTKCON2"); + string registrant("JTKCON"); + AeDomainCreateCommand cmd("jtkutest.co.ae", "jtkUT3st", ®istrant, &techIds, + eligibilityType, policyReason, registrantName); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, + "jtkutest.co.aeJTKCONJTKCON2jtkUT3stAusRegistryTrade License (IT)1JTKUTEST.20070101.010101.0"); + } + + /** + * Test that the XML string generated for a sample create domain command + * specified with all available parameters matches the expected XML for + * an EPP create domain command with those parameters. + * + */ + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + vector techIds; + techIds.push_back("JTKCON2"); + + vector adminContacts; + adminContacts.push_back("JTKCON"); + adminContacts.push_back("JTKCON2"); + + string registrant("JTKCON"); + + vector nameServers; + nameServers.push_back("ns1.ausregistry.net"); + nameServers.push_back("ns2.ausregistry.net"); + + Period period(48, PeriodUnit::MONTHS()); + + AeDomainCreateCommand cmd( + "jtkutest.co.ae", "jtkUT3st", ®istrant, + &techIds, &adminContacts, + NULL, &nameServers, &period, + eligibilityType, policyReason, + registrantName, ®istrantID, + ®istrantIDType, &eligibilityName, + &eligibilityID, &eligibilityIDType); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.co.ae48ns1.ausregistry.netns2.ausregistry.netJTKCONJTKCONJTKCON2JTKCON2jtkUT3stAusRegistry01241326211Trade License (IT)Blah12312395231JTKUTEST.20070101.010101.0"); + + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/AeDomainInfoResponse.cpp b/AusRegEPPTK/se/AeDomainInfoResponse.cpp new file mode 100644 index 0000000..a929425 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainInfoResponse.cpp @@ -0,0 +1,57 @@ +#include "se/AeDomainInfoResponse.hpp" +#include "se/StandardObjectType.hpp" + +#include // atoi() + +using namespace std; + +const std::string AeDomainInfoResponse::AEEXT_EXPR(Response::RESPONSE_EXPR() + "/e:extension/aeext:infData"); +const std::string AeDomainInfoResponse::AE_PROPERTIES_EXPR(AeDomainInfoResponse::AEEXT_EXPR + "/aeext:aeProperties"); +const std::string AeDomainInfoResponse::AE_REGISTRANT_NAME_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:registrantName/text()"); +const std::string AeDomainInfoResponse::AE_REGISTRANT_ID_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:registrantID/text()"); +const std::string AeDomainInfoResponse::AE_REGISTRANT_ID_TYPE_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:registrantID/@type"); +const std::string AeDomainInfoResponse::AE_ELI_TYPE_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:eligibilityType/text()"); +const std::string AeDomainInfoResponse::AE_ELI_NAME_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:eligibilityName/text()"); +const std::string AeDomainInfoResponse::AE_ELI_ID_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:eligibilityID/text()"); +const std::string AeDomainInfoResponse::AE_ELI_ID_TYPE_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:eligibilityID/@type"); +const std::string AeDomainInfoResponse::AE_POLICY_REASON_EXPR(AeDomainInfoResponse::AE_PROPERTIES_EXPR + "/aeext:policyReason/text()"); + + + +AeDomainInfoResponse::AeDomainInfoResponse() : DomainInfoResponse() +{ + policyReason = 0; +} + +void AeDomainInfoResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + DomainInfoResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + registrantName = xmlDoc->getNodeValue (AE_REGISTRANT_NAME_EXPR); + registrantID = xmlDoc->getNodeValue (AE_REGISTRANT_ID_EXPR); + registrantIDType = xmlDoc->getNodeValue (AE_REGISTRANT_ID_TYPE_EXPR); + eligibilityType = xmlDoc->getNodeValue (AE_ELI_TYPE_EXPR); + eligibilityName = xmlDoc->getNodeValue (AE_ELI_NAME_EXPR); + eligibilityID = xmlDoc->getNodeValue (AE_ELI_ID_EXPR); + eligibilityIDType = xmlDoc->getNodeValue (AE_ELI_ID_TYPE_EXPR); + + string polReasonStr = xmlDoc->getNodeValue (AE_POLICY_REASON_EXPR); + if (polReasonStr.length() > 0) { + policyReason = atoi (polReasonStr.c_str()); + } + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe("Could not parse AeDomainInfoResponse object."); + pe.causedBy(e); + throw pe; + } +} + diff --git a/AusRegEPPTK/se/AeDomainInfoResponse.hpp b/AusRegEPPTK/se/AeDomainInfoResponse.hpp new file mode 100644 index 0000000..2e2378d --- /dev/null +++ b/AusRegEPPTK/se/AeDomainInfoResponse.hpp @@ -0,0 +1,72 @@ +#ifndef __AE_DOMAIN_INFO_RESPONSE_HPP +#define __AE_DOMAIN_INFO_RESPONSE_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainInfoResponse.hpp" + +#include + +/** + * Extension of the domain mapping of the EPP info response, as defined in + * RFC3730 and RFC3731, to .ae domain names, the specification of which is in + * the XML schema definition urn:X-ae:params:xml:ns:aeext-1.0. + * Instances of this class provide an interface to access all of the + * information available through EPP for a .ae domain name. + * This relies on the instance first being initialised by a suitable EPP domain + * info response using the method fromXML. For flexibility, this + * implementation extracts the data from the response using XPath queries, the + * expressions for which are defined statically. + + * @deprecated AE eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainInfoResponse and + * registering a @c DomainInfoKVResponseExtension object, which + * will contain the AE eligibility extensions. + * + * See + * {@link DomainInfoResponse.registerExtension(ResponseExtension)} + * and + * {@link DomainInfoKVResponseExtension}. + */ +class AeDomainInfoResponse : public DomainInfoResponse +{ +public: + DEPRECATED(AeDomainInfoResponse()); + + const std::string& getRegistrantName() const { return registrantName; }; + const std::string& getAERegistrantID() const { return registrantID; }; + const std::string& getRegistrantIDType() const { return registrantIDType; }; + const std::string& getEligibilityType() const { return eligibilityType; }; + const std::string& getEligibilityName() const { return eligibilityName; }; + const std::string& getEligibilityID() const { return eligibilityID; }; + const std::string& getEligibilityIDType() const { return eligibilityIDType; }; + int getPolicyReason() const { return policyReason; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +private: + static const std::string AEEXT_EXPR, + AE_PROPERTIES_EXPR, + AE_REGISTRANT_NAME_EXPR, + AE_REGISTRANT_ID_EXPR, + AE_REGISTRANT_ID_TYPE_EXPR, + AE_ELI_TYPE_EXPR, + AE_ELI_NAME_EXPR, + AE_ELI_ID_EXPR, + AE_ELI_ID_TYPE_EXPR, + AE_POLICY_REASON_EXPR; + + std::string registrantName, + registrantID, + registrantIDType, + eligibilityType, + eligibilityName, + eligibilityID, + eligibilityIDType; + + int policyReason; +}; + +#endif // __AE_DOMAIN_INFO_RESPONSE_HPP + diff --git a/AusRegEPPTK/se/AeDomainModifyRegistrantCommand.cpp b/AusRegEPPTK/se/AeDomainModifyRegistrantCommand.cpp new file mode 100644 index 0000000..db10b91 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainModifyRegistrantCommand.cpp @@ -0,0 +1,93 @@ +#include "se/AeDomainModifyRegistrantCommand.hpp" +#include "common/ErrorPkg.hpp" +#include "se/AeExtension.hpp" +#include "xml/XMLHelper.hpp" + +namespace { + AeExtension& aeExtension() { + static AeExtension* aeExtension = new AeExtension(); + return *aeExtension; + } +}; // anonymous namespace + +AeDomainModifyRegistrantCommand::AeDomainModifyRegistrantCommand( + const std::string& name, + const std::string& registrantName, + const std::string& explanation, + const std::string* eligibilityType, + int policyReason, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType) : DomainUpdateCommand(name) +{ + if (eligibilityType == NULL + || (registrantID == NULL && registrantIDType != NULL) + || (registrantID != NULL && registrantIDType == NULL) + || (eligibilityID == NULL && eligibilityIDType != NULL) + || (eligibilityID != NULL && eligibilityIDType == NULL)) + { + throw IllegalArgException( + ErrorPkg::getMessage("se.domain.modify.ae.missing_arg")); + } + + DOMElement* aeextUpdate = xmlWriter->appendChild( + xmlWriter->appendChild(command, "extension"), + "update", + aeExtension().getURI()); + + aeextUpdate->setAttribute( + XStr("xsi:schemaLocation").str(), + XStr(aeExtension().getSchemaLocation()).str()); + + DOMElement* aeProperties = xmlWriter->appendChild(aeextUpdate, + "aeProperties"); + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "registrantName"), + registrantName); + + if (registrantID != NULL && registrantIDType != NULL) + { + xmlWriter->appendChild( + aeProperties, + "registrantID", + *registrantID, + "type", + *registrantIDType); + } + + if (eligibilityType != NULL) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "eligibilityType"), + *eligibilityType); + } + + if (eligibilityName != NULL) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "eligibilityName"), + *eligibilityName); + } + + if (eligibilityID != NULL && eligibilityIDType != NULL) + { + xmlWriter->appendChild( + aeProperties, + "eligibilityID", + *eligibilityID, + "type", + *eligibilityIDType); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "policyReason"), + policyReason); + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeextUpdate, "explanation"), + explanation); +} + diff --git a/AusRegEPPTK/se/AeDomainModifyRegistrantCommand.hpp b/AusRegEPPTK/se/AeDomainModifyRegistrantCommand.hpp new file mode 100644 index 0000000..f67f0a0 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainModifyRegistrantCommand.hpp @@ -0,0 +1,46 @@ +#ifndef __AE_DOMAIN_MODIFY_REGISTRANT_COMMAND_HPP +#define __AE_DOMAIN_MODIFY_REGISTRANT_COMMAND_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainUpdateCommand.hpp" + +/** + * An extension of the domain mapping of the EPP update command, as defined in + * RFC3730 and RFC3731, to .ae domain names, the specification of which is in + * the XML schema definition urn:X-ae:params:xml:ns:aeext-1.0. + * This class should only be used to correct ae extension data for .ae domain + * names, and only where the legal registrant has not changed. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + * + * @deprecated AE eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainUpdateCommand and + * appending a @c DomainKVCommandExtension object containing + * the AE eligibility extensions. + * + * See + * {@link DomainUpdateCommand.appendExtension(CommandExtension)} + * and + * {@link DomainKVCommandExtension}. + */ +class AeDomainModifyRegistrantCommand : public DomainUpdateCommand +{ +public: + DEPRECATED( + AeDomainModifyRegistrantCommand(const std::string& name, + const std::string& registrantName, + const std::string& explanation, + const std::string* eligibilityType = NULL, + int policyReason = 0, + const std::string* registrantID = NULL, + const std::string* registrantIDType = NULL, + const std::string* eligibilityName = NULL, + const std::string* eligibilityID = NULL, + const std::string* eligibilityIDType = NULL)); +}; + +#endif // __AE_DOMAIN_MODIFY_REGISTRANT_COMMAND_HPP + diff --git a/AusRegEPPTK/se/AeDomainObjectType.cpp b/AusRegEPPTK/se/AeDomainObjectType.cpp new file mode 100644 index 0000000..718cb60 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainObjectType.cpp @@ -0,0 +1,25 @@ +#include "AeDomainObjectType.hpp" + +#include + +const std::string& AeDomainObjectType::getName() const { + static const std::string name = "aedom"; + return name; +} + +const std::string& AeDomainObjectType::getURI() const { + static const std::string uri = "urn:X-ae:params:xml:ns:aedomain-1.0"; + return uri; +} + +const std::string& AeDomainObjectType::getSchemaLocation() const { + static const std::string schemaLocation = + "urn:X-ae:params:xml:ns:aedomain-1.0 aedomain-1.0.xsd"; + return schemaLocation; +} + +const std::string& AeDomainObjectType::getIdentType() const { + static const std::string ident = "name"; + return ident; +} + diff --git a/AusRegEPPTK/se/AeDomainObjectType.hpp b/AusRegEPPTK/se/AeDomainObjectType.hpp new file mode 100644 index 0000000..38485a5 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainObjectType.hpp @@ -0,0 +1,19 @@ +#ifndef AEDOMAIN_OBJECT_TYPE +#define AEDOMAIN_OBJECT_TYPE + +#include "ObjectType.hpp" + +#include + +class AeDomainObjectType : public ObjectType { +public: + virtual ~AeDomainObjectType(void) { } + + virtual const std::string& getName() const; + virtual const std::string& getURI() const; + virtual const std::string& getSchemaLocation() const; + virtual const std::string& getIdentType() const; +}; + +#endif // AEDOMAIN_OBJECT_TYPE + diff --git a/AusRegEPPTK/se/AeDomainTransferRegistrantCommand.cpp b/AusRegEPPTK/se/AeDomainTransferRegistrantCommand.cpp new file mode 100644 index 0000000..85fe3be --- /dev/null +++ b/AusRegEPPTK/se/AeDomainTransferRegistrantCommand.cpp @@ -0,0 +1,92 @@ +#include "se/AeDomainTransferRegistrantCommand.hpp" +#include "se/XMLGregorianCalendar.hpp" + +#include "se/AeExtension.hpp" +#include "se/AeDomainObjectType.hpp" +#include "se/RegistrantTransferCommandType.hpp" +#include "se/CommandType.hpp" +#include "se/Period.hpp" +#include "common/ErrorPkg.hpp" + +#include "se/EPPDateFormatter.hpp" + +#include "xml/XMLHelper.hpp" + +namespace { + Extension& aeExtension() { + static Extension* aeExt = new AeExtension(); + return *aeExt; + } + + const RegistrantTransferCommandType rtrnType; + const AeDomainObjectType aedomType; +} // anonymous namespace + +AeDomainTransferRegistrantCommand::AeDomainTransferRegistrantCommand ( + const std::string& name, + const XMLGregorianCalendar& curExpDate, + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string& explanation, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType, + const Period* period) : ProtocolExtensionCommand( + &rtrnType, &aedomType, name, aeExtension()) +{ + if ((registrantID && registrantIDType == NULL) + || (registrantIDType == NULL && registrantIDType) + || (eligibilityName && (eligibilityID == NULL || eligibilityIDType == NULL)) + || (eligibilityName == NULL && (eligibilityID || eligibilityIDType))) + { + // If provided, a registrantID must have a type. + // If provided, an eligibilityName must have both an eligibilityID and type. + throw IllegalArgException( + ErrorPkg::getMessage("se.domain.registrantTransfer.ae.missing_arg")); + } + + DOMElement *element; + + std::string curExpDateStr = EPPDateFormatter::toXSDate(curExpDate); + XMLHelper::setTextContent( + xmlWriter->appendChild(objElement, "curExpDate"), curExpDateStr); + + if (period) + period->appendPeriod(xmlWriter, objElement); + + DOMElement *aeProperties = xmlWriter->appendChild(objElement, "aeProperties"); + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "registrantName"), registrantName); + + if (registrantID) + { + element = xmlWriter->appendChild(aeProperties, "registrantID"); + XMLHelper::setTextContent(element, *registrantID); + XMLHelper::setAttribute(element, "type", *registrantIDType); + } + XMLHelper::setTextContent + (xmlWriter->appendChild(aeProperties, "eligibilityType"), eligibilityType); + + if (eligibilityName) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "eligibilityName"), *eligibilityName); + + element = xmlWriter->appendChild(aeProperties, "eligibilityID"); + XMLHelper::setTextContent(element, *eligibilityID); + XMLHelper::setAttribute(element, "type", *eligibilityIDType); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(aeProperties, "policyReason"), + policyReason); + + XMLHelper::setTextContent( + xmlWriter->appendChild(objElement, "explanation"), + explanation); +} + diff --git a/AusRegEPPTK/se/AeDomainTransferRegistrantCommand.hpp b/AusRegEPPTK/se/AeDomainTransferRegistrantCommand.hpp new file mode 100644 index 0000000..c85a161 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainTransferRegistrantCommand.hpp @@ -0,0 +1,88 @@ +#ifndef __AE_DOMAIN_TRANSFER_REGISTRANT_COMMAND_HPP +#define __AE_DOMAIN_TRANSFER_REGISTRANT_COMMAND_HPP + +#include "common/Deprecated.hpp" +#include "se/ProtocolExtensionCommand.hpp" +class XMLGregorianCalendar; +class Period; + +/** + * In cases where the legal registrant of a .ae domain name has changed, this + * class should be used to request a transfer of registrant. This is a + * different action to correcting extension data which was originally specified + * incorrectly, and should only be used in the situation described. This + * command will result in the validity period of the domain name being updated + * and the requesting client being charged the usual create fee upon success of + * this operation. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + + * @deprecated AE eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. The Registrant + * Transfer command that utilises this extension is defined in the + * urn:X-ar:params:xml:ns:registrant-1.0 namespace. This can + * be done through the toolkit by using a + * @c DomainRegistrantTransferCommand and specifying + * @c "ae" as the kvListName. + * + * See + * {@link DomainRegistrantTransferCommand} + * and + * {@link DomainRegistrantTransferCommand.addItem(std::string, std::string)} + */ +class AeDomainTransferRegistrantCommand : public ProtocolExtensionCommand +{ +public: + + /** + * Request that the named .ae domain name be transferred to the legal + * entity specified by the given ae extension data. + * + * @param name The domain name to transfer. + * + * @param curExpDate The current expiry of the identified domain name. + * This is required in order to prevent repeated transfer of the name due + * to protocol transmission failures. + * + * @param eligibilityType + * + * @param policyReason + * + * @param registrantName + * + * @param explanation An explanation of how the transfer was effected. + * + * @param registrantID + * + * @param registrantIDType + * + * @param eligibilityName + * + * @param eligibilityID + * + * @param eligibilityIDType + * + * @param period The desired new validity period, starting from the time + * the transfer completes successfully. + * + * @param explanation An explanation of how the transfer was effected. + */ + DEPRECATED( + AeDomainTransferRegistrantCommand (const std::string& name, + const XMLGregorianCalendar& curExpDate, + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string& explanation, + const std::string* registrantID = NULL, + const std::string* registrantIDType = NULL, + const std::string* eligibilityName = NULL, + const std::string* eligibilityID = NULL, + const std::string* eligibilityIDType = NULL, + const Period* period = NULL)); +}; + +#endif // __AE_DOMAIN_TRANSFER_REGISTRANT_COMMAND_HPP + diff --git a/AusRegEPPTK/se/AeDomainTransferRegistrantResponse.cpp b/AusRegEPPTK/se/AeDomainTransferRegistrantResponse.cpp new file mode 100644 index 0000000..9aac8f7 --- /dev/null +++ b/AusRegEPPTK/se/AeDomainTransferRegistrantResponse.cpp @@ -0,0 +1,37 @@ +#include "se/AeDomainTransferRegistrantResponse.hpp" +#include "se/AeDomainObjectType.hpp" +#include "se/RegistrantTransferCommandType.hpp" +#include "se/EPPDateFormatter.hpp" + +namespace { + const RegistrantTransferCommandType rtrnType; + const AeDomainObjectType aedomType; +} // anonymous namespace + +using namespace std; + +const string AeDomainTransferRegistrantResponse::AEDOM_NAME_EXPR = + "/e:epp/e:response/e:resData/aedom:rtrnData/aedom:name/text()"; + +const string AeDomainTransferRegistrantResponse::AEDOM_EX_DATE_EXPR = + "/e:epp/e:response/e:resData/aedom:rtrnData/aedom:exDate/text()"; + +AeDomainTransferRegistrantResponse::AeDomainTransferRegistrantResponse() + : DataResponse(&rtrnType, &aedomType) +{ +} + +void AeDomainTransferRegistrantResponse::fromXML(XMLDocument* xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + name = xmlDoc->getNodeValue(AEDOM_NAME_EXPR); + std::string exDateStr = xmlDoc->getNodeValue(AEDOM_EX_DATE_EXPR); + exDate = std::auto_ptr( + EPPDateFormatter::fromXSDateTime(exDateStr)); +} + diff --git a/AusRegEPPTK/se/AeDomainTransferRegistrantResponse.hpp b/AusRegEPPTK/se/AeDomainTransferRegistrantResponse.hpp new file mode 100644 index 0000000..3dd97cc --- /dev/null +++ b/AusRegEPPTK/se/AeDomainTransferRegistrantResponse.hpp @@ -0,0 +1,44 @@ +#ifndef __AE_DOMAIN_TRANSFER_REGISTRANT_RESPONSE +#define __AE_DOMAIN_TRANSFER_REGISTRANT_RESPONSE + +#include "common/Deprecated.hpp" +#include "se/DataResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +/** + * Use this to access create data for a domain as provided in an EPP domain + * create response compliant with RFCs 3730 and 3731. Such a service element + * is sent by a compliant EPP server in response to a valid domain create + * command, implemented by the DomainCreateCommand. + * + * @see DomainCreateCommand + + * @deprecated Performing a registrant transfer with AE eligibility extensions + * should now be managed through the use of the + * @c DomainRegistrantTransferCommand and + * @c DomainRegistrantTransferResponse + * + * See + * {@link DomainRegistrantTransferCommand} + * and + * {@link DomainRegistrantTransferResponse}. + */ +class AeDomainTransferRegistrantResponse : public DataResponse +{ +public: + DEPRECATED(AeDomainTransferRegistrantResponse()); + + const std::string& getName() { return name; } + const XMLGregorianCalendar* getExpiryDate() { return exDate.get(); } + void fromXML(XMLDocument* xmlDoc) throw (ParsingException); + +private: + static const std::string AEDOM_NAME_EXPR; + static const std::string AEDOM_EX_DATE_EXPR; + + std::string name; + std::auto_ptr exDate; +}; + +#endif // __AE_DOMAIN_TRANSFER_REGISTRANT_RESPONSE + diff --git a/AusRegEPPTK/se/AeExtension.cpp b/AusRegEPPTK/se/AeExtension.cpp new file mode 100644 index 0000000..ceb46bf --- /dev/null +++ b/AusRegEPPTK/se/AeExtension.cpp @@ -0,0 +1,14 @@ +#include "se/AeExtension.hpp" + +std::string& AeExtension::getURI() const +{ + static std::string uri = "urn:X-ae:params:xml:ns:aeext-1.0"; + return uri; +} + +std::string& AeExtension::getSchemaLocation() const +{ + static std::string loc = "urn:X-ae:params:xml:ns:aeext-1.0 aeext-1.0.xsd"; + return loc; +} + diff --git a/AusRegEPPTK/se/AeExtension.hpp b/AusRegEPPTK/se/AeExtension.hpp new file mode 100644 index 0000000..6c8b529 --- /dev/null +++ b/AusRegEPPTK/se/AeExtension.hpp @@ -0,0 +1,29 @@ +#ifndef __AEEXTENSION_HPP +#define __AEEXTENSION_HPP + +#include "se/Extension.hpp" + +/** + * A bundled set of constants representing the .ae EPP extension + * schema. The namespace URI uniquely identifies the extension. + */ +class AeExtension : public Extension +{ +public: + + virtual ~AeExtension(void) { } + + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __AEEXTENSION_HPP + diff --git a/AusRegEPPTK/se/Appendable.hpp b/AusRegEPPTK/se/Appendable.hpp new file mode 100644 index 0000000..ce39bfb --- /dev/null +++ b/AusRegEPPTK/se/Appendable.hpp @@ -0,0 +1,27 @@ +#ifndef __APPENDABLE_HPP +#define __APPENDABLE_HPP + +#include +class XMLWriter; + +/** + * Implementors of this interface provide a mechanism for building the part of + * the service element DOM tree that they represent. This should only be + * implemented by developers wishing to extend the command / response framework + * of EPP. + */ +class Appendable +{ +public: + virtual ~Appendable(void) { } + /** + * Used internally for building a DOM representation of a service element. + * This really should not be exposed to the end user, but Java has no + * package-visible interface type. + */ + virtual xercesc::DOMElement* appendToElement( + XMLWriter* xmlWriter, + xercesc::DOMElement* parent) const = 0; +}; + +#endif // __APPENDABLE_HPP diff --git a/AusRegEPPTK/se/ArDomainObjectType.cpp b/AusRegEPPTK/se/ArDomainObjectType.cpp new file mode 100644 index 0000000..a604a90 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainObjectType.cpp @@ -0,0 +1,25 @@ +#include + +#include "ArDomainObjectType.hpp" + +const std::string & ArDomainObjectType::getName() const { + static const std::string name = "ardom"; + return name; +} + +const std::string & ArDomainObjectType::getURI() const { + static const std::string uri = "urn:X-ar:params:xml:ns:ardomain-1.0"; + return uri; +} + +const std::string & ArDomainObjectType::getSchemaLocation() const { + static const std::string schemaLocation = + "urn:X-ar:params:xml:ns:ardomain-1.0 ardomain-1.0.xsd"; + return schemaLocation; +} + +const std::string & ArDomainObjectType::getIdentType() const { + static const std::string ident = "name"; + return ident; +} + diff --git a/AusRegEPPTK/se/ArDomainObjectType.hpp b/AusRegEPPTK/se/ArDomainObjectType.hpp new file mode 100644 index 0000000..0c30376 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainObjectType.hpp @@ -0,0 +1,17 @@ +#ifndef ARDOMAIN_OBJECT_TYPE +#define ARDOMAIN_OBJECT_TYPE + +#include "ObjectType.hpp" + +#include + +class ArDomainObjectType : public ObjectType { +public: + virtual const std::string& getName() const; + virtual const std::string& getURI() const; + virtual const std::string& getSchemaLocation() const; + virtual const std::string& getIdentType() const; +}; + +#endif // ARDOMAIN_OBJECT_TYPE + diff --git a/AusRegEPPTK/se/ArDomainPolicyDeleteCommand.cpp b/AusRegEPPTK/se/ArDomainPolicyDeleteCommand.cpp new file mode 100644 index 0000000..0b479b0 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainPolicyDeleteCommand.cpp @@ -0,0 +1,35 @@ +#include "se/ArDomainPolicyDeleteCommand.hpp" +#include "se/ArExtension.hpp" +#include "se/ArDomainObjectType.hpp" +#include "se/CommandType.hpp" +#include "se/Extension.hpp" +#include "xml/XMLHelper.hpp" + +#include + +namespace { + class ArDomainPolicyDeleteCommandType : public CommandType + { + public: + ArDomainPolicyDeleteCommandType() : CommandType(getCommandName()) { } + std::string getCommandName() const { return "policyDelete"; } + std::string toString() const { return "policyDelete"; } + }; + + Extension& arExtension() { + static Extension* arExt = new ArExtension(); + return *arExt; + } + + const ArDomainPolicyDeleteCommandType polDeleteCmdType; + const ArDomainObjectType ardomType; +}; // anonymous namespace + +ArDomainPolicyDeleteCommand::ArDomainPolicyDeleteCommand ( + const std::string &name, const std::string &reason) : ProtocolExtensionCommand( + &polDeleteCmdType, &ardomType, name, arExtension()) +{ + XMLHelper::setTextContent( + xmlWriter->appendChild(objElement, "reason"), reason); +} + diff --git a/AusRegEPPTK/se/ArDomainPolicyDeleteCommand.hpp b/AusRegEPPTK/se/ArDomainPolicyDeleteCommand.hpp new file mode 100644 index 0000000..9db05d0 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainPolicyDeleteCommand.hpp @@ -0,0 +1,28 @@ +#ifndef __AR_DOMAIN_POLICY_DELETE_COMMAND_HPP +#define __AR_DOMAIN_POLICY_DELETE_COMMAND_HPP + +#include "se/Extension.hpp" +#include "se/ProtocolExtensionCommand.hpp" + +/** + * Mapping of EPP urn:ar:params:xml:ns:arext-1.0 policyDelete command specified + * by the AusRegistry EPP extensions document. This should be used to delete + * domains violating relevant policy, rather than at the request of the + * registrant. + * Use this class to generate an AusRegistry-compliant XML document, given + * simple input parameters. The toXML method in Command serialises this object + * to XML. + */ +class ArDomainPolicyDeleteCommand : public ProtocolExtensionCommand +{ +public: + ArDomainPolicyDeleteCommand ( + const std::string &name, + const std::string &reason); + +private: + Extension& getExtension() const; +}; + +#endif // __AR_DOMAIN_POLICY_DELETE_COMMAND_HPP + diff --git a/AusRegEPPTK/se/ArDomainPolicyDeleteCommandTest.cpp b/AusRegEPPTK/se/ArDomainPolicyDeleteCommandTest.cpp new file mode 100644 index 0000000..6f5a93f --- /dev/null +++ b/AusRegEPPTK/se/ArDomainPolicyDeleteCommandTest.cpp @@ -0,0 +1,29 @@ +#include "se/ArDomainPolicyDeleteCommand.hpp" +#include "se/CLTRID.hpp" +#include "common/init.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + ArDomainPolicyDeleteCommand cmd("jtkutest.com.au", "jtkutest"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.aujtkutestJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.cpp b/AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.cpp new file mode 100644 index 0000000..ae1043e --- /dev/null +++ b/AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.cpp @@ -0,0 +1,31 @@ +#include "se/ArDomainPolicyUndeleteCommand.hpp" +#include "se/ArExtension.hpp" +#include "se/ArDomainObjectType.hpp" +#include "se/CommandType.hpp" +#include "xml/XMLHelper.hpp" +#include "xml/XStr.hpp" + +namespace { + class ArPolicyUndeleteCommandType : public CommandType + { + public: + ArPolicyUndeleteCommandType() : CommandType(getCommandName()) { } + std::string getCommandName() const { return "policyUndelete"; } + std::string toString() const { return "policyUndelete"; } + }; + + Extension& arExtension() { + static Extension* arExt = new ArExtension(); + return *arExt; + } + + const ArPolicyUndeleteCommandType polUndeleteCmdType; + const ArDomainObjectType ardomType; +}; // anonymous namespace + +ArDomainPolicyUndeleteCommand::ArDomainPolicyUndeleteCommand( + const std::string &name) : ProtocolExtensionCommand( + &polUndeleteCmdType, &ardomType, name, arExtension()) +{ +} + diff --git a/AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.hpp b/AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.hpp new file mode 100644 index 0000000..cb3ccb8 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainPolicyUndeleteCommand.hpp @@ -0,0 +1,22 @@ +#ifndef __AR_DOMAIN_POLICY_UNDELETE_COMMAND_HPP +#define __AR_DOMAIN_POLICY_UNDELETE_COMMAND_HPP + +#include "se/ProtocolExtensionCommand.hpp" + +/** + * Mapping of EPP urn:ar:params:xml:ns:arext-1.0 policy domainUndelete command + * specified by the AusRegistry EPP extensions document. This should only be + * used to request undeletion of domains which have been deleted due to policy + * violation using the policy delete operation. + * Use this class to generate an AusRegistry-compliant XML document, given + * simple input parameters. The toXML method in Command serialises this object + * to XML. + */ +class ArDomainPolicyUndeleteCommand : public ProtocolExtensionCommand +{ +public: + ArDomainPolicyUndeleteCommand(const std::string &name); +}; + +#endif // __AR_DOMAIN_POLICY_UNDELETE_COMMAND_HPP + diff --git a/AusRegEPPTK/se/ArDomainPolicyUndeleteCommandTest.cpp b/AusRegEPPTK/se/ArDomainPolicyUndeleteCommandTest.cpp new file mode 100644 index 0000000..4b06e39 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainPolicyUndeleteCommandTest.cpp @@ -0,0 +1,29 @@ +#include "se/ArDomainPolicyUndeleteCommand.hpp" +#include "se/CLTRID.hpp" +#include "common/init.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + ArDomainPolicyUndeleteCommand cmd("jtkutest.com.au"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/ArDomainUndeleteCommand.cpp b/AusRegEPPTK/se/ArDomainUndeleteCommand.cpp new file mode 100644 index 0000000..4885910 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUndeleteCommand.cpp @@ -0,0 +1,32 @@ +#include "se/ArDomainUndeleteCommand.hpp" + +#include "se/ArExtension.hpp" +#include "se/ArDomainObjectType.hpp" +#include "se/CommandType.hpp" +#include "xml/XMLHelper.hpp" +#include "xml/XStr.hpp" + +namespace { + class ArUndeleteCommandType : public CommandType + { + public: + ArUndeleteCommandType() : CommandType (getCommandName()) {} + std::string getCommandName() const { return "undelete"; } + std::string toString() const { return "undelete"; } + }; + + Extension& arExtension() { + static Extension* arExt = new ArExtension(); + return *arExt; + } + + const ArUndeleteCommandType undeleteCmdType; + const ArDomainObjectType ardomType; +}; // anonymous namespace + +ArDomainUndeleteCommand::ArDomainUndeleteCommand( + const std::string &name) : ProtocolExtensionCommand( + &undeleteCmdType, &ardomType, name, arExtension()) +{ +} + diff --git a/AusRegEPPTK/se/ArDomainUndeleteCommand.hpp b/AusRegEPPTK/se/ArDomainUndeleteCommand.hpp new file mode 100644 index 0000000..f2b9357 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUndeleteCommand.hpp @@ -0,0 +1,20 @@ +#ifndef __ARDOMAIN_UNDELETE_COMMAND_HPP +#define __ARDOMAIN_UNDELETE_COMMAND_HPP + +#include "se/ProtocolExtensionCommand.hpp" + +/** + * Mapping of EPP urn:ar:params:xml:ns:arext-1.0 domainUndelete command + * specified by the AusRegistry EPP extensions document. + * Use this class to generate an AusRegistry-compliant XML document, given + * simple input parameters. The toXML method in Command serialises this object + * to XML. + */ +class ArDomainUndeleteCommand: public ProtocolExtensionCommand +{ +public: + ArDomainUndeleteCommand(const std::string &name); +}; + +#endif // __ARDOMAIN_UNDELETE_COMMAND_HPP + diff --git a/AusRegEPPTK/se/ArDomainUndeleteCommandTest.cpp b/AusRegEPPTK/se/ArDomainUndeleteCommandTest.cpp new file mode 100644 index 0000000..5a81251 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUndeleteCommandTest.cpp @@ -0,0 +1,28 @@ +#include "se/ArDomainUndeleteCommand.hpp" +#include "se/CLTRID.hpp" +#include "se/Period.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + ArDomainUndeleteCommand cmd("jtkutest.com.au"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auJTKUTEST.20070101.010101.0"); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/ArDomainUnrenewCommand.cpp b/AusRegEPPTK/se/ArDomainUnrenewCommand.cpp new file mode 100644 index 0000000..d204d91 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUnrenewCommand.cpp @@ -0,0 +1,37 @@ +#include "se/ArDomainUnrenewCommand.hpp" + +#include "se/CommandType.hpp" +#include "se/ArExtension.hpp" +#include "se/ArDomainObjectType.hpp" +#include "se/EPPDateFormatter.hpp" +#include "xml/XMLHelper.hpp" +#include "se/XMLGregorianCalendar.hpp" + +namespace { + class ArUnrenewCommand : public CommandType + { + public: + ArUnrenewCommand() : CommandType (getCommandName()) { } + std::string getCommandName() const { return "unrenew"; } + std::string toString() const { return "unrenew"; } + }; + + Extension& arExtension() { + static Extension* arExt = new ArExtension(); + return *arExt; + } + + const ArUnrenewCommand unrenewCmdType; + const ArDomainObjectType ardomType; +}; // anonymous namespace + +ArDomainUnrenewCommand::ArDomainUnrenewCommand( + const std::string &name, + const XMLGregorianCalendar& exDate) : ProtocolExtensionCommand( + &unrenewCmdType, &ardomType, name, arExtension()) +{ + std::string exDateStr = EPPDateFormatter::toXSDate(exDate); + XMLHelper::setTextContent + (xmlWriter->appendChild(objElement, "curExpDate"), exDateStr); +} + diff --git a/AusRegEPPTK/se/ArDomainUnrenewCommand.hpp b/AusRegEPPTK/se/ArDomainUnrenewCommand.hpp new file mode 100644 index 0000000..8b419d6 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUnrenewCommand.hpp @@ -0,0 +1,23 @@ +#ifndef __AR_DOMAIN_UNRENEW_COMMAND_HPP +#define __AR_DOMAIN_UNRENEW_COMMAND_HPP + +#include "se/ProtocolExtensionCommand.hpp" +#include + +class XMLGregorianCalendar; + +/** + * Mapping of EPP urn:ar:params:xml:ns:arext-1.0 domainUnrenew command + * specified by the AusRegistry EPP extensions document. + * Use this class to generate an AusRegistry-compliant XML document, given + * simple input parameters. The toXML method in Command serialises this object + * to XML. + */ +class ArDomainUnrenewCommand : public ProtocolExtensionCommand +{ +public: + ArDomainUnrenewCommand(const std::string & name, const XMLGregorianCalendar& exDate); +}; + +#endif // __AR_DOMAIN_UNRENEW_COMMAND_HPP + diff --git a/AusRegEPPTK/se/ArDomainUnrenewCommandTest.cpp b/AusRegEPPTK/se/ArDomainUnrenewCommandTest.cpp new file mode 100644 index 0000000..605feec --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUnrenewCommandTest.cpp @@ -0,0 +1,30 @@ +#include "se/ArDomainUnrenewCommand.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + ArDomainUnrenewCommand cmd( + "jtkutest.com.au", *EPPDateFormatter::fromXSDateTime("2007-01-01T00:00:00.0Z")); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.au2007-01-01JTKUTEST.20070101.010101.0"); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/ArDomainUnrenewResponse.cpp b/AusRegEPPTK/se/ArDomainUnrenewResponse.cpp new file mode 100644 index 0000000..0f0b42a --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUnrenewResponse.cpp @@ -0,0 +1,37 @@ +#include "se/ArDomainUnrenewResponse.hpp" +#include "se/ArDomainObjectType.hpp" +#include "se/ArUnrenewCommandType.hpp" +#include "se/EPPDateFormatter.hpp" + +namespace { + const ArUnrenewCommandType urenType; + const ArDomainObjectType ardomType; +} // anonymous namespace + +using namespace std; + +const string ArDomainUnrenewResponse::ARDOM_NAME_EXPR = + "/e:epp/e:response/e:resData/ardom:urenData/ardom:name/text()"; + +const string ArDomainUnrenewResponse::ARDOM_EX_DATE_EXPR = + "/e:epp/e:response/e:resData/ardom:urenData/ardom:exDate/text()"; + +ArDomainUnrenewResponse::ArDomainUnrenewResponse() + : DataResponse(&urenType, &ardomType) +{ +} + +void ArDomainUnrenewResponse::fromXML(XMLDocument* xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + name = xmlDoc->getNodeValue(ARDOM_NAME_EXPR); + std::string exDateStr = xmlDoc->getNodeValue(ARDOM_EX_DATE_EXPR); + exDate = std::auto_ptr( + EPPDateFormatter::fromXSDateTime(exDateStr)); +} + diff --git a/AusRegEPPTK/se/ArDomainUnrenewResponse.hpp b/AusRegEPPTK/se/ArDomainUnrenewResponse.hpp new file mode 100644 index 0000000..17d7a39 --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUnrenewResponse.hpp @@ -0,0 +1,33 @@ +#ifndef __AR_DOMAIN_UNRENEW_RESPONSE +#define __AR_DOMAIN_UNRENEW_RESPONSE + +#include "se/DataResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +/** + * Use this to access unrenew data for a domain as provided in an EPP domain + * unrenew response compliant with AusRegistry Extensions to EPP and the domain + * name mapping for such extensions. Such a service element is sent by a + * compliant EPP server in response to a valid domain unrenew command, + * implemented by the ArDomainUnrenewCommand class. + * + * @see ArDomainUnrenewCommand + */ +class ArDomainUnrenewResponse : public DataResponse +{ +public: + ArDomainUnrenewResponse(); + + const std::string& getName() { return name; } + const XMLGregorianCalendar* getExpiryDate() { return exDate.get(); } + void fromXML(XMLDocument* xmlDoc) throw (ParsingException); + +private: + static const std::string ARDOM_NAME_EXPR; + static const std::string ARDOM_EX_DATE_EXPR; + + std::string name; + std::auto_ptr exDate; +}; + +#endif // __AU_DOMAIN_UNRENEW_RESPONSE diff --git a/AusRegEPPTK/se/ArDomainUnrenewResponseTest.cpp b/AusRegEPPTK/se/ArDomainUnrenewResponseTest.cpp new file mode 100644 index 0000000..2fe8bed --- /dev/null +++ b/AusRegEPPTK/se/ArDomainUnrenewResponseTest.cpp @@ -0,0 +1,54 @@ +#include "se/ArDomainUnrenewResponse.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" +#include "se/EPPDateFormatter.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + const string xml1 = + "Command completed successfullyexample.com2009-04-03T22:00:00.0ZABC-1234554321-XYZ"; + const string xml2 = + "Command completed successfully; action pendingexample.comABC-1234554321-XYZ"; + + ArDomainUnrenewResponse response1; + ArDomainUnrenewResponse response2; + XMLParser parser; + auto_ptr doc(parser.parse(xml1)); + response1.fromXML(doc.get()); + { + ASSERT_EQ(response1.getName(), "example.com"); + const XMLGregorianCalendar *exDate = response1.getExpiryDate(); + string res = EPPDateFormatter::toXSDateTime(*exDate); + ASSERT_EQ(res, "2009-04-03T22:00:00.0Z"); + const vector& results(response1.getResults()); + ASSERT_EQ(response1.getCLTRID(), "ABC-12345"); + ASSERT_EQ(results[0].getResultCode(), 1000); + ASSERT_EQ(results[0].getResultMessage(), + "Command completed successfully"); + } + + auto_ptr doc2(parser.parse(xml2)); + response2.fromXML(doc2.get()); + { + ASSERT_EQ(response2.getName(), "example.com"); + const XMLGregorianCalendar *exDate = response2.getExpiryDate(); + ASSERT_NULL(exDate); + const vector& results(response2.getResults()); + ASSERT_EQ(response2.getCLTRID(), "ABC-12345"); + ASSERT_EQ(results[0].getResultCode(), 1001); + ASSERT_EQ(results[0].getResultMessage(), + "Command completed successfully; action pending"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/ArExtension.cpp b/AusRegEPPTK/se/ArExtension.cpp new file mode 100644 index 0000000..b5d6e77 --- /dev/null +++ b/AusRegEPPTK/se/ArExtension.cpp @@ -0,0 +1,14 @@ +#include "se/ArExtension.hpp" + +std::string& ArExtension::getURI() const +{ + static std::string uri = "urn:X-ar:params:xml:ns:arext-1.0"; + return uri; +} + +std::string& ArExtension::getSchemaLocation() const +{ + static std::string loc = "urn:X-ar:params:xml:ns:arext-1.0 arext-1.0.xsd"; + return loc; +} + diff --git a/AusRegEPPTK/se/ArExtension.hpp b/AusRegEPPTK/se/ArExtension.hpp new file mode 100644 index 0000000..229e106 --- /dev/null +++ b/AusRegEPPTK/se/ArExtension.hpp @@ -0,0 +1,26 @@ +#ifndef __AREXTENSION_HPP +#define __AREXTENSION_HPP + +#include "se/Extension.hpp" + +/** + * A bundled set of constants representing the AusRegistry EPP extension + * schema. The namespace URI uniquely identifies the extension. + */ +class ArExtension : public Extension +{ +public: + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __AREXTENSION_HPP + diff --git a/AusRegEPPTK/se/ArUnrenewCommandType.cpp b/AusRegEPPTK/se/ArUnrenewCommandType.cpp new file mode 100644 index 0000000..893c17a --- /dev/null +++ b/AusRegEPPTK/se/ArUnrenewCommandType.cpp @@ -0,0 +1,4 @@ +#include "se/ArUnrenewCommandType.hpp" + +const std::string ArUnrenewCommandType::cmdName("unrenew"); + diff --git a/AusRegEPPTK/se/ArUnrenewCommandType.hpp b/AusRegEPPTK/se/ArUnrenewCommandType.hpp new file mode 100644 index 0000000..970db3a --- /dev/null +++ b/AusRegEPPTK/se/ArUnrenewCommandType.hpp @@ -0,0 +1,19 @@ +#ifndef AR_UNRENEW_COMMAND_TYPE +#define AR_UNRENEW_COMMAND_TYPE + +#include "se/CommandType.hpp" +#include + +class ArUnrenewCommandType : public CommandType +{ + public: + ArUnrenewCommandType() : CommandType(getCommandName()) {}; + std::string getCommandName() const { return cmdName; }; + std::string toString() const { return cmdName; }; + + private: + static const std::string cmdName; +}; + +#endif /* AR_UNRENEW_COMMAND_TYPE */ + diff --git a/AusRegEPPTK/se/AuDomainCreateCommand.cpp b/AusRegEPPTK/se/AuDomainCreateCommand.cpp new file mode 100644 index 0000000..44ef9d3 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainCreateCommand.cpp @@ -0,0 +1,131 @@ +#include "se/AuDomainCreateCommand.hpp" +#include "xml/XMLHelper.hpp" +#include "se/AuExtension.hpp" +#include "common/ErrorPkg.hpp" + +namespace { + Extension& auExtension() { + static Extension* auExtension = new AuExtension(); + return *auExtension; + } +}; // anonymous namespace + +AuDomainCreateCommand::AuDomainCreateCommand ( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::string &auEligibilityType, + int auPolicyReason, + const std::string &auRegistrantName) : DomainCreateCommand ( + name, pw, registrantID, techContacts) +{ + setExtension (auEligibilityType, auPolicyReason, auRegistrantName); +} + +AuDomainCreateCommand::AuDomainCreateCommand ( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::vector* adminContacts, + const std::vector* billingContacts, + const std::vector* nameservers, + const std::string &auEligibilityType, + int auPolicyReason, + const std::string &auRegistrantName, + const std::string *auRegistrantID, + const std::string *auRegistrantIDType, + const std::string *auEligibilityName, + const std::string *auEligibilityID, + const std::string *auEligibilityIDType) : DomainCreateCommand ( + name, pw, registrantID, techContacts, nameservers, + adminContacts, billingContacts, NULL) +{ + setExtension (auEligibilityType, auPolicyReason, + auRegistrantName, auRegistrantID, auRegistrantIDType, + auEligibilityName, auEligibilityID, auEligibilityIDType); +} + +void AuDomainCreateCommand::setExtension (const std::string& eligibilityType, + int policyReason, + const std::string& registrantName) +{ + setExtension (eligibilityType, policyReason, registrantName, + NULL, NULL, NULL, NULL, NULL); +} + +void AuDomainCreateCommand::setExtension ( + const std::string& eligibilityType, + int policyReason, + const std::string ®istrantName, + const std::string* registrantID, + const std::string ®istrantIDType) +{ + setExtension (eligibilityType, policyReason, registrantName, + registrantID, ®istrantIDType, NULL, NULL, NULL); +} + +void AuDomainCreateCommand::setExtension ( + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType) +{ + if ((registrantID && registrantIDType == NULL) + || (registrantID == NULL && registrantIDType) + || (eligibilityID && eligibilityIDType == NULL) + || (eligibilityID == NULL && eligibilityIDType)) + { + throw IllegalArgException(ErrorPkg::getMessage( + "se.domaincreate.au.missing_ar")); + } + + DOMElement *auextCreate = xmlWriter->appendChild( + xmlWriter->appendChild( + command, + "extension"), + "create", + auExtension().getURI()); + + XMLHelper::setAttribute(auextCreate, + "xsi:schemaLocation", + auExtension().getSchemaLocation()); + + DOMElement* auProperties = xmlWriter->appendChild( + auextCreate, "auProperties"); + + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "registrantName"), + registrantName); + + if (registrantID && registrantIDType) + xmlWriter->appendChild (auProperties, + "registrantID", *registrantID, + "type", *registrantIDType); + + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "eligibilityType"), + eligibilityType); + + if (eligibilityName) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "eligibilityName"), + *eligibilityName); + + if (eligibilityID && eligibilityIDType) + xmlWriter->appendChild(auProperties, + "eligibilityID", *eligibilityID, + "type", *eligibilityIDType); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "policyReason"), + policyReason); +} + diff --git a/AusRegEPPTK/se/AuDomainCreateCommand.hpp b/AusRegEPPTK/se/AuDomainCreateCommand.hpp new file mode 100644 index 0000000..2b61277 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainCreateCommand.hpp @@ -0,0 +1,147 @@ +#ifndef __AUDOMAINCREATECOMMAND_HPP +#define __AUDOMAINCREATECOMMAND_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainCreateCommand.hpp" + +/** + * Extension of EPP urn:ietf:params:xml:ns:domain-1.0 create command specified + * in RFC3731 to urn:au:params:xml:ns:auext-1.0. .au domains must be + * provisioned using this class rather than {@link + * DomainCreateCommand}, as the au extension data + * is mandatory. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + * The response expected from a server should be handled by a {@link + * DomainCreateResponse} object. + + * @deprecated AU eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainCreateCommand and + * appending a @c DomainKVCommandExtension object containing + * the AU eligibility extensions. + * + * See + * {@link DomainCreateCommand.appendExtension(CommandExtension)} + * and + * {@link DomainKVCommandExtension}. + */ +class AuDomainCreateCommand : public DomainCreateCommand +{ +public: + /** + * Minimal constructor for creating a domain:create + auext:create + * EPP command. These parameters are the least required for a valid + * .au domain create command. + */ + DEPRECATED( + AuDomainCreateCommand (const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::string &auEligibilityType, + int auPolicyReason, + const std::string& auRegistrantName)); + /** + * Full data specification constructor for a domain:create + auext:create + * EPP command. Please refer to the urn:au:params:xml:ns:auext-1.1 schema + * for specification of the required fields. + * The mapping of parameter names to au extension fields is given in the + * parameter documentation. + * + * @param name The name of the new domain. + * + * @param pw The password to assign to the domain (also known as authInfo + * or authorisation information). + * + * @param registrantID The identifier of an existing contact to assign as + * the registrant contact for this domain. Failure to ensure the contact + * exists prior to using them in this way will result in an EPP result of + * '2303 "Object does not exist"'. + * + * @param techContacts The identifiers of existing contacts to assign as + * technical contacts for this domain. Failure to ensure the contacts + * exist prior to using them in this way will result in an EPP result of + * '2303 "Object does not exist"'. + * + * @param adminContacts See techContacts (substitute administrative for + * technical). + * + * @param billingContacts See techContacts (substitute billing for + * technical). + * + * @param nameservers The names of existing hosts to delegate the domain + * being created to. Failure to ensure the hosts exist prior to using them + * in this way will result in an EPP result of '2303 "Object does not + * exist"'. + * + * @param auEligibilityType auext:eligType. + * + * @param auPolicyReason auext:policyReason. + * + * @param auRegistrantName auext:registrantName. + * + * @param auRegistrantID auext:registrantID. + * + * @param auRegistrantIDType auext:registrantID type attribute. + * + * @param auEligibilityName auext:eligibilityName. + * + * @param auEligibilityID auext:eligibilityID. + * + * @param auEligibilityIDType auext:eligibilityID type attribute. + */ + DEPRECATED( + AuDomainCreateCommand (const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::vector* adminContacts, + const std::vector* billingContacts, + const std::vector* nameservers, + const std::string &auEligibilityType, + int auPolicyReason, + const std::string& auRegistrantName, + const std::string* auRegistrantID, + const std::string* auRegistrantIDType, + const std::string* auEligibilityName, + const std::string* auEligibilityID, + const std::string* auEligibilityIDType)); +private: + void setExtension (const std::string& eligibilityType, + int PolicyReason, + const std::string& registrantName); + + void setExtension (const std::string& eligibilityType, + int PolicyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string& registrantIDType); + + /** + * <extension> + *  <create xmlns="urn:au:params:xml:ns:auext-1.1" xsi:schemaLocation="urn:au:params:xml:ns:auext-1.1 auext.1.1.xsd"> + *   <registrantName>registrantName</registrantName> + *   <registrantID type="registrantIDType">registrantID</registrantID> + *   <eligibilityType>eligibilityType</eligibilityType> + *   <eligibilityName>eligibilityName</eligibilityName> + *   <eligibilityID type="eligibilityIDType">eligibilityID</eligibilityID> + *   <policyReason>policyReason</policyReason> + *  </create> + * </extension> + */ + + void setExtension (const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType); +}; + + +#endif // __AUDOMAINCREATECOMMAND_HPP diff --git a/AusRegEPPTK/se/AuDomainCreateCommandTest.cpp b/AusRegEPPTK/se/AuDomainCreateCommandTest.cpp new file mode 100644 index 0000000..12da74a --- /dev/null +++ b/AusRegEPPTK/se/AuDomainCreateCommandTest.cpp @@ -0,0 +1,84 @@ +#include "se/ContactCheckCommand.hpp" +#include "se/AuDomainCreateCommand.hpp" +#include "se/CLTRID.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string registrantName = "AusRegistry"; + const string registrantID = "01241326211"; + const string registrantIDType = "ACN"; + const string eligibilityType = "Company"; + const int policyReason = 1; + const string eligibilityName = "Blah"; + const string eligibilityID = "1231239523"; + const string eligibilityIDType = "OTHER"; + + /** + * Test that the XML string generated for a minimal create domain command + * matches the expected XML for an EPP create domain command with those + * parameters. + */ + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + vector techIds; + techIds.push_back("JTKCON2"); + string registrant("JTKCON"); + AuDomainCreateCommand cmd("jtkutest.com.au", "jtkUT3st", ®istrant, &techIds, + eligibilityType, policyReason, registrantName); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, + "jtkutest.com.auJTKCONJTKCON2jtkUT3stAusRegistryCompany1JTKUTEST.20070101.010101.0"); + } + + /** + * Test that the XML string generated for a sample create domain command + * specified with all available parameters matches the expected XML for + * an EPP create domain command with those parameters. + * + */ + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + vector techIds; + techIds.push_back("JTKCON2"); + + vector adminContacts; + adminContacts.push_back("JTKCON"); + adminContacts.push_back("JTKCON2"); + + string registrant("JTKCON"); + + vector nameServers; + nameServers.push_back("ns1.ausregistry.net"); + nameServers.push_back("ns2.ausregistry.net"); + + AuDomainCreateCommand cmd( + "jtkutest.com.au", "jtkUT3st", ®istrant, + &techIds, &adminContacts, + NULL, &nameServers, + eligibilityType, policyReason, + registrantName, ®istrantID, + ®istrantIDType, &eligibilityName, + &eligibilityID, &eligibilityIDType); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auns1.ausregistry.netns2.ausregistry.netJTKCONJTKCONJTKCON2JTKCON2jtkUT3stAusRegistry01241326211CompanyBlah12312395231JTKUTEST.20070101.010101.0"); + + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/AuDomainCreateCommandV1.cpp b/AusRegEPPTK/se/AuDomainCreateCommandV1.cpp new file mode 100644 index 0000000..0ebacc9 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainCreateCommandV1.cpp @@ -0,0 +1,124 @@ +#include "se/AuDomainCreateCommandV1.hpp" +#include "xml/XMLHelper.hpp" +#include "se/AuExtensionV1.hpp" + +namespace { + Extension& auExtension() { + static Extension* auExtension = new AuExtensionV1(); + return *auExtension; + } +}; // anonymous namespace + +AuDomainCreateCommandV1::AuDomainCreateCommandV1( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::string &auEligibilityType, + int auPolicyReason, + const std::string &auRegistrantName) : DomainCreateCommand ( + name, pw, registrantID, techContacts) +{ + setExtension(auEligibilityType, auPolicyReason, auRegistrantName); +} + +AuDomainCreateCommandV1::AuDomainCreateCommandV1( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + std::vector* adminContacts, + std::vector* billingContacts, + std::vector* nameservers, + const std::string &auEligibilityType, + int auPolicyReason, + const std::string &auRegistrantName, + std::string *auRegistrantID, + std::string *auRegistrantIDType, + std::string *auEligibilityName, + std::string *auEligibilityID, + std::string *auEligibilityIDType) : DomainCreateCommand ( + name, pw, registrantID, techContacts, + adminContacts, billingContacts, nameservers, NULL) +{ + setExtension(auEligibilityType, auPolicyReason, + auRegistrantName, auRegistrantID, auRegistrantIDType, + auEligibilityName, auEligibilityID, auEligibilityIDType); +} + + + +void AuDomainCreateCommandV1::setExtension( + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName) +{ + setExtension(eligibilityType, policyReason, registrantName, + NULL, NULL, NULL, NULL, NULL); +} + +void AuDomainCreateCommandV1::setExtension( + const std::string& eligibilityType, + int policyReason, + const std::string ®istrantName, + const std::string* registrantID, + const std::string ®istrantIDType) +{ + setExtension(eligibilityType, policyReason, registrantName, + registrantID, ®istrantIDType, NULL, NULL, NULL); +} + +void AuDomainCreateCommandV1::setExtension( + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType) +{ + DOMElement *extensionAU = + xmlWriter->appendChild + (xmlWriter->appendChild + (command, + "extension"), + "extensionAU", + auExtension().getURI()); + + XMLHelper::setAttribute (extensionAU, + "xsi:schemaLocation", + auExtension().getSchemaLocation()); + + DOMElement *auextCreate = xmlWriter->appendChild (extensionAU, "create"); + + XMLHelper::setTextContent + (xmlWriter->appendChild (auextCreate, "registrantName"), + registrantName); + + if (registrantID && registrantIDType) + xmlWriter->appendChild (auextCreate, + "registrantID", *registrantID, + "type", *registrantIDType); + + XMLHelper::setTextContent + (xmlWriter->appendChild (auextCreate, "eligibilityType"), + eligibilityType); + + if (eligibilityName) + { + XMLHelper::setTextContent + (xmlWriter->appendChild (auextCreate, "eligibilityName"), + *eligibilityName); + + if (eligibilityID && eligibilityIDType) + xmlWriter->appendChild (auextCreate, + "eligibilityID", *eligibilityID, + "type", *eligibilityIDType); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(auextCreate, "policyReason"), + policyReason); +} + diff --git a/AusRegEPPTK/se/AuDomainCreateCommandV1.hpp b/AusRegEPPTK/se/AuDomainCreateCommandV1.hpp new file mode 100644 index 0000000..a3ff7c5 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainCreateCommandV1.hpp @@ -0,0 +1,85 @@ +#ifndef __AUDOMAINCREATECOMMANDV1_HPP +#define __AUDOMAINCREATECOMMANDV1_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainCreateCommand.hpp" + +/** + * Extension of EPP urn:ietf:params:xml:ns:domain-1.0 create command specified + * in RFC3731 to urn:au:params:xml:ns:auext-1.0. .au domains must be + * provisioned using this class rather than {@link + * com.ausregistry.jtoolkit2.se.DomainCreateCommand}, as the au extension data + * is mandatory. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + * The response expected from a server should be handled by a {@link + * com.ausregistry.jtoolkit2.se.DomainCreateResponse} object. + * + * @deprecated AU eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainCreateCommand and + * appending a @c DomainKVCommandExtension object containing + * the AU eligibility extensions. + * + * See + * {@link DomainCreateCommand.appendExtension(CommandExtension)} + * and + * {@link DomainKVCommandExtension}. + */ +class AuDomainCreateCommandV1 : public DomainCreateCommand +{ +public: + AuDomainCreateCommandV1( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::string& auEligibilityType, + int auPolicyReason, + const std::string& auRegistrantName); + + AuDomainCreateCommandV1( + const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + std::vector* adminContacts, + std::vector* billingContacts, + std::vector* nameservers, + const std::string &auEligibilityType, + int auPolicyReason, + const std::string& auRegistrantName, + std::string* auRegistrantID, + std::string* auRegistrantIDType, + std::string* auEligibilityName, + std::string* auEligibilityID, + std::string* auEligibilityIDType); + +private: + void setExtension( + const std::string& eligibilityType, + int PolicyReason, + const std::string& registrantName); + + void setExtension( + const std::string& eligibilityType, + int PolicyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string& registrantIDType); + + void setExtension( + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType); +}; + + +#endif // __AUDOMAINCREATECOMMANDV1_HPP diff --git a/AusRegEPPTK/se/AuDomainInfoResponse.cpp b/AusRegEPPTK/se/AuDomainInfoResponse.cpp new file mode 100644 index 0000000..4b5ff96 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainInfoResponse.cpp @@ -0,0 +1,57 @@ +#include "se/AuDomainInfoResponse.hpp" +#include "se/StandardObjectType.hpp" + +#include // atoi() + +using namespace std; + +const std::string AuDomainInfoResponse::AUEXT_EXPR(Response::RESPONSE_EXPR() + "/e:extension/auext:infData"); +const std::string AuDomainInfoResponse::AU_PROPERTIES_EXPR(AuDomainInfoResponse::AUEXT_EXPR + "/auext:auProperties"); +const std::string AuDomainInfoResponse::AU_REGISTRANT_NAME_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:registrantName/text()"); +const std::string AuDomainInfoResponse::AU_REGISTRANT_ID_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:registrantID/text()"); +const std::string AuDomainInfoResponse::AU_REGISTRANT_ID_TYPE_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:registrantID/@type"); +const std::string AuDomainInfoResponse::AU_ELI_TYPE_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:eligibilityType/text()"); +const std::string AuDomainInfoResponse::AU_ELI_NAME_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:eligibilityName/text()"); +const std::string AuDomainInfoResponse::AU_ELI_ID_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:eligibilityID/text()"); +const std::string AuDomainInfoResponse::AU_ELI_ID_TYPE_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:eligibilityID/@type"); +const std::string AuDomainInfoResponse::AU_POLICY_REASON_EXPR(AuDomainInfoResponse::AU_PROPERTIES_EXPR + "/auext:policyReason/text()"); + + + +AuDomainInfoResponse::AuDomainInfoResponse() : DomainInfoResponse() +{ + policyReason = 0; +} + +void AuDomainInfoResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + DomainInfoResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + registrantName = xmlDoc->getNodeValue (AU_REGISTRANT_NAME_EXPR); + registrantID = xmlDoc->getNodeValue (AU_REGISTRANT_ID_EXPR); + registrantIDType = xmlDoc->getNodeValue (AU_REGISTRANT_ID_TYPE_EXPR); + eligibilityType = xmlDoc->getNodeValue (AU_ELI_TYPE_EXPR); + eligibilityName = xmlDoc->getNodeValue (AU_ELI_NAME_EXPR); + eligibilityID = xmlDoc->getNodeValue (AU_ELI_ID_EXPR); + eligibilityIDType = xmlDoc->getNodeValue (AU_ELI_ID_TYPE_EXPR); + + string polReasonStr = xmlDoc->getNodeValue (AU_POLICY_REASON_EXPR); + if (polReasonStr.length() > 0) { + policyReason = atoi (polReasonStr.c_str()); + } + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe("Could not parse AuDomainInfoResponse object."); + pe.causedBy(e); + throw pe; + } +} + diff --git a/AusRegEPPTK/se/AuDomainInfoResponse.hpp b/AusRegEPPTK/se/AuDomainInfoResponse.hpp new file mode 100644 index 0000000..f155ac0 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainInfoResponse.hpp @@ -0,0 +1,72 @@ +#ifndef __AU_DOMAIN_INFO_RESPONSE_HPP +#define __AU_DOMAIN_INFO_RESPONSE_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainInfoResponse.hpp" + +#include + +/** + * Extension of the domain mapping of the EPP info response, as defined in + * RFC3730 and RFC3731, to .au domain names, the specification of which is in + * the XML schema definition urn:au:params:xml:ns:auext-1.1. + * Instances of this class provide an interface to access all of the + * information available through EPP for a .au domain name. + * This relies on the instance first being initialised by a suitable EPP domain + * info response using the method fromXML. For flexibility, this + * implementation extracts the data from the response using XPath queries, the + * expressions for which are defined statically. + + * @deprecated AU eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainInfoResponse and + * registering a @c DomainInfoKVResponseExtension object, which + * will contain the AU eligibility extensions. + * + * See + * {@link DomainInfoResponse.registerExtension(ResponseExtension)} + * and + * {@link DomainInfoKVResponseExtension}. + */ +class AuDomainInfoResponse : public DomainInfoResponse +{ +public: + DEPRECATED(AuDomainInfoResponse()); + + const std::string& getRegistrantName() const { return registrantName; }; + const std::string& getAURegistrantID() const { return registrantID; }; + const std::string& getRegistrantIDType() const { return registrantIDType; }; + const std::string& getEligibilityType() const { return eligibilityType; }; + const std::string& getEligibilityName() const { return eligibilityName; }; + const std::string& getEligibilityID() const { return eligibilityID; }; + const std::string& getEligibilityIDType() const { return eligibilityIDType; }; + int getPolicyReason() const { return policyReason; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +private: + static const std::string AUEXT_EXPR, + AU_PROPERTIES_EXPR, + AU_REGISTRANT_NAME_EXPR, + AU_REGISTRANT_ID_EXPR, + AU_REGISTRANT_ID_TYPE_EXPR, + AU_ELI_TYPE_EXPR, + AU_ELI_NAME_EXPR, + AU_ELI_ID_EXPR, + AU_ELI_ID_TYPE_EXPR, + AU_POLICY_REASON_EXPR; + + std::string registrantName, + registrantID, + registrantIDType, + eligibilityType, + eligibilityName, + eligibilityID, + eligibilityIDType; + + int policyReason; +}; + +#endif // __AU_DOMAIN_INFO_RESPONSE_HPP + diff --git a/AusRegEPPTK/se/AuDomainInfoResponseTest.cpp b/AusRegEPPTK/se/AuDomainInfoResponseTest.cpp new file mode 100644 index 0000000..66d4a86 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainInfoResponseTest.cpp @@ -0,0 +1,44 @@ +#include "se/AuDomainInfoResponse.hpp" +#include "xml/XMLParser.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + const string xml = + "Command completed successfullyexample.com.auD0000003-AREXAMPLEEXAMPLEns1.example.com.auns2.example.com.auns1.example.com.auns2.exmaple.com.auRegistrarRegistrar2006-02-09T15:44:58.0Z2008-02-10T00:00:00.0Z0192pqowRegistrantName Pty. Ltd.123456789OtherRegistrant Eligi9876543212ABC-12345805"; + AuDomainInfoResponse response; + try + { + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + ASSERT_EQ("123456789", response.getAURegistrantID()); + ASSERT_EQ("RegistrantName Pty. Ltd.", response.getRegistrantName()); + ASSERT_EQ("ACN", response.getRegistrantIDType()); + ASSERT_EQ("Other", response.getEligibilityType()); + ASSERT_EQ("Registrant Eligi", response.getEligibilityName()); + ASSERT_EQ("987654321", response.getEligibilityID()); + ASSERT_EQ("ABN", response.getEligibilityIDType()); + ASSERT_EQ(2, response.getPolicyReason()); + ASSERT_EQ("example.com.au", response.getName()); + ASSERT_EQ("D0000003-AR", response.getROID()); + ASSERT_EQ("ABC-12345", response.getCLTRID()); + } + catch (EPPException& e) + { + FAIL(e.getMessage()); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/AuDomainInfoResponseV1.cpp b/AusRegEPPTK/se/AuDomainInfoResponseV1.cpp new file mode 100644 index 0000000..30ae5bd --- /dev/null +++ b/AusRegEPPTK/se/AuDomainInfoResponseV1.cpp @@ -0,0 +1,60 @@ +#include "se/AuDomainInfoResponseV1.hpp" +#include "se/StandardObjectType.hpp" + +#include // atoi() + +using namespace std; + +const string AuDomainInfoResponseV1::AUEXT_EXPR( + Response::RESPONSE_EXPR() + "/e:extension/auextv1:extensionAU/auextv1:info"); +const string AuDomainInfoResponseV1::AU_REGISTRANT_NAME_EXPR( + AUEXT_EXPR + "/auextv1:registrantName/text()"); +const string AuDomainInfoResponseV1::AU_REGISTRANT_ID_EXPR( + AUEXT_EXPR + "/auextv1:registrantID/text()"); +const string AuDomainInfoResponseV1::AU_REGISTRANT_ID_TYPE_EXPR( + AUEXT_EXPR + "/auextv1:registrantID/@type"); +const string AuDomainInfoResponseV1::AU_ELI_TYPE_EXPR( + AUEXT_EXPR + "/auextv1:eligibilityType/text()"); +const string AuDomainInfoResponseV1::AU_ELI_NAME_EXPR( + AUEXT_EXPR + "/auextv1:eligibilityName/text()"); +const string AuDomainInfoResponseV1::AU_ELI_ID_EXPR( + AUEXT_EXPR + "/auextv1:eligibilityID/text()"); +const string AuDomainInfoResponseV1::AU_ELI_ID_TYPE_EXPR( + AUEXT_EXPR + "/auextv1:eligibilityID/@type"); +const string AuDomainInfoResponseV1::AU_POLICY_REASON_EXPR( + AUEXT_EXPR + "/auextv1:policyReason/text()"); + + + +AuDomainInfoResponseV1::AuDomainInfoResponseV1() + : DomainInfoResponse() +{ } + +void AuDomainInfoResponseV1::fromXML(XMLDocument *xmlDoc) throw (ParsingException) +{ + DomainInfoResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + registrantName = xmlDoc->getNodeValue(AU_REGISTRANT_NAME_EXPR); + registrantID = xmlDoc->getNodeValue(AU_REGISTRANT_ID_EXPR); + registrantIDType = xmlDoc->getNodeValue(AU_REGISTRANT_ID_TYPE_EXPR); + eligibilityType = xmlDoc->getNodeValue(AU_ELI_TYPE_EXPR); + eligibilityName = xmlDoc->getNodeValue(AU_ELI_NAME_EXPR); + eligibilityID = xmlDoc->getNodeValue(AU_ELI_ID_EXPR); + eligibilityIDType = xmlDoc->getNodeValue(AU_ELI_ID_TYPE_EXPR); + + policyReason = atoi (xmlDoc->getNodeValue(AU_POLICY_REASON_EXPR).c_str()); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe("Could not parse AuDomainInfoResponse object."); + pe.causedBy(e); + throw pe; + } +} diff --git a/AusRegEPPTK/se/AuDomainInfoResponseV1.hpp b/AusRegEPPTK/se/AuDomainInfoResponseV1.hpp new file mode 100644 index 0000000..20fb102 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainInfoResponseV1.hpp @@ -0,0 +1,68 @@ +#ifndef __AU_DOMAIN_INFO_RESPONSEV1_HPP +#define __AU_DOMAIN_INFO_RESPONSEV1_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainInfoResponse.hpp" + +#include + +/** + * Extension of the domain mapping of the EPP info response, as defined in + * RFC3730 and RFC3731, to .au domain names, the specification of which is in + * the XML schema definition urn:au:params:xml:ns:auext-1.0. + * Instances of this class provide an interface to access all of the + * information available through EPP for a .au domain name. + * This relies on the instance first being initialised by a suitable EPP domain + * info response using the method fromXML. For flexibility, this + * implementation extracts the data from the response using XPath queries, the + * expressions for which are defined statically. + + * @deprecated AU eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainInfoResponse and + * registering a @c DomainInfoKVResponseExtension object, which + * will contain the AU eligibility extensions. + * + * See + * {@link DomainInfoResponse.registerExtension(ResponseExtension)} + * and + * {@link DomainInfoKVResponseExtension}. + */ +class AuDomainInfoResponseV1 : public DomainInfoResponse +{ +public: + DEPRECATED(AuDomainInfoResponseV1()); + + const std::string& getRegistrantName() const { return registrantName; }; + const std::string& getAURegistrantID() const { return registrantID; }; + const std::string& getRegistrantIDType() const { return registrantIDType; }; + const std::string& getEligibilityType() const { return eligibilityType; }; + const std::string& getEligibilityName() const { return eligibilityName; }; + const std::string& getEligibilityID() const { return eligibilityID; }; + const std::string& getEligibilityIDType() const { return eligibilityIDType; }; + int getPolicyReason() const { return policyReason; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +private: + static const std::string AUEXT_EXPR, + AU_REGISTRANT_NAME_EXPR, + AU_REGISTRANT_ID_EXPR, + AU_REGISTRANT_ID_TYPE_EXPR, + AU_ELI_TYPE_EXPR, + AU_ELI_NAME_EXPR, + AU_ELI_ID_EXPR, + AU_ELI_ID_TYPE_EXPR, + AU_POLICY_REASON_EXPR; + std::string registrantName, + registrantID, + registrantIDType, + eligibilityType, + eligibilityName, + eligibilityID, + eligibilityIDType; + int policyReason; +}; + +#endif // __AU_DOMAIN_INFO_RESPONSEV1_HPP diff --git a/AusRegEPPTK/se/AuDomainInfoResponsev1Test.cpp b/AusRegEPPTK/se/AuDomainInfoResponsev1Test.cpp new file mode 100644 index 0000000..1247fc0 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainInfoResponsev1Test.cpp @@ -0,0 +1,42 @@ +#include "se/AuDomainInfoResponseV1.hpp" +#include "xml/XMLDocument.hpp" +#include "xml/XMLParser.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string xml = + "Command completed successfullyexample.com.auD0000003-AREXAMPLEEXAMPLEns1.example.com.auns2.example.com.auns1.example.com.auns2.exmaple.com.auRegistrarRegistrar2006-02-09T15:44:58.0Z2008-02-10T00:00:00.0Z0192pqowRegistrantName Pty. Ltd.123456789OtherRegistrant Eligi9876543212ABC-12345805"; + AuDomainInfoResponseV1 response; + XMLParser parser; + auto_ptr doc(parser.parse(xml)); + response.fromXML(doc.get()); + + ASSERT_EQ("123456789", response.getAURegistrantID()); + ASSERT_EQ("RegistrantName Pty. Ltd.", response.getRegistrantName()); + ASSERT_EQ("ACN", response.getRegistrantIDType()); + ASSERT_EQ("Other", response.getEligibilityType()); + ASSERT_EQ("Registrant Eligi", response.getEligibilityName()); + ASSERT_EQ("987654321", response.getEligibilityID()); + ASSERT_EQ("ABN", response.getEligibilityIDType()); + ASSERT_EQ(2, response.getPolicyReason()); + ASSERT_EQ("example.com.au", response.getName()); + ASSERT_EQ("D0000003-AR", response.getROID()); + ASSERT_EQ("ABC-12345", response.getCLTRID()); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/AuDomainModifyRegistrantCommand.cpp b/AusRegEPPTK/se/AuDomainModifyRegistrantCommand.cpp new file mode 100644 index 0000000..9c12e97 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainModifyRegistrantCommand.cpp @@ -0,0 +1,93 @@ +#include "se/AuDomainModifyRegistrantCommand.hpp" +#include "common/ErrorPkg.hpp" +#include "se/AuExtension.hpp" +#include "xml/XMLHelper.hpp" + +namespace { + AuExtension& auExtension() { + static AuExtension* auExtension = new AuExtension(); + return *auExtension; + } +}; // anonymous namespace + +AuDomainModifyRegistrantCommand::AuDomainModifyRegistrantCommand( + const std::string& name, + const std::string& registrantName, + const std::string& explanation, + const std::string* eligibilityType, + int policyReason, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType) : DomainUpdateCommand(name) +{ + if (eligibilityType == NULL + || (registrantID == NULL && registrantIDType != NULL) + || (registrantID != NULL && registrantIDType == NULL) + || (eligibilityID == NULL && eligibilityIDType != NULL) + || (eligibilityID != NULL && eligibilityIDType == NULL)) + { + throw IllegalArgException( + ErrorPkg::getMessage("se.domain.modify.au.missing_arg")); + } + + DOMElement* auextUpdate = xmlWriter->appendChild( + xmlWriter->appendChild(command, "extension"), + "update", + auExtension().getURI()); + + auextUpdate->setAttribute( + XStr("xsi:schemaLocation").str(), + XStr(auExtension().getSchemaLocation()).str()); + + DOMElement* auProperties = xmlWriter->appendChild(auextUpdate, + "auProperties"); + + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "registrantName"), + registrantName); + + if (registrantID != NULL && registrantIDType != NULL) + { + xmlWriter->appendChild( + auProperties, + "registrantID", + *registrantID, + "type", + *registrantIDType); + } + + if (eligibilityType != NULL) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "eligibilityType"), + *eligibilityType); + } + + if (eligibilityName != NULL) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "eligibilityName"), + *eligibilityName); + } + + if (eligibilityID != NULL && eligibilityIDType != NULL) + { + xmlWriter->appendChild( + auProperties, + "eligibilityID", + *eligibilityID, + "type", + *eligibilityIDType); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "policyReason"), + policyReason); + + XMLHelper::setTextContent( + xmlWriter->appendChild(auextUpdate, "explanation"), + explanation); +} + diff --git a/AusRegEPPTK/se/AuDomainModifyRegistrantCommand.hpp b/AusRegEPPTK/se/AuDomainModifyRegistrantCommand.hpp new file mode 100644 index 0000000..c89751b --- /dev/null +++ b/AusRegEPPTK/se/AuDomainModifyRegistrantCommand.hpp @@ -0,0 +1,46 @@ +#ifndef __AU_DOMAIN_MODIFY_REGISTRANT_COMMAND_HPP +#define __AU_DOMAIN_MODIFY_REGISTRANT_COMMAND_HPP + +#include "common/Deprecated.hpp" +#include "se/DomainUpdateCommand.hpp" + +/** + * An extension of the domain mapping of the EPP update command, as defined in + * RFC3730 and RFC3731, to .au domain names, the specification of which is in + * the XML schema definition urn:au:params:xml:ns:auext-1.1. + * This class should only be used to correct au extension data for .au domain + * names, and only where the legal registrant has not changed. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + * + * @deprecated AU eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. This can be done + * through the toolkit by using a @c DomainUpdateCommand and + * appending a @c DomainKVCommandExtension object containing + * the AU eligibility extensions. + * + * See + * {@link DomainUpdateCommand.appendExtension(CommandExtension)} + * and + * {@link DomainKVCommandExtension}. + */ +class AuDomainModifyRegistrantCommand : public DomainUpdateCommand +{ +public: + DEPRECATED( + AuDomainModifyRegistrantCommand(const std::string& name, + const std::string& registrantName, + const std::string& explanation, + const std::string* eligibilityType = NULL, + int policyReason = 0, + const std::string* registrantID = NULL, + const std::string* registrantIDType = NULL, + const std::string* eligibilityName = NULL, + const std::string* eligibilityID = NULL, + const std::string* eligibilityIDType = NULL)); +}; + +#endif // __AU_DOMAIN_MODIFY_REGISTRANT_COMMAND_HPP + diff --git a/AusRegEPPTK/se/AuDomainModifyRegistrantCommandTest.cpp b/AusRegEPPTK/se/AuDomainModifyRegistrantCommandTest.cpp new file mode 100644 index 0000000..fbba3d3 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainModifyRegistrantCommandTest.cpp @@ -0,0 +1,48 @@ +#include "se/ContactCheckCommand.hpp" +#include "se/AuDomainModifyRegistrantCommand.hpp" +#include "se/CLTRID.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string registrantName = "AusRegistry"; + const string registrantID = "01241326211"; + const string registrantIDType = "ACN"; + const string eligibilityType = "Company"; + const int policyReason = 1; + const string eligibilityName = "Blah"; + const string eligibilityID = "1231239523"; + const string eligibilityIDType = "OTHER"; + + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + AuDomainModifyRegistrantCommand cmd( + "jtkutest.com.au", + registrantName, + "testing", + &eligibilityType, + policyReason, + ®istrantID, + ®istrantIDType, + &eligibilityName, + &eligibilityID, + &eligibilityIDType); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auAusRegistry01241326211CompanyBlah12312395231testingJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/AuDomainObjectType.cpp b/AusRegEPPTK/se/AuDomainObjectType.cpp new file mode 100644 index 0000000..0cb43e1 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainObjectType.cpp @@ -0,0 +1,25 @@ +#include "AuDomainObjectType.hpp" + +#include + +const std::string& AuDomainObjectType::getName() const { + static const std::string name = "audom"; + return name; +} + +const std::string& AuDomainObjectType::getURI() const { + static const std::string uri = "urn:X-au:params:xml:ns:audomain-1.0"; + return uri; +} + +const std::string& AuDomainObjectType::getSchemaLocation() const { + static const std::string schemaLocation = + "urn:X-au:params:xml:ns:audomain-1.0 audomain-1.0.xsd"; + return schemaLocation; +} + +const std::string& AuDomainObjectType::getIdentType() const { + static const std::string ident = "name"; + return ident; +} + diff --git a/AusRegEPPTK/se/AuDomainObjectType.hpp b/AusRegEPPTK/se/AuDomainObjectType.hpp new file mode 100644 index 0000000..1ea8de3 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainObjectType.hpp @@ -0,0 +1,17 @@ +#ifndef AUDOMAIN_OBJECT_TYPE +#define AUDOMAIN_OBJECT_TYPE + +#include "ObjectType.hpp" + +#include + +class AuDomainObjectType : public ObjectType { +public: + virtual const std::string& getName() const; + virtual const std::string& getURI() const; + virtual const std::string& getSchemaLocation() const; + virtual const std::string& getIdentType() const; +}; + +#endif // AUDOMAIN_OBJECT_TYPE + diff --git a/AusRegEPPTK/se/AuDomainTransferRegistrantCommand.cpp b/AusRegEPPTK/se/AuDomainTransferRegistrantCommand.cpp new file mode 100644 index 0000000..57c4491 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainTransferRegistrantCommand.cpp @@ -0,0 +1,92 @@ +#include "se/AuDomainTransferRegistrantCommand.hpp" +#include "se/XMLGregorianCalendar.hpp" + +#include "se/AuExtension.hpp" +#include "se/AuDomainObjectType.hpp" +#include "se/RegistrantTransferCommandType.hpp" +#include "se/CommandType.hpp" +#include "se/Period.hpp" +#include "common/ErrorPkg.hpp" + +#include "se/EPPDateFormatter.hpp" + +#include "xml/XMLHelper.hpp" + +namespace { + Extension& auExtension() { + static Extension* auExt = new AuExtension(); + return *auExt; + } + + const RegistrantTransferCommandType rtrnType; + const AuDomainObjectType audomType; +} // anonymous namespace + +AuDomainTransferRegistrantCommand::AuDomainTransferRegistrantCommand ( + const std::string& name, + const XMLGregorianCalendar& curExpDate, + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string& explanation, + const std::string* registrantID, + const std::string* registrantIDType, + const std::string* eligibilityName, + const std::string* eligibilityID, + const std::string* eligibilityIDType, + const Period* period) : ProtocolExtensionCommand( + &rtrnType, &audomType, name, auExtension()) +{ + if ((registrantID && registrantIDType == NULL) + || (registrantIDType == NULL && registrantIDType) + || (eligibilityName && (eligibilityID == NULL || eligibilityIDType == NULL)) + || (eligibilityName == NULL && (eligibilityID || eligibilityIDType))) + { + // If provided, a registrantID must have a type. + // If provided, an eligibilityName must have both an eligibilityID and type. + throw IllegalArgException( + ErrorPkg::getMessage("se.domain.registrantTransfer.au.missing_arg")); + } + + DOMElement *element; + + std::string curExpDateStr = EPPDateFormatter::toXSDate(curExpDate); + XMLHelper::setTextContent( + xmlWriter->appendChild(objElement, "curExpDate"), curExpDateStr); + + if (period) + period->appendPeriod(xmlWriter, objElement); + + DOMElement *auProperties = xmlWriter->appendChild(objElement, "auProperties"); + + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "registrantName"), registrantName); + + if (registrantID) + { + element = xmlWriter->appendChild(auProperties, "registrantID"); + XMLHelper::setTextContent(element, *registrantID); + XMLHelper::setAttribute(element, "type", *registrantIDType); + } + XMLHelper::setTextContent + (xmlWriter->appendChild(auProperties, "eligibilityType"), eligibilityType); + + if (eligibilityName) + { + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "eligibilityName"), *eligibilityName); + + element = xmlWriter->appendChild(auProperties, "eligibilityID"); + XMLHelper::setTextContent(element, *eligibilityID); + XMLHelper::setAttribute(element, "type", *eligibilityIDType); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(auProperties, "policyReason"), + policyReason); + + XMLHelper::setTextContent( + xmlWriter->appendChild(objElement, "explanation"), + explanation); +} + diff --git a/AusRegEPPTK/se/AuDomainTransferRegistrantCommand.hpp b/AusRegEPPTK/se/AuDomainTransferRegistrantCommand.hpp new file mode 100644 index 0000000..d088183 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainTransferRegistrantCommand.hpp @@ -0,0 +1,89 @@ +#ifndef __AU_DOMAIN_TRANSFER_REGISTRANT_COMMAND_HPP +#define __AU_DOMAIN_TRANSFER_REGISTRANT_COMMAND_HPP + +#include "common/Deprecated.hpp" +#include "se/ProtocolExtensionCommand.hpp" +class XMLGregorianCalendar; +class Period; + +/** + * In cases where the legal registrant of a .au domain name has changed, this + * class should be used to request a transfer of registrant. This is a + * different action to correcting extension data which was originally specified + * incorrectly, and should only be used in the situation described. This + * command will result in the validity period of the domain name being updated + * and the requesting client being charged the usual create fee upon success of + * this operation. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + + * @deprecated AU eligibility extensions should now be managed through the + * @c extension defined in the + * urn:X-ar:params:xml:ns:kv-1.0 namespace. The Registrant + * Transfer command that utilises this extension is defined in the + * urn:X-ar:params:xml:ns:registrant-1.0 namespace. This can + * be done through the toolkit by using a + * @c DomainRegistrantTransferCommand and specifying + * @c "au" as the kvListName. + * + * See + * {@link DomainRegistrantTransferCommand} + * and + * {@link DomainRegistrantTransferCommand.addItem(std::string, std::string)} + * . + */ +class AuDomainTransferRegistrantCommand : public ProtocolExtensionCommand +{ +public: + + /** + * Request that the named .au domain name be transferred to the legal + * entity specified by the given au extension data. + * + * @param name The domain name to transfer. + * + * @param curExpDate The current expiry of the identified domain name. + * This is required in order to prevent repeated transfer of the name due + * to protocol transmission failures. + * + * @param eligibilityType + * + * @param policyReason + * + * @param registrantName + * + * @param explanation An explanation of how the transfer was effected. + * + * @param registrantID + * + * @param registrantIDType + * + * @param eligibilityName + * + * @param eligibilityID + * + * @param eligibilityIDType + * + * @param period The desired new validity period, starting from the time + * the transfer completes successfully. + * + * @param explanation An explanation of how the transfer was effected. + */ + DEPRECATED( + AuDomainTransferRegistrantCommand (const std::string& name, + const XMLGregorianCalendar& curExpDate, + const std::string& eligibilityType, + int policyReason, + const std::string& registrantName, + const std::string& explanation, + const std::string* registrantID = NULL, + const std::string* registrantIDType = NULL, + const std::string* eligibilityName = NULL, + const std::string* eligibilityID = NULL, + const std::string* eligibilityIDType = NULL, + const Period* period = NULL)); +}; + +#endif // __AU_DOMAIN_TRANSFER_REGISTRANT_COMMAND_HPP + diff --git a/AusRegEPPTK/se/AuDomainTransferRegistrantCommandTest.cpp b/AusRegEPPTK/se/AuDomainTransferRegistrantCommandTest.cpp new file mode 100644 index 0000000..b8f02bc --- /dev/null +++ b/AusRegEPPTK/se/AuDomainTransferRegistrantCommandTest.cpp @@ -0,0 +1,71 @@ +#include "se/AuDomainTransferRegistrantCommand.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "se/Period.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const int policyReason = 1; + const string registrantName = "AusRegistry"; + const string registrantID = "01241326211"; + const string registrantIDType = "ACN"; + const string eligibilityType = "Company"; + const string eligibilityName = "Blah"; + const string eligibilityID = "1231239523"; + const string eligibilityIDType = "OTHER"; + auto_ptr curExpDate(EPPDateFormatter::fromXSDateTime("2007-01-01T01:01:01.0Z")); + + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + AuDomainTransferRegistrantCommand cmd( + "jtkutest.com.au", // domain name + *curExpDate, // current expire date + "Other", + policyReason, + registrantName, + "testing"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.au2007-01-01AusRegistryOther1testingJTKUTEST.20070101.010101.0"); + } + + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + Period p(2, PeriodUnit::YEARS()); + + AuDomainTransferRegistrantCommand cmd( + "jtkutest.com.au", // name + *curExpDate, // curExpDate + eligibilityType, + policyReason, + registrantName, + "testing", + ®istrantID, + ®istrantIDType, + &eligibilityName, + &eligibilityID, + &eligibilityIDType, + &p); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.au2007-01-012AusRegistry01241326211CompanyBlah12312395231testingJTKUTEST.20070101.010101.0"); + } + +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/AuDomainTransferRegistrantResponse.cpp b/AusRegEPPTK/se/AuDomainTransferRegistrantResponse.cpp new file mode 100644 index 0000000..e18b0f6 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainTransferRegistrantResponse.cpp @@ -0,0 +1,37 @@ +#include "se/AuDomainTransferRegistrantResponse.hpp" +#include "se/AuDomainObjectType.hpp" +#include "se/RegistrantTransferCommandType.hpp" +#include "se/EPPDateFormatter.hpp" + +namespace { + const RegistrantTransferCommandType rtrnType; + const AuDomainObjectType audomType; +} // anonymous namespace + +using namespace std; + +const string AuDomainTransferRegistrantResponse::AUDOM_NAME_EXPR = + "/e:epp/e:response/e:resData/audom:rtrnData/audom:name/text()"; + +const string AuDomainTransferRegistrantResponse::AUDOM_EX_DATE_EXPR = + "/e:epp/e:response/e:resData/audom:rtrnData/audom:exDate/text()"; + +AuDomainTransferRegistrantResponse::AuDomainTransferRegistrantResponse() + : DataResponse(&rtrnType, &audomType) +{ +} + +void AuDomainTransferRegistrantResponse::fromXML(XMLDocument* xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + name = xmlDoc->getNodeValue(AUDOM_NAME_EXPR); + std::string exDateStr = xmlDoc->getNodeValue(AUDOM_EX_DATE_EXPR); + exDate = std::auto_ptr( + EPPDateFormatter::fromXSDateTime(exDateStr)); +} + diff --git a/AusRegEPPTK/se/AuDomainTransferRegistrantResponse.hpp b/AusRegEPPTK/se/AuDomainTransferRegistrantResponse.hpp new file mode 100644 index 0000000..6a8847c --- /dev/null +++ b/AusRegEPPTK/se/AuDomainTransferRegistrantResponse.hpp @@ -0,0 +1,43 @@ +#ifndef __AU_DOMAIN_TRANSFER_REGISTRANT_RESPONSE +#define __AU_DOMAIN_TRANSFER_REGISTRANT_RESPONSE + +#include "common/Deprecated.hpp" +#include "se/DataResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +/** + * Use this to access create data for a domain as provided in an EPP domain + * create response compliant with RFCs 3730 and 3731. Such a service element + * is sent by a compliant EPP server in response to a valid domain create + * command, implemented by the DomainCreateCommand. + * + * @see DomainCreateCommand + + * @deprecated Performing a registrant transfer with AU eligibility extensions + * should now be managed through the use of the + * @c DomainRegistrantTransferCommand and + * @c DomainRegistrantTransferResponse + * + * See + * {@link DomainRegistrantTransferCommand} + * and + * {@link DomainRegistrantTransferResponse}. + */ +class AuDomainTransferRegistrantResponse : public DataResponse +{ +public: + DEPRECATED(AuDomainTransferRegistrantResponse()); + + const std::string& getName() const { return name; } + const XMLGregorianCalendar* getExpiryDate() const { return exDate.get(); } + void fromXML(XMLDocument* xmlDoc) throw (ParsingException); + +private: + static const std::string AUDOM_NAME_EXPR; + static const std::string AUDOM_EX_DATE_EXPR; + + std::string name; + std::auto_ptr exDate; +}; + +#endif // __AU_DOMAIN_TRANSFER_REGISTRANT_RESPONSE diff --git a/AusRegEPPTK/se/AuDomainTransferRegistrantResponseTest.cpp b/AusRegEPPTK/se/AuDomainTransferRegistrantResponseTest.cpp new file mode 100644 index 0000000..da4b953 --- /dev/null +++ b/AusRegEPPTK/se/AuDomainTransferRegistrantResponseTest.cpp @@ -0,0 +1,38 @@ +#include "se/AuDomainTransferRegistrantResponse.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" +#include "se/EPPDateFormatter.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + const string xml = + "Command completed successfullyexample.com2009-04-03T22:00:00.0ZABC-1234554321-XYZ"; + + AuDomainTransferRegistrantResponse response; + AuDomainTransferRegistrantResponse response2; + XMLParser parser; + auto_ptr doc(parser.parse(xml)); + response.fromXML(doc.get()); + { + ASSERT_EQ(response.getName(), "example.com"); + const XMLGregorianCalendar *exDate = response.getExpiryDate(); + string res = EPPDateFormatter::toXSDateTime(*exDate); + ASSERT_EQ(res, "2009-04-03T22:00:00.0Z"); + const vector& results(response.getResults()); + ASSERT_EQ(response.getCLTRID(), "ABC-12345"); + ASSERT_EQ(results[0].getResultCode(), 1000); + ASSERT_EQ(results[0].getResultMessage(), + "Command completed successfully"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/AuExtension.cpp b/AusRegEPPTK/se/AuExtension.cpp new file mode 100644 index 0000000..fe2c18b --- /dev/null +++ b/AusRegEPPTK/se/AuExtension.cpp @@ -0,0 +1,14 @@ +#include "se/AuExtension.hpp" + +std::string& AuExtension::getURI() const +{ + static std::string uri = "urn:X-au:params:xml:ns:auext-1.1"; + return uri; +} + +std::string& AuExtension::getSchemaLocation() const +{ + static std::string loc = "urn:X-au:params:xml:ns:auext-1.1 auext-1.1.xsd"; + return loc; +} + diff --git a/AusRegEPPTK/se/AuExtension.hpp b/AusRegEPPTK/se/AuExtension.hpp new file mode 100644 index 0000000..9dac98d --- /dev/null +++ b/AusRegEPPTK/se/AuExtension.hpp @@ -0,0 +1,27 @@ +#ifndef __AUEXTENSION_HPP +#define __AUEXTENSION_HPP + +#include "se/Extension.hpp" + +/** + * A bundled set of constants representing the .au EPP extension + * schema. The namespace URI uniquely identifies the extension. + */ +class AuExtension : public Extension +{ +public: + + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __AUEXTENSION_HPP + diff --git a/AusRegEPPTK/se/AuExtensionV1.cpp b/AusRegEPPTK/se/AuExtensionV1.cpp new file mode 100644 index 0000000..43db25c --- /dev/null +++ b/AusRegEPPTK/se/AuExtensionV1.cpp @@ -0,0 +1,13 @@ +#include "se/AuExtensionV1.hpp" + +std::string& AuExtensionV1::getURI() const +{ + static std::string uri = "urn:au:params:xml:ns:auext-1.0"; + return uri; +} + +std::string& AuExtensionV1::getSchemaLocation() const +{ + static std::string loc = "urn:au:params:xml:ns:auext-1.0 auext-1.0.xsd"; + return loc; +} diff --git a/AusRegEPPTK/se/AuExtensionV1.hpp b/AusRegEPPTK/se/AuExtensionV1.hpp new file mode 100644 index 0000000..2e48b82 --- /dev/null +++ b/AusRegEPPTK/se/AuExtensionV1.hpp @@ -0,0 +1,25 @@ +#ifndef __AUEXTENSIONV1_HPP +#define __AUEXTENSIONV1_HPP + +#include "se/Extension.hpp" + +/** + * A bundled set of constants representing the .au EPP extension + * schema. The namespace URI uniquely identifies the extension. + */ +class AuExtensionV1 : public Extension +{ +public: + + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __AUEXTENSIONV1_HPP diff --git a/AusRegEPPTK/se/CLTRID.cpp b/AusRegEPPTK/se/CLTRID.cpp new file mode 100644 index 0000000..3b361de --- /dev/null +++ b/AusRegEPPTK/se/CLTRID.cpp @@ -0,0 +1,44 @@ +#include "se/CLTRID.hpp" +#include "session/Timer.hpp" + +#include +#include + +using namespace std; + +string& CLTRID::clID() +{ + static string id = ""; + return id; +} + +int& CLTRID::val() +{ + static int v = 0; + return v; +} + +string CLTRID::nextVal() +{ + // Good until 2034. + time_t now = Timer::now() / 1000; + struct tm * tm_now = localtime(&now); + char tmbuf[30]; + + ostringstream retval; + strftime(tmbuf, sizeof(tmbuf), ".%Y%m%d.%H%M%S.", tm_now); + retval << clID() << tmbuf << val(); + inc(); + return retval.str(); +} + +void CLTRID::setClID (const string &clID) +{ + CLTRID::clID() = clID; + val() = 0; +} + +void CLTRID::inc() +{ + val() = (val() + 1) % maxVal; +} diff --git a/AusRegEPPTK/se/CLTRID.hpp b/AusRegEPPTK/se/CLTRID.hpp new file mode 100644 index 0000000..9330690 --- /dev/null +++ b/AusRegEPPTK/se/CLTRID.hpp @@ -0,0 +1,37 @@ +#ifndef __CLTRID_HPP +#define __CLTRID_HPP + +#include + +/** + * Provides generated unique client transaction identifiers for use in EPP + * commands as the value of the epp:clTRID element. The class should first be + * initialised by setting the client identifier. + */ +class CLTRID +{ +public: + CLTRID() { } + + /** + * Generate a unique client transaction identifier and return the value. + */ + static std::string nextVal(); + + /** + * Set the client identifier for generating client transaction IDs. This + * constitutes the first part of the clTRID and helps to ensure uniqueness + * of clTRIDs within a Registry system. + */ + static void setClID(const std::string &clID); + +private: + static const int BUFFER_SIZE = 24; + static const int maxVal = 1000; + static int& val(); + static std::string& clID(); + + static void inc(); +}; + +#endif // __CLTRID_HPP diff --git a/AusRegEPPTK/se/CheckCommand.hpp b/AusRegEPPTK/se/CheckCommand.hpp new file mode 100644 index 0000000..b70cd29 --- /dev/null +++ b/AusRegEPPTK/se/CheckCommand.hpp @@ -0,0 +1,46 @@ +#ifndef __CHECKCOMMAND_HPP +#define __CHECKCOMMAND_HPP + +#include "se/ObjectCommand.hpp" +#include "se/StandardCommandType.hpp" + +#include +#include + +/** + * Representation of the EPP check command, as defined in RFC3730. + * Subclasses of this must specify the object to which the command is mapped + * and specify the object-specific identifiers of the objects to check the + * availability of. + */ +class CheckCommand : public ObjectCommand +{ +public: + /** + * Create a check command mapped to the specified object type to check the + * availability of the identified object. + * + * @param objType The object mapping to use. + * + * @param ident An object type-specific label identifying the object to + * check the availability of. + */ + CheckCommand (const ObjectType* objType, + const std::string &ident) + : ObjectCommand (StandardCommandType::CHECK(), objType, ident) {}; + + /** + * Create a check command mapped to the specified object type to check the + * availability of the identified object. + * + * @param objType The object mapping to use. + * + * @param idents An object type-specific array of labels identifying the + * objects to check the availability of. + */ + CheckCommand (const ObjectType* objType, + const std::vector &idents) + : ObjectCommand (StandardCommandType::CHECK(), objType, idents) {}; +}; + +#endif // __CHECKCOMMAND_HPP diff --git a/AusRegEPPTK/se/CheckResponse.cpp b/AusRegEPPTK/se/CheckResponse.cpp new file mode 100644 index 0000000..7f68170 --- /dev/null +++ b/AusRegEPPTK/se/CheckResponse.cpp @@ -0,0 +1,118 @@ +#include "se/CheckResponse.hpp" +#include "se/ItemNotFoundException.hpp" +#include "se/StandardCommandType.hpp" +#include "common/StringUtils.hpp" + +using namespace std; + +const string CheckResponse::CHKDATA_COUNT_EXPR() +{ + static string expr = "count(" + DataResponse::RES_DATA_EXPR() + "/OBJ:chkData/*)"; + return expr; +} +const string CheckResponse::CHKDATA_IND_EXPR() +{ + static string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:chkData/OBJ:cd[IDX]"; + return expr; +} +const string CheckResponse::CHKDATA_IDENT_EXPR() +{ + static string expr = "/OBJ:IDENT/text()"; + return expr; +} +const string CheckResponse::CHKDATA_AVAIL_EXPR() +{ + static string expr = "/OBJ:IDENT/@avail"; + return expr; +} +const string CheckResponse::CHKDATA_REASON_EXPR() +{ + static string expr = "/OBJ:reason/text()"; + return expr; +} + + +CheckResponse::CheckResponse (const ObjectType* objectType) + : DataResponse(StandardCommandType::CHECK(), objectType) +{ +} + +bool CheckResponse::isAvailable (const string &nameID) const +{ + map::const_iterator p = availMap.find(nameID); + if (p != availMap.end()) + return p->second.avail; + else + return false; +} + +const string& CheckResponse::getReason (const string &nameID) const +{ + map::const_iterator p = availMap.find(nameID); + if (p != availMap.end()) + return p->second.reason; + else + throw ItemNotFoundException(); +} + +const string & CheckResponse::getReason (int index) const +{ + return reasonArray[index]; +} + +void CheckResponse::fromXML(XMLDocument *xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + availArray.clear(); + reasonArray.clear(); + + int cdCount = xmlDoc->getNodeCount(chkDataCountExpr()); + availArray.reserve(cdCount); + reasonArray.reserve(cdCount); + + for (int i = 0; i < cdCount; i++) + { + string qry = replaceIndex(chkDataIndexExpr(), i + 1); + string type = getObjType().getIdentType(); + string nameID = xmlDoc->getNodeValue(qry + chkDataTextExpr()); + string availStr = xmlDoc->getNodeValue(qry + chkDataAvailExpr()); + bool avail = (availStr == "1"); + availArray.push_back(avail); + string reason = xmlDoc->getNodeValue(qry + chkDataReasonExpr()); + reasonArray.push_back(reason); + + availMap.insert(make_pair(nameID, Availability(avail, reason))); + } + // End for + debugLogger->fine(toString()); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + + +string CheckResponse::toString () const +{ + string retval = DataResponse::toString(); + + map::const_iterator p; + + for (p = availMap.begin(); p != availMap.end(); p++) + retval += "(name = " + p->first + ")(available = " + + StringUtils::makeString(p->second.avail) + + ")(reason = " + p->second.reason + ")"; + + return retval; +} diff --git a/AusRegEPPTK/se/CheckResponse.hpp b/AusRegEPPTK/se/CheckResponse.hpp new file mode 100644 index 0000000..2694292 --- /dev/null +++ b/AusRegEPPTK/se/CheckResponse.hpp @@ -0,0 +1,62 @@ +#ifndef __CHECKRESPONSE_HPP +#define __CHECKRESPONSE_HPP + +#include "se/DataResponse.hpp" +#include + +/** + * Representation of the EPP check response, as defined in RFC3730. + * Subclasses of this must specify the object to which the command is mapped. + * Instances of this class provide an interface to access availability + * information for each object identified in a {@link + * com.ausregistry.jtoolkit2.se.CheckCommand}. + * This relies on the instance first being initialised by a suitable EPP check + * response using the method fromXML. For flexibility, this implementation + * extracts the data from the response using XPath queries, the expressions for + * which are defined statically. + * + * @see CheckCommand + */ +class CheckResponse : public DataResponse +{ +public: + CheckResponse (const ObjectType* objectType); + + bool isAvailable (const std::string &nameID) const; + const std::string & getReason (const std::string &nameID) const; + const std::string & getReason (int index) const; + const std::vector & getAvailableList() const { return availArray; }; + const std::vector & getReasonList() const { return reasonArray; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + virtual std::string toString() const; + +protected: + static const std::string CHKDATA_COUNT_EXPR(); + static const std::string CHKDATA_IND_EXPR(); + static const std::string CHKDATA_IDENT_EXPR(); + static const std::string CHKDATA_AVAIL_EXPR(); + static const std::string CHKDATA_REASON_EXPR(); + + class Availability + { + public: + Availability (bool avail, const std::string &reason) + : avail(avail), reason(reason) {}; + + bool avail; + std::string reason; + }; + + std::map availMap; + std::vector availArray; + std::vector reasonArray; + + virtual const std::string& chkDataCountExpr() const = 0; + virtual const std::string& chkDataIndexExpr() const = 0; + virtual const std::string& chkDataTextExpr() const = 0; + virtual const std::string& chkDataAvailExpr() const = 0; + virtual const std::string& chkDataReasonExpr() const = 0; +}; + +#endif // __CHECKRESPONSE_HPP diff --git a/AusRegEPPTK/se/Command.cpp b/AusRegEPPTK/se/Command.cpp new file mode 100644 index 0000000..1e55a44 --- /dev/null +++ b/AusRegEPPTK/se/Command.cpp @@ -0,0 +1,57 @@ +#include +#include + +#include "se/CLTRID.hpp" +#include "se/Command.hpp" +#include "se/CommandType.hpp" +#include "se/IllegalArgException.hpp" +#include "xml/XMLHelper.hpp" +#include "xml/XMLParser.hpp" +#include "common/ErrorPkg.hpp" + +Command::Command(const CommandType* commandType) + : extensionElement(NULL), cmdType(commandType) +{ + if (commandType == NULL) + { + throw IllegalArgException( + ErrorPkg::getMessage("se.command.type.missing")); + } + + command = xmlWriter->appendChild(xmlWriter->getRoot(), "command"); + cmdElement = xmlWriter->appendChild(command, cmdType->getCommandName()); +} + +std::string Command::toXMLImpl() +{ + XMLHelper::setTextContent( + xmlWriter->appendChild (command, "clTRID"), + CLTRID::nextVal()); + + return xmlWriter->toXML(); +} + +void Command::appendExtension(const CommandExtension& extension) +{ + try + { + if (extensionElement == NULL) + { + extensionElement = xmlWriter->appendChild(command, "extension"); + } + + extension.addToCommand(*this); + } + catch (std::exception &e) + { + userLogger->warning("Exception while appending an extension to command of type \'" + + cmdType->getCommandName() + "\': " + e.what()); + throw; + } + catch (...) + { + userLogger->warning("Unknown exception while appending an extension to command of type \'" + + cmdType->getCommandName() + "\'"); + throw; + } +} diff --git a/AusRegEPPTK/se/Command.hpp b/AusRegEPPTK/se/Command.hpp new file mode 100644 index 0000000..e3d0212 --- /dev/null +++ b/AusRegEPPTK/se/Command.hpp @@ -0,0 +1,47 @@ +#ifndef __COMMAND_HPP +#define __COMMAND_HPP + +#include "se/SendSE.hpp" +#include "se/Extension.hpp" +#include "se/CommandExtension.hpp" + +#include +#include + +class CommandType; +class XMLParser; + +/** + * Standard and extension EPP command service elements are modelled by + * subclasses of the Command class. All such classes provide the means to + * serialize their data to XML format as a valid EPP command, as well as + * constructors sufficiently flexible to create any valid EPP command of that + * type, and a method to query the type of command represented by an instance + * of the class. + */ +class Command : public SendSE +{ +public: + Command(const CommandType* commandType); + + const CommandType* getCommandType() const { return cmdType; } + XMLWriter* getXmlWriter() const { return xmlWriter; } + DOMElement* getExtensionElement() const { return extensionElement; } + void appendExtension(const CommandExtension& extension); +protected: + DOMElement *command; + DOMElement *cmdElement; + DOMElement *extensionElement; + const CommandType *cmdType; + + /** Establish the element and the command specific sub-element. + * Subclasses of Command that need to establish, for example, a specialised + * extension namespace for these elements should provide these + * two elements as arguments. + */ +private: + virtual std::string toXMLImpl(); +}; + +#endif // __COMMAND_HPP + diff --git a/AusRegEPPTK/se/CommandExtension.hpp b/AusRegEPPTK/se/CommandExtension.hpp new file mode 100644 index 0000000..6891850 --- /dev/null +++ b/AusRegEPPTK/se/CommandExtension.hpp @@ -0,0 +1,23 @@ +#ifndef __COMMAND_EXTENSION_HPP_ +#define __COMMAND_EXTENSION_HPP_ + +#include + +class Command; + +/** + * Any classes that implement an EPP command extension should implement this + * interface. The responsibility of implementor is to construct the subtree + * under the command extension element. + */ + + +class CommandExtension +{ + public: + CommandExtension() { } + virtual ~CommandExtension() { } + virtual void addToCommand(const Command &command) const = 0; +}; + +#endif /* __COMMAND_EXTENSION_HPP_ */ diff --git a/AusRegEPPTK/se/CommandType.hpp b/AusRegEPPTK/se/CommandType.hpp new file mode 100644 index 0000000..0154288 --- /dev/null +++ b/AusRegEPPTK/se/CommandType.hpp @@ -0,0 +1,31 @@ +#ifndef __COMMANDTYPE_HPP +#define __COMMANDTYPE_HPP + +#include "common/StringUtils.hpp" +#include + +/** + * Each EPP command is identified by an instance of CommandType. A CommandType + * has a command name, which is the name of the corresponding EPP command, and + * a response name, which is the name of the specific EPP response appropriate + * to this command type, if any. + * + */ +class CommandType +{ +public: + CommandType (const std::string& hashRef) + : hashVal (StringUtils::hashCode(hashRef)) {}; + + virtual ~CommandType() { } + + virtual std::string getCommandName() const = 0; + virtual std::string toString() const = 0; + + StringUtils::HashType hash() const { return hashVal; }; + +private: + StringUtils::HashType hashVal; +}; + +#endif // __COMMANDTYPE_HPP diff --git a/AusRegEPPTK/se/ContactCheckCommand.hpp b/AusRegEPPTK/se/ContactCheckCommand.hpp new file mode 100644 index 0000000..870205b --- /dev/null +++ b/AusRegEPPTK/se/ContactCheckCommand.hpp @@ -0,0 +1,34 @@ +#ifndef __CONTACT_CHECK_COMMAND_HPP +#define __CONTACT_CHECK_COMMAND_HPP + +#include "se/CheckCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * A ContactCheckCommand is used to check the availability of contact objects + * in a Registry. Instances of this class generate RFC3730 and RFC3733 + * compliant contact check EPP command service elements via the toXML method. + * + * @see ContactCheckResponse + */ +class ContactCheckCommand : public CheckCommand +{ +public: + /** + * Check the availability of the single identified contact. + * + * @param id The identifier of the contact to check the availability of. + */ + ContactCheckCommand (const std::string &id) + : CheckCommand (StandardObjectType::CONTACT(), id) {}; + + /** + * Check the availability of at least one contact. + * + * @param ids The identifiers of the contacts to check the availability of. + */ + ContactCheckCommand (std::vector &ids) + : CheckCommand (StandardObjectType::CONTACT(), ids) {}; +}; + +#endif // __CONTACT_CHECK_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactCheckCommandTest.cpp b/AusRegEPPTK/se/ContactCheckCommandTest.cpp new file mode 100644 index 0000000..befddbb --- /dev/null +++ b/AusRegEPPTK/se/ContactCheckCommandTest.cpp @@ -0,0 +1,40 @@ +#include "se/ContactCheckCommand.hpp" +#include "se/CLTRID.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + auto_ptr cmd(new ContactCheckCommand("JTKCON")); + + const string xml(cmd->toXML()); + ASSERT_EQ(xml, + "JTKCONJTKUTEST.20070101.010101.0"); + } + + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + vector ids; + ids.push_back("JTKCON1"); + ids.push_back("JTKCON2"); + auto_ptr cmd(new ContactCheckCommand(ids)); + const string xml(cmd->toXML()); + ASSERT_EQ(xml, + "JTKCON1JTKCON2JTKUTEST.20070101.010101.0"); + } +} + + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/ContactCheckResponse.cpp b/AusRegEPPTK/se/ContactCheckResponse.cpp new file mode 100644 index 0000000..b3367b7 --- /dev/null +++ b/AusRegEPPTK/se/ContactCheckResponse.cpp @@ -0,0 +1,61 @@ +#include "se/ContactCheckResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "common/StringUtils.hpp" + +using namespace std; + +const string& ContactCheckResponse::CON_CHKDATA_COUNT_EXPR() +{ + static const string expr = + ContactCheckResponse::exprReplace(CheckResponse::CHKDATA_COUNT_EXPR()); + return expr; +} + +const string& ContactCheckResponse::CON_CHKDATA_IND_EXPR() +{ + static const string expr = + ContactCheckResponse::exprReplace(CheckResponse::CHKDATA_IND_EXPR()); + return expr; +} + +const string& ContactCheckResponse::CON_CHKDATA_IDENT_EXPR() +{ + static const string expr = + ContactCheckResponse::exprReplace(CheckResponse::CHKDATA_IDENT_EXPR()); + return expr; +} + +const string& ContactCheckResponse::CON_CHKDATA_AVAIL_EXPR() +{ + static const string expr = + ContactCheckResponse::exprReplace(CheckResponse::CHKDATA_AVAIL_EXPR()); + return expr; +} + +const string& ContactCheckResponse::CON_CHKDATA_REASON_EXPR() +{ + static const string expr = + ContactCheckResponse::exprReplace(CheckResponse::CHKDATA_REASON_EXPR()); + return expr; +} + + +ContactCheckResponse::ContactCheckResponse() + : CheckResponse(StandardObjectType::CONTACT()) +{ } + + +string ContactCheckResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll( + StringUtils::replaceAll( + expr, DataResponse::OBJ(), + StandardObjectType::CONTACT()->getName()), + "IDENT", + "id"); +} + +void ContactCheckResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + CheckResponse::fromXML(xmlDoc); +} diff --git a/AusRegEPPTK/se/ContactCheckResponse.hpp b/AusRegEPPTK/se/ContactCheckResponse.hpp new file mode 100644 index 0000000..c745d5c --- /dev/null +++ b/AusRegEPPTK/se/ContactCheckResponse.hpp @@ -0,0 +1,50 @@ +#ifndef __CONTACT_CHECK_RESPONSE_HPP +#define __CONTACT_CHECK_RESPONSE_HPP + +#include "se/CheckResponse.hpp" + +/** + * Use this to access availability data for contacts as provided in an EPP + * contact check response compliant with RFCs 3730 and 3733. Such a service + * element is sent by a compliant EPP server in response to a valid contact + * check command, implemented by the ContactCheckCommand class. + * + * @see ContactCheckCommand + */ +class ContactCheckResponse : public CheckResponse +{ +public: + ContactCheckResponse(); + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + static const std::string &CON_CHKDATA_COUNT_EXPR(), + &CON_CHKDATA_IND_EXPR(), + &CON_CHKDATA_IDENT_EXPR(), + &CON_CHKDATA_AVAIL_EXPR(), + &CON_CHKDATA_REASON_EXPR(); + + const std::string& chkDataCountExpr() const + { + return CON_CHKDATA_COUNT_EXPR(); + } + const std::string& chkDataIndexExpr() const + { + return CON_CHKDATA_IND_EXPR(); + } + const std::string& chkDataTextExpr() const + { + return CON_CHKDATA_IDENT_EXPR(); + } + const std::string& chkDataAvailExpr() const + { + return CON_CHKDATA_AVAIL_EXPR(); + } + const std::string& chkDataReasonExpr() const + { + return CON_CHKDATA_REASON_EXPR(); + } + static std::string exprReplace (const std::string &expr); +}; +#endif // __CONTACT_CHECK_RESPONSE_HPP diff --git a/AusRegEPPTK/se/ContactCheckResponseTest.cpp b/AusRegEPPTK/se/ContactCheckResponseTest.cpp new file mode 100644 index 0000000..7afbf89 --- /dev/null +++ b/AusRegEPPTK/se/ContactCheckResponseTest.cpp @@ -0,0 +1,42 @@ +#include "se/ContactCheckResponse.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string xml = "Command completed successfullysh8013sah8013In use8013sahABC-1234554322-XYZ"; + + ContactCheckResponse response; + XMLParser parser; + std::auto_ptr doc(parser.parse(xml)); + response.fromXML(doc.get()); + ASSERT_EQ(response.isAvailable("sh8013"), true); + ASSERT_EQ(response.isAvailable("sah8013"), false); + ASSERT_EQ(response.isAvailable("8013sah"), true); + ASSERT_EQ(response.getReason("sah8013"), "In use"); + ASSERT_EQ(response.getReason(1), "In use"); + { + vector availList(response.getAvailableList()); + ASSERT_EQ(availList.size(), 3); + ASSERT_EQ(availList[0], true); + ASSERT_EQ(availList[1], false); + ASSERT_EQ(availList[2], true); + } + { + vector reasonList(response.getReasonList()); + ASSERT_EQ(reasonList.size(), 3); + ASSERT_EQ(reasonList[1], "In use"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/ContactCreateCommand.cpp b/AusRegEPPTK/se/ContactCreateCommand.cpp new file mode 100644 index 0000000..7707a46 --- /dev/null +++ b/AusRegEPPTK/se/ContactCreateCommand.cpp @@ -0,0 +1,74 @@ +#include "se/ContactCreateCommand.hpp" +#include "se/StandardObjectType.hpp" +#include "se/IntPostalInfo.hpp" +#include "xml/XMLHelper.hpp" +#include "se/PostalInfo.hpp" +#include "se/LocalPostalInfo.hpp" +#include "se/Disclose.hpp" +#include "se/IllegalArgException.hpp" +#include "common/ErrorPkg.hpp" + + +ContactCreateCommand::ContactCreateCommand (const std::string& id, + const std::string& pw, + const PostalInfo* postalInfo, + const std::string& email, + const LocalPostalInfo* localPostalInfo, + const std::string* voice, + const std::string* voiceExt, + const std::string* fax, + const std::string* faxExt, + const Disclose* disclose) + : CreateCommand(StandardObjectType::CONTACT(), id) +{ + if (postalInfo == NULL && localPostalInfo == NULL) + { + throw IllegalArgException( + ErrorPkg::getMessage("se.contact.create.missing_arg")); + } + + if (dynamic_cast(postalInfo)) + { + postalInfo->appendToElement(xmlWriter, objElement); + if (localPostalInfo) + { + localPostalInfo->appendToElement(xmlWriter, objElement); + } + } + else if (dynamic_cast(postalInfo)) + { + postalInfo->appendToElement(xmlWriter, objElement); + } + + if (voice) + { + if (voiceExt) + xmlWriter->appendChild (objElement, "voice", *voice, "x", *voiceExt); + else + XMLHelper::setTextContent + (xmlWriter->appendChild (objElement, "voice"), *voice); + } + + if (fax) + { + if (faxExt) + xmlWriter->appendChild (objElement, "fax", *fax, "x", *faxExt); + else + XMLHelper::setTextContent + (xmlWriter->appendChild (objElement, "fax"), *fax); + } + + XMLHelper::setTextContent + (xmlWriter->appendChild (objElement, "email"), email); + + XMLHelper::setTextContent + (xmlWriter->appendChild + (xmlWriter->appendChild + (objElement, + "authInfo"), + "pw"), + pw); + + if (disclose) + disclose->appendToElement (xmlWriter, objElement); +} diff --git a/AusRegEPPTK/se/ContactCreateCommand.hpp b/AusRegEPPTK/se/ContactCreateCommand.hpp new file mode 100644 index 0000000..ae8ba3a --- /dev/null +++ b/AusRegEPPTK/se/ContactCreateCommand.hpp @@ -0,0 +1,62 @@ +#ifndef __CONTACT_CREATE_COMMAND_HPP +#define __CONTACT_CREATE_COMMAND_HPP + +#include "se/CreateCommand.hpp" +class PostalInfo; +class LocalPostalInfo; +class Disclose; + +/** + * Use this to request that a contact object be provisioned in an EPP Registry. + * Instances of this class generate RFC3730 and RFC3733 compliant contact + * create EPP command service elements via the toXML method. + * + * @see ContactCreateResponse + */ +class ContactCreateCommand : public CreateCommand +{ +public: + /** + * Provision a contact with the specified details. This constructor allows + * specification of any and all parameters for a contact create command. + * + * @param id The new contact's identifier. + * + * @param pw The password to assign to the contact (also known as authInfo + * or authorisation information). + * + * @param postalInfo Postal information for the new contact. If + * localPostalInfo is also specified, then this MUST be IntPostalInfo. + * + * @param localPostalInfo Local postal information for the new contact. + * + * @param voice The contact's voice telephone number. + * + * @param voiceExt The extension for the contact's voice telephone number, + * if applicable. + * + * @param fax The contact's fax telephone number. + * + * @param faxExt The extension for the contact's fax telephone number, if + * applicable. + * + * @param email The contact's email address. + * + * @param disclose Disclosure request information, which may modify what + * information is disclosed by the Registry system in response to queries. + * Note that the server may not accept specification of this parameter, or + * may ignore any requests described by this parameter. + */ + ContactCreateCommand (const std::string& id, + const std::string& pw, + const PostalInfo* postalInfo, + const std::string& email, + const LocalPostalInfo* localPostalInfo = NULL, + const std::string* voice = NULL, + const std::string* voiceExt = NULL, + const std::string* fax = NULL, + const std::string* faxExt = NULL, + const Disclose* disclose = NULL); +}; + +#endif // __CONTACT_CREATE_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactCreateResponse.cpp b/AusRegEPPTK/se/ContactCreateResponse.cpp new file mode 100644 index 0000000..ef2cc70 --- /dev/null +++ b/AusRegEPPTK/se/ContactCreateResponse.cpp @@ -0,0 +1,41 @@ +#include "se/ContactCreateResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "common/StringUtils.hpp" + +const std::string ContactCreateResponse::CON_CR_DATE_EXPR + (ContactCreateResponse::exprReplace (CreateResponse::CR_DATE_EXPR())); + +const std::string ContactCreateResponse::CON_ID_EXPR + (ContactCreateResponse::exprReplace + (CreateResponse::CRE_DATA_EXPR()) + + "/contact:id/text()"); + +ContactCreateResponse::ContactCreateResponse() + : CreateResponse(StandardObjectType::CONTACT()) +{ } + + +void ContactCreateResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + CreateResponse::fromXML(xmlDoc); + + try + { + id = xmlDoc->getNodeValue (CON_ID_EXPR); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException p; + p.causedBy(e); + throw p; + } +} + + +std::string ContactCreateResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + CreateResponse::OBJ(), + StandardObjectType::CONTACT()->getName()); +} diff --git a/AusRegEPPTK/se/ContactCreateResponse.hpp b/AusRegEPPTK/se/ContactCreateResponse.hpp new file mode 100644 index 0000000..9c6555e --- /dev/null +++ b/AusRegEPPTK/se/ContactCreateResponse.hpp @@ -0,0 +1,35 @@ +#ifndef __CONTACT_CREATE_RESPONSE_HPP +#define __CONTACT_CREATE_RESPONSE_HPP + +#include "se/CreateResponse.hpp" + +/** + * Use this to access create data for a contact as provided in an EPP contact + * create response compliant with RFCs 3730 and 3733. Such a service element + * is sent by a compliant EPP server in response to a valid contact create + * command, implemented by the ContactCreateCommand. + * + * @see ContactCreateCommand + */ +class ContactCreateResponse : public CreateResponse +{ +public: + ContactCreateResponse(); + + const std::string & getID() const { return id; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + const std::string & crDateExpr() const { return CON_CR_DATE_EXPR; }; + + static std::string exprReplace (const std::string &expr); + +private: + static const std::string CON_CR_DATE_EXPR, + CON_ID_EXPR; + + std::string id; +}; + +#endif // __CONTACT_CREATE_RESPONSE_HPP diff --git a/AusRegEPPTK/se/ContactDeleteCommand.hpp b/AusRegEPPTK/se/ContactDeleteCommand.hpp new file mode 100644 index 0000000..8cfe0c4 --- /dev/null +++ b/AusRegEPPTK/se/ContactDeleteCommand.hpp @@ -0,0 +1,24 @@ +#ifndef __CONTACT_DELETE_COMMAND_HPP +#define __CONTACT_DELETE_COMMAND_HPP + +#include "se/DeleteCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * Use this to request that a contact object be deleted from an EPP Registry. + * Instances of this class generate RFC3730 and RFC3733 compliant contact + * delete EPP command service elements via the toXML method. + */ +class ContactDeleteCommand : public DeleteCommand +{ +public: + /** + * Delete the identified contact. + * + * @param id The identifier of the contact to delete. + */ + ContactDeleteCommand (const std::string &id) + : DeleteCommand (StandardObjectType::CONTACT(), id) {}; +}; + +#endif // __CONTACT_DELETE_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactDeleteCommandTest.cpp b/AusRegEPPTK/se/ContactDeleteCommandTest.cpp new file mode 100644 index 0000000..7d3ec12 --- /dev/null +++ b/AusRegEPPTK/se/ContactDeleteCommandTest.cpp @@ -0,0 +1,28 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/ContactDeleteCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + ContactDeleteCommand cmd("JTKCON"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "JTKCONJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/ContactInfoCommand.hpp b/AusRegEPPTK/se/ContactInfoCommand.hpp new file mode 100644 index 0000000..66febb3 --- /dev/null +++ b/AusRegEPPTK/se/ContactInfoCommand.hpp @@ -0,0 +1,38 @@ +#ifndef __CONTACT_INFO_COMMAND_HPP +#define __CONTACT_INFO_COMMAND_HPP + +#include "se/InfoCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * Use this to request information about a contact object provisioned in an EPP + * Registry. Instances of this class generate RFC3730 and RFC3733 compliant + * contact info EPP command service elements via the toXML method. + * + * @see ContactInfoResponse + */ +class ContactInfoCommand : public InfoCommand +{ +public: + /** + * Create a contact info command with the specified identifier. + * + * @param id The identifier of the contact to retrieve information about. + */ + ContactInfoCommand (const std::string &id) + : InfoCommand (StandardObjectType::CONTACT(), id) {}; + + /** + * Create a contact info command with the specified identifier. + * + * @param id The identifier of the contact to retrieve information about. + * + * @param pw The password of the identified contact object (also known as + * authInfo or authorisation information). + */ + ContactInfoCommand (const std::string &id, const std::string &pw) + : InfoCommand (StandardObjectType::CONTACT(), id, pw) {}; +}; + + +#endif // __CONTACT_INFO_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactInfoCommandTest.cpp b/AusRegEPPTK/se/ContactInfoCommandTest.cpp new file mode 100644 index 0000000..a19a743 --- /dev/null +++ b/AusRegEPPTK/se/ContactInfoCommandTest.cpp @@ -0,0 +1,36 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/ContactInfoCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + ContactInfoCommand cmd("C100000-AR"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "C100000-ARJTKUTEST.20070101.010101.0"); + } + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + ContactInfoCommand cmd("C100000-AR", "jtkUT3st"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "C100000-ARjtkUT3stJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/ContactInfoResponse.cpp b/AusRegEPPTK/se/ContactInfoResponse.cpp new file mode 100644 index 0000000..9d808cf --- /dev/null +++ b/AusRegEPPTK/se/ContactInfoResponse.cpp @@ -0,0 +1,253 @@ +#include "se/ContactInfoResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "se/IntPostalInfo.hpp" +#include "se/LocalPostalInfo.hpp" +#include "se/DiscloseItem.hpp" + +const std::string ContactInfoResponse::CON_ROID_EXPR + (exprReplace(InfoResponse::ROID_EXPR())); + +const std::string ContactInfoResponse::CON_CR_ID_EXPR + (exprReplace(InfoResponse::CR_ID_EXPR())); + +const std::string ContactInfoResponse::CON_UP_ID_EXPR + (exprReplace(InfoResponse::UP_ID_EXPR())); + +const std::string ContactInfoResponse::CON_CL_ID_EXPR + (exprReplace(InfoResponse::CL_ID_EXPR())); + +const std::string ContactInfoResponse::CON_CR_DATE_EXPR + (exprReplace(InfoResponse::CR_DATE_EXPR())); + +const std::string ContactInfoResponse::CON_UP_DATE_EXPR + (exprReplace(InfoResponse::UP_DATE_EXPR())); + +const std::string ContactInfoResponse::CON_TR_DATE_EXPR + (exprReplace(InfoResponse::TR_DATE_EXPR())); + +const std::string ContactInfoResponse::CON_STATUS_COUNT_EXPR + (exprReplace(InfoResponse::STATUS_COUNT_EXPR())); + +const std::string ContactInfoResponse::CON_STATUS_EXPR + (exprReplace(InfoResponse::STATUS_EXPR())); + +const std::string ContactInfoResponse::CON_INF_DATA_EXPR + (exprReplace(InfoResponse::INF_DATA_EXPR())); + +const std::string ContactInfoResponse::CON_ID_EXPR + (CON_INF_DATA_EXPR + "/contact:id/text()"); + +const std::string ContactInfoResponse::CON_PW_EXPR + (CON_INF_DATA_EXPR + "/contact:authInfo/contact:pw/text()"); + +const std::string ContactInfoResponse::CON_PINFO_INT_EXPR + (CON_INF_DATA_EXPR + "/contact:postalInfo[@type='int']"); + +const std::string ContactInfoResponse::CON_PINFO_INT_NAME_EXPR + (CON_PINFO_INT_EXPR + "/contact:name/text()"); + +const std::string ContactInfoResponse::CON_PINFO_INT_ORG_EXPR + (CON_PINFO_INT_EXPR + "/contact:org/text()"); + +const std::string ContactInfoResponse::CON_PINFO_INT_STREET_EXPR + (CON_PINFO_INT_EXPR + "/contact:addr/contact:street"); + +const std::string ContactInfoResponse::CON_PINFO_INT_CITY_EXPR + (CON_PINFO_INT_EXPR + "/contact:addr/contact:city/text()"); + +const std::string ContactInfoResponse::CON_PINFO_INT_SP_EXPR + (CON_PINFO_INT_EXPR + "/contact:addr/contact:sp/text()"); + +const std::string ContactInfoResponse::CON_PINFO_INT_PC_EXPR + (CON_PINFO_INT_EXPR + "/contact:addr/contact:pc/text()"); + +const std::string ContactInfoResponse::CON_PINFO_INT_CC_EXPR + (CON_PINFO_INT_EXPR + "/contact:addr/contact:cc/text()"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_EXPR + (CON_INF_DATA_EXPR + "/contact:postalInfo[@type='loc']"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_NAME_EXPR + (CON_PINFO_LOC_EXPR + "/contact:name/text()"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_ORG_EXPR + (CON_PINFO_LOC_EXPR + "/contact:org/text()"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_STREET_EXPR + (CON_PINFO_LOC_EXPR + "/contact:addr/contact:street"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_CITY_EXPR + (CON_PINFO_LOC_EXPR + "/contact:addr/contact:city/text()"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_SP_EXPR + (CON_PINFO_LOC_EXPR + "/contact:addr/contact:sp/text()"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_PC_EXPR + (CON_PINFO_LOC_EXPR + "/contact:addr/contact:pc/text()"); + +const std::string ContactInfoResponse::CON_PINFO_LOC_CC_EXPR + (CON_PINFO_LOC_EXPR + "/contact:addr/contact:cc/text()"); + +const std::string ContactInfoResponse::CON_VOICE_EXPR + (CON_INF_DATA_EXPR + "/contact:voice/text()"); + +const std::string ContactInfoResponse::CON_VOICEX_EXPR + (CON_INF_DATA_EXPR + "/contact:voice/@x"); + +const std::string ContactInfoResponse::CON_FAX_EXPR + (CON_INF_DATA_EXPR + "/contact:fax/text()"); + +const std::string ContactInfoResponse::CON_FAXX_EXPR + (CON_INF_DATA_EXPR + "/contact:fax/@x"); + +const std::string ContactInfoResponse::CON_EMAIL_EXPR + (CON_INF_DATA_EXPR + "/contact:email/text()"); + +const std::string ContactInfoResponse::CON_DISCLOSE_EXPR + (CON_INF_DATA_EXPR + "/contact:disclose"); + +const std::string ContactInfoResponse::CON_DISCLOSE_COUNT_EXPR + ("count(" + CON_DISCLOSE_EXPR + "/*)"); + +const std::string ContactInfoResponse::CON_DISCLOSE_FLAG_EXPR + (CON_DISCLOSE_EXPR + "/@flag"); + +const std::string ContactInfoResponse::CON_DISCLOSE_CHILD_EXPR + (CON_DISCLOSE_EXPR + "/*[IDX]"); + +const std::string ContactInfoResponse::CON_DISCLOSE_NAME_EXPR ("/local-name()"); +const std::string ContactInfoResponse::CON_DISCLOSE_TYPE_EXPR ("/@type"); + +ContactInfoResponse::ContactInfoResponse() + : InfoResponse (StandardObjectType::CONTACT()), + intPostalInfo(NULL), + locPostalInfo(NULL), + voiceX(-1), + faxX(-1) +{ } + +ContactInfoResponse::~ContactInfoResponse() +{ + if (intPostalInfo) + delete intPostalInfo; + if (locPostalInfo) + delete locPostalInfo; +} + +const LocalPostalInfo & ContactInfoResponse::getLocPostalInfo() const + throw (EmptyPostalInfoException) +{ + if (locPostalInfo) + return *locPostalInfo; + else + throw EmptyPostalInfoException(); +} + +const IntPostalInfo & ContactInfoResponse::getIntPostalInfo() const + throw (EmptyPostalInfoException) +{ + if (intPostalInfo) + return *intPostalInfo; + else + throw EmptyPostalInfoException(); +} + +bool ContactInfoResponse::isDisclosed() const + throw (NoDiscloseItemsException) +{ + if (items.size() > 0) + return discloseFlag; + else + throw NoDiscloseItemsException(); +} + +void ContactInfoResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + debugLogger->LOG_FINEST("enter"); + + InfoResponse::fromXML (xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + id = xmlDoc->getNodeValue (CON_ID_EXPR); + + std::string iName = xmlDoc->getNodeValue (CON_PINFO_INT_NAME_EXPR); + std::string iOrg = xmlDoc->getNodeValue (CON_PINFO_INT_ORG_EXPR); + std::vector iStreet = + xmlDoc->getNodeValues (CON_PINFO_INT_STREET_EXPR); + std::string iCity = xmlDoc->getNodeValue (CON_PINFO_INT_CITY_EXPR); + std::string iSP = xmlDoc->getNodeValue (CON_PINFO_INT_SP_EXPR); + std::string iPC = xmlDoc->getNodeValue (CON_PINFO_INT_PC_EXPR); + std::string iCC = xmlDoc->getNodeValue (CON_PINFO_INT_CC_EXPR); + + intPostalInfo = + new IntPostalInfo(iName, iOrg, iStreet, iCity, iSP, iPC, iCC); + + std::string lName = xmlDoc->getNodeValue (CON_PINFO_LOC_NAME_EXPR); + + if (lName.length() > 0) + { + std::string lOrg = xmlDoc->getNodeValue (CON_PINFO_LOC_ORG_EXPR); + std::vector lStreet = + xmlDoc->getNodeValues(CON_PINFO_LOC_STREET_EXPR); + std::string lCity = xmlDoc->getNodeValue(CON_PINFO_LOC_CITY_EXPR); + std::string lSP = xmlDoc->getNodeValue(CON_PINFO_LOC_SP_EXPR); + std::string lPC = xmlDoc->getNodeValue(CON_PINFO_LOC_PC_EXPR); + std::string lCC = xmlDoc->getNodeValue(CON_PINFO_LOC_CC_EXPR); + + locPostalInfo = + new LocalPostalInfo(lName, lOrg, lStreet, lCity, lSP, lPC, lCC); + } + + voice = xmlDoc->getNodeValue(CON_VOICE_EXPR); + std::string voiceXStr = xmlDoc->getNodeValue(CON_VOICEX_EXPR); + if (voiceXStr.length() > 0) + voiceX = atoi(voiceXStr.c_str()); + + fax = xmlDoc->getNodeValue (CON_FAX_EXPR); + std::string faxXStr = xmlDoc->getNodeValue (CON_FAXX_EXPR); + if (faxXStr.length() > 0) + faxX = atoi(faxXStr.c_str()); + + email = xmlDoc->getNodeValue (CON_EMAIL_EXPR); + pw = xmlDoc->getNodeValue (CON_PW_EXPR); + std::string flagStr = xmlDoc->getNodeValue (CON_DISCLOSE_FLAG_EXPR); + discloseFlag = (flagStr == "1") ? true : false; + + int count = xmlDoc->getNodeCount (CON_DISCLOSE_COUNT_EXPR); + for (int i = 0; i < count; i++) + { + std::string qry = ReceiveSE::replaceIndex (CON_DISCLOSE_CHILD_EXPR, i+1); + std::string childName = + xmlDoc->getNodeValue (qry + CON_DISCLOSE_NAME_EXPR); + std::string childType = + xmlDoc->getNodeValue (qry + CON_DISCLOSE_TYPE_EXPR); + + if (childType.length() == 0) + items.push_back (DiscloseItem(childName)); + else + items.push_back (DiscloseItem(childName, childType)); + } + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException p; + p.causedBy(e); + throw p; + } + debugLogger->LOG_FINEST("exit"); +} + + +std::string ContactInfoResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + DataResponse::OBJ(), + StandardObjectType::CONTACT()->getName()); +} + diff --git a/AusRegEPPTK/se/ContactInfoResponse.hpp b/AusRegEPPTK/se/ContactInfoResponse.hpp new file mode 100644 index 0000000..9c48978 --- /dev/null +++ b/AusRegEPPTK/se/ContactInfoResponse.hpp @@ -0,0 +1,122 @@ +#ifndef __CONTACT_INFO_RESPONSE_HPP +#define __CONTACT_INFO_RESPONSE_HPP + +#include "se/InfoResponse.hpp" +class IntPostalInfo; +class LocalPostalInfo; +class DiscloseItem; + +#include "common/EPPException.hpp" + +class NoDiscloseItemsException : public EPPException +{ +public: + NoDiscloseItemsException() + : EPPException("NoDiscloseItemsException") { } + EPP_EXCEPTION(NoDiscloseItemsException); +}; + +class EmptyPostalInfoException : public EPPException +{ +public: + EmptyPostalInfoException() + : EPPException("EmptyPostalInfoException") { } + EPP_EXCEPTION(EmptyPostalInfoException); +}; + +/** + * Use this to access contact object information as provided in an EPP contact + * info response compliant with RFCs 3730 and 3733. Such a service element is + * sent by a compliant EPP server in response to a valid contact info command, + * implemented by the ContactInfoCommand class. + * + * @see ContactInfoCommand + */ +class ContactInfoResponse : public InfoResponse +{ +public: + ContactInfoResponse (); + virtual ~ContactInfoResponse(); + + const std::string & getID() const { return id; }; + const IntPostalInfo & getIntPostalInfo() const + throw (EmptyPostalInfoException); + const LocalPostalInfo & getLocPostalInfo() const + throw (EmptyPostalInfoException); + const std::string & getVoice() const { return voice; }; + int getVoiceExtension() const { return voiceX; }; + const std::string & getFax() const { return fax; }; + int getFaxExtension() const { return faxX; }; + const std::string & getEmail() const { return email; }; + const std::string & getPassword() const { return pw; }; + const std::vector & getDiscloseItems() const { return items; }; + + bool isDisclosed() const throw (NoDiscloseItemsException); + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + + +protected: + const std::string & roidExpr() const { return CON_ROID_EXPR; }; + const std::string & crIDExpr() const { return CON_CR_ID_EXPR; }; + const std::string & upIDExpr() const { return CON_UP_ID_EXPR; }; + const std::string & clIDExpr() const { return CON_CL_ID_EXPR; }; + const std::string & crDateExpr() const { return CON_CR_DATE_EXPR; }; + const std::string & upDateExpr() const { return CON_UP_DATE_EXPR; }; + const std::string & trDateExpr() const { return CON_TR_DATE_EXPR; }; + const std::string & statusExpr() const { return CON_STATUS_EXPR; }; + const std::string & statusCountExpr() const { return CON_STATUS_COUNT_EXPR; }; + + static std::string exprReplace (const std::string &expr); + + +private: + static const std::string CON_ROID_EXPR, + CON_CR_ID_EXPR, + CON_UP_ID_EXPR, + CON_CL_ID_EXPR, + CON_CR_DATE_EXPR, + CON_UP_DATE_EXPR, + CON_TR_DATE_EXPR, + CON_STATUS_COUNT_EXPR, + CON_STATUS_EXPR, + CON_INF_DATA_EXPR, + CON_ID_EXPR, + CON_PW_EXPR, + CON_PINFO_INT_EXPR, + CON_PINFO_INT_NAME_EXPR, + CON_PINFO_INT_ORG_EXPR, + CON_PINFO_INT_STREET_EXPR, + CON_PINFO_INT_CITY_EXPR, + CON_PINFO_INT_SP_EXPR, + CON_PINFO_INT_PC_EXPR, + CON_PINFO_INT_CC_EXPR, + CON_PINFO_LOC_EXPR, + CON_PINFO_LOC_NAME_EXPR, + CON_PINFO_LOC_ORG_EXPR, + CON_PINFO_LOC_STREET_EXPR, + CON_PINFO_LOC_CITY_EXPR, + CON_PINFO_LOC_SP_EXPR, + CON_PINFO_LOC_PC_EXPR, + CON_PINFO_LOC_CC_EXPR, + CON_VOICE_EXPR, + CON_VOICEX_EXPR, + CON_FAX_EXPR, + CON_FAXX_EXPR, + CON_EMAIL_EXPR, + CON_DISCLOSE_EXPR, + CON_DISCLOSE_COUNT_EXPR, + CON_DISCLOSE_FLAG_EXPR, + CON_DISCLOSE_CHILD_EXPR, + CON_DISCLOSE_NAME_EXPR, + CON_DISCLOSE_TYPE_EXPR; + + std::string id, voice, fax, email, pw; + IntPostalInfo *intPostalInfo; + LocalPostalInfo *locPostalInfo; + int voiceX, faxX; + bool discloseFlag; + std::vector items; +}; + +#endif // __CONTACT_INFO_RESPONSE_HPP diff --git a/AusRegEPPTK/se/ContactInfoResponseTest.cpp b/AusRegEPPTK/se/ContactInfoResponseTest.cpp new file mode 100644 index 0000000..58e6fa9 --- /dev/null +++ b/AusRegEPPTK/se/ContactInfoResponseTest.cpp @@ -0,0 +1,37 @@ +#include "se/ContactInfoResponse.hpp" +#include "se/IntPostalInfo.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string xml( + "Command completed successfullysh8013SH8013-REPJohn DoeExample Inc.123 Example Dr.Suite 100DullesVA20166-6503US+1.7035555555+1.7035555556jdoe@example.comClientYClientX1999-04-03T22:00:00.0ZClientX1999-12-03T09:00:00.0Z2000-04-08T09:00:00.0Z2fooBARABC-1234554322-XYZ"); + + ContactInfoResponse response; + XMLParser parser; + std::auto_ptr doc(parser.parse(xml)); + response.fromXML(doc.get()); + + { + vector streets = response.getIntPostalInfo().getStreet(); + + ASSERT_EQ(streets[0], "123 Example Dr."); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/ContactNotificationResponse.cpp b/AusRegEPPTK/se/ContactNotificationResponse.cpp new file mode 100644 index 0000000..3b9d64a --- /dev/null +++ b/AusRegEPPTK/se/ContactNotificationResponse.cpp @@ -0,0 +1,57 @@ +#include "se/ContactNotificationResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "common/StringUtils.hpp" + +using namespace std; + +ContactNotificationResponse::ContactNotificationResponse() + : NotificationResponse(StandardObjectType::CONTACT()) +{ +} + +string ContactNotificationResponse::exprReplace(const string& expr) +{ + return StringUtils::replaceAll( + StringUtils::replaceAll( + expr, + DataResponse::OBJ(), + StandardObjectType::CONTACT()->getName()), + NotificationResponse::IDENT(), + StandardObjectType::CONTACT()->getIdentType()); +} + +const string& ContactNotificationResponse::CON_ID_EXPR() +{ + static const string expr = ContactNotificationResponse::exprReplace( + NotificationResponse::IDENT_EXPR()); + return expr; +} + +const string& ContactNotificationResponse::CON_RESULT_EXPR() +{ + static const string expr = ContactNotificationResponse::exprReplace( + NotificationResponse::RESULT_EXPR()); + return expr; +} + +const string& ContactNotificationResponse::CON_CLTRID_EXPR() +{ + static const string expr = ContactNotificationResponse::exprReplace( + NotificationResponse::CLTRID_EXPR()); + return expr; +} + +const string& ContactNotificationResponse::CON_SVTRID_EXPR() +{ + static const string expr = ContactNotificationResponse::exprReplace( + NotificationResponse::SVTRID_EXPR()); + return expr; +} + +const string& ContactNotificationResponse::CON_PADATE_EXPR() +{ + static const string expr = ContactNotificationResponse::exprReplace( + NotificationResponse::PADATE_EXPR()); + return expr; +} + diff --git a/AusRegEPPTK/se/ContactNotificationResponse.hpp b/AusRegEPPTK/se/ContactNotificationResponse.hpp new file mode 100644 index 0000000..dceeee2 --- /dev/null +++ b/AusRegEPPTK/se/ContactNotificationResponse.hpp @@ -0,0 +1,35 @@ +#ifndef CONTACT_NOTIFICATION_RESPONSE +#define CONTACT_NOTIFICATION_RESPONSE + +#include "se/NotificationResponse.hpp" + +using namespace std; + +/** + * Notification data specific to contact objects. Refer to + * {@link NotificationResponse} for further details. + */ +class ContactNotificationResponse : public NotificationResponse +{ + public: + ContactNotificationResponse(); + + protected: + const string& identifierExpr() const { return CON_ID_EXPR(); }; + const string& resultExpr() const { return CON_RESULT_EXPR(); }; + const string& cltridExpr() const { return CON_CLTRID_EXPR(); }; + const string& svtridExpr() const { return CON_SVTRID_EXPR(); }; + const string& padateExpr() const { return CON_PADATE_EXPR(); }; + + static string exprReplace(const string &expr); + + private: + static const string& CON_ID_EXPR(); + static const string& CON_RESULT_EXPR(); + static const string& CON_CLTRID_EXPR(); + static const string& CON_SVTRID_EXPR(); + static const string& CON_PADATE_EXPR(); +}; + +#endif /* CONTACT_NOTIFICATION_RESPONSE */ + diff --git a/AusRegEPPTK/se/ContactTransferApproveCommand.hpp b/AusRegEPPTK/se/ContactTransferApproveCommand.hpp new file mode 100644 index 0000000..6c731c5 --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferApproveCommand.hpp @@ -0,0 +1,32 @@ +#ifndef __CONTACT_TRANSFER_APPROVE_COMMAND_HPP +#define __CONTACT_TRANSFER_APPROVE_COMMAND_HPP + +#include "se/ContactTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to approve the transfer of a contact object currently pending + * transfer. The contact object must be sponsored by the client attempting to + * approve the transfer. Instances of this class generate RFC3730 and RFC3733 + * compliant contact transfer EPP command service elements via the toXML method + * with the transfer operation set to "approve". + * + * @see ContactTransferResponse + */ +class ContactTransferApproveCommand : public ContactTransferCommand +{ +public: + /** + * Create a contact transfer command for the idenfitied contact, specifying + * the designated password and the 'approve' transfer operation. + * + * @param id The identifier of the contact to approve transfer of. + * + * @param pw The identified contact's password. + */ + ContactTransferApproveCommand (const std::string &id, const std::string &pw) + : ContactTransferCommand (TransferOp::APPROVE(), id, pw) + { } +}; + +#endif // __CONTACT_TRANSFER_APPROVE_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactTransferCancelCommand.hpp b/AusRegEPPTK/se/ContactTransferCancelCommand.hpp new file mode 100644 index 0000000..365b2db --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferCancelCommand.hpp @@ -0,0 +1,32 @@ +#ifndef __CONTACT_TRANSFER_CANCEL_COMMAND_HPP +#define __CONTACT_TRANSFER_CANCEL_COMMAND_HPP + +#include "se/ContactTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to cancel the transfer of a contact object currently pending + * transfer. The transfer must have been initiated via a transfer request by + * the client attempting to cancel the transfer. Instances of this class + * generate RFC3730 and RFC3733 compliant contact transfer EPP command service + * elements via the toXML method with the transfer operation set to "cancel". + * + * @see ContactTransferResponse + */ +class ContactTransferCancelCommand : public ContactTransferCommand +{ +public: + /** + * Create a contact transfer command for the idenfitied contact, specifying + * the designated password and the 'cancel' transfer operation. + * + * @param id The identifier of the contact to cancel transfer of. + * + * @param pw The identified contact's password. + */ + ContactTransferCancelCommand (const std::string &id, const std::string &pw) + : ContactTransferCommand (TransferOp::CANCEL(), id, pw) + { } +}; + +#endif // __CONTACT_TRANSFER_CANCEL_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactTransferCommand.hpp b/AusRegEPPTK/se/ContactTransferCommand.hpp new file mode 100644 index 0000000..fabb2e6 --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferCommand.hpp @@ -0,0 +1,27 @@ +#ifndef __CONTACT_TRANSFER_COMMAND_HPP +#define __CONTACT_TRANSFER_COMMAND_HPP + +#include "se/TransferCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * The superclass of all contact transfer command classes. Subclasses are + * responsible for specifying the kind of transfer operation, but hiding the + * implementation from the user. + */ +class ContactTransferCommand : public TransferCommand +{ +public: + ContactTransferCommand (const TransferOp *operation, const std::string &id) + : TransferCommand (StandardObjectType::CONTACT(), operation, id) + { } + + ContactTransferCommand (const TransferOp *operation, + const std::string &id, + const std::string &pw) + : TransferCommand (StandardObjectType::CONTACT(), + operation, id, pw) + { } +}; + +#endif // __CONTACT_TRANSFER_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactTransferQueryCommand.hpp b/AusRegEPPTK/se/ContactTransferQueryCommand.hpp new file mode 100644 index 0000000..902058f --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferQueryCommand.hpp @@ -0,0 +1,41 @@ +#ifndef __CONTACT_TRANSFER_QUERY_COMMAND_HPP +#define __CONTACT_TRANSFER_QUERY_COMMAND_HPP + +#include "se/ContactTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to query the transfer state of a contact object. Instances of this + * class generate RFC3730 and RFC3733 compliant contact transfer EPP command + * service elements via the toXML method with the transfer operation set to + * "query". + * + * @see ContactTransferResponse + */ +class ContactTransferQueryCommand : public ContactTransferCommand +{ +public: + /** + * Create a contact transfer command for the idenfitied contact, specifying + * the 'query' transfer operation. + * + * @param id The identifier of the contact to query the transfer state of. + */ + ContactTransferQueryCommand (const std::string &id) + : ContactTransferCommand (TransferOp::QUERY(), id) + { } + + /** + * Create a contact transfer command for the idenfitied contact, specifying + * the designated password and the 'query' transfer operation. + * + * @param id The identifier of the contact to query the transfer state of. + * + * @param pw The identified contact's password. + */ + ContactTransferQueryCommand (const std::string &id, const std::string &pw) + : ContactTransferCommand (TransferOp::QUERY(), id, pw) + { } +}; + +#endif // __CONTACT_TRANSFER_QUERY_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactTransferRejectCommand.hpp b/AusRegEPPTK/se/ContactTransferRejectCommand.hpp new file mode 100644 index 0000000..d4a1213 --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferRejectCommand.hpp @@ -0,0 +1,32 @@ +#ifndef __CONTACT_TRANSFER_REJECT_COMMAND_HPP +#define __CONTACT_TRANSFER_REJECT_COMMAND_HPP + +#include "se/ContactTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to reject the transfer of a contact object currently pending + * transfer. The contact object must be sponsored by the client attempting to + * reject the transfer. Instances of this class generate RFC3730 and RFC3733 + * compliant contact transfer EPP command service elements via the toXML method + * with the transfer operation set to "reject". + * + * @see ContactTransferResponse + */ +class ContactTransferRejectCommand : public ContactTransferCommand +{ +public: + /** + * Create a contact transfer command for the idenfitied contact, specifying + * the designated password and the 'reject' transfer operation. + * + * @param id The identifier of the contact to reject transfer of. + * + * @param pw The identified contact's password. + */ + ContactTransferRejectCommand(const std::string &id, const std::string &pw) + : ContactTransferCommand(TransferOp::REJECT(), id, pw) + { } +}; + +#endif // __CONTACT_TRANSFER_REJECT_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactTransferRequestCommand.hpp b/AusRegEPPTK/se/ContactTransferRequestCommand.hpp new file mode 100644 index 0000000..0888178 --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferRequestCommand.hpp @@ -0,0 +1,34 @@ +#ifndef __CONTACT_TRANSFER_REQUEST_COMMAND_HPP +#define __CONTACT_TRANSFER_REQUEST_COMMAND_HPP + +#include "se/ContactTransferCommand.hpp" +#include "se/TransferOp.hpp" + +#include + +/** + * Use this to request the transfer of a contact object from another client. + * The contact object MUST NOT be sponsored by the client attempting to request + * the transfer. Instances of this class generate RFC3730 and RFC3733 + * compliant contact transfer EPP command service elements via the toXML method + * with the transfer operation set to "request". + * + * @see ContactTransferResponse + */ +class ContactTransferRequestCommand : public ContactTransferCommand +{ +public: + /** + * Create a contact transfer command for the idenfitied contact, specifying + * the designated password and the 'request' transfer operation. + * + * @param id The identifier of the contact to request transfer of. + * + * @param pw The identified contact's password. + */ + ContactTransferRequestCommand (const std::string &id, const std::string &pw) + : ContactTransferCommand (TransferOp::REQUEST(), id, pw) + { } +}; + +#endif // __CONTACT_TRANSFER_REQUEST_COMMAND_HPP diff --git a/AusRegEPPTK/se/ContactTransferRequestCommandTest.cpp b/AusRegEPPTK/se/ContactTransferRequestCommandTest.cpp new file mode 100644 index 0000000..4f019d8 --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferRequestCommandTest.cpp @@ -0,0 +1,31 @@ +#include "se/ContactTransferRequestCommand.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "xml/XMLParser.hpp" +#include "common/init.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + ContactTransferRequestCommand cmd("JTKCON1", "jtkcon1pw"); + + const string expected("JTKCON1jtkcon1pwJTKUTEST.20070101.010101.0"); + const string xml(cmd.toXML()); + ASSERT_EQ(expected, xml); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/ContactTransferResponse.cpp b/AusRegEPPTK/se/ContactTransferResponse.cpp new file mode 100644 index 0000000..f576267 --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferResponse.cpp @@ -0,0 +1,55 @@ +#include "se/ContactTransferResponse.hpp" +#include "common/StringUtils.hpp" + +const std::string ContactTransferResponse::CON_ID_EXPR + (DataResponse::RES_DATA_EXPR() + "/contact:trnData/contact:id/text()"); + +const std::string ContactTransferResponse::CON_TR_STATUS_EXPR + (ContactTransferResponse::exprReplace + (TransferResponse::TR_STATUS_EXPR())); + +const std::string ContactTransferResponse::CON_REID_EXPR + (ContactTransferResponse::exprReplace + (TransferResponse::REID_EXPR())); + +const std::string ContactTransferResponse::CON_REDATE_EXPR + (ContactTransferResponse::exprReplace + (TransferResponse::REDATE_EXPR())); + +const std::string ContactTransferResponse::CON_ACID_EXPR + (ContactTransferResponse::exprReplace + (TransferResponse::ACID_EXPR())); + +const std::string ContactTransferResponse::CON_ACDATE_EXPR + (ContactTransferResponse::exprReplace + (TransferResponse::ACDATE_EXPR())); + + +void ContactTransferResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + TransferResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + id = xmlDoc->getNodeValue(CON_ID_EXPR); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + + +std::string ContactTransferResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + TransferResponse::OBJ(), + StandardObjectType::CONTACT()->getName()); +} diff --git a/AusRegEPPTK/se/ContactTransferResponse.hpp b/AusRegEPPTK/se/ContactTransferResponse.hpp new file mode 100644 index 0000000..27a38b3 --- /dev/null +++ b/AusRegEPPTK/se/ContactTransferResponse.hpp @@ -0,0 +1,51 @@ +#ifndef __CONTACT_TRANSFER_RESPONSE_HPP +#define __CONTACT_TRANSFER_RESPONSE_HPP + +#include "se/StandardObjectType.hpp" +#include "se/TransferResponse.hpp" + +/** + * Use this to access contact object transfer information as provided in an EPP + * contact transfer response compliant with RFCs 3730 and 3733. Such a service + * element is sent by a compliant EPP server in response to a valid contact + * transfer command, implemented by a subclass of the ContactTransferCommand + * class. + * + * @see ContactTransferCommand + * @see ContactTransferRequestCommand + * @see ContactTransferApproveCommand + * @see ContactTransferCancelCommand + * @see ContactTransferRejectCommand + * @see ContactTransferQueryCommand + */ +class ContactTransferResponse : public TransferResponse +{ +public: + ContactTransferResponse() + : TransferResponse(StandardObjectType::CONTACT()) + { } + + const std::string & getID() const { return id; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + static std::string exprReplace (const std::string &expr); + + const std::string& trStatusExpr() const { return CON_TR_STATUS_EXPR; }; + const std::string& reIDExpr() const { return CON_REID_EXPR; }; + const std::string& reDateExpr() const { return CON_REDATE_EXPR; }; + const std::string& acIDExpr() const { return CON_ACID_EXPR; }; + const std::string& acDateExpr() const { return CON_ACDATE_EXPR; }; + +private: + static const std::string CON_ID_EXPR, + CON_TR_STATUS_EXPR, + CON_REID_EXPR, + CON_REDATE_EXPR, + CON_ACID_EXPR, + CON_ACDATE_EXPR; + std::string id; +}; + +#endif // __CONTACT_TRANSFER_RESPONSE_HPP diff --git a/AusRegEPPTK/se/ContactUpdateCommand.cpp b/AusRegEPPTK/se/ContactUpdateCommand.cpp new file mode 100644 index 0000000..fdb1bd8 --- /dev/null +++ b/AusRegEPPTK/se/ContactUpdateCommand.cpp @@ -0,0 +1,100 @@ +#include "se/ContactUpdateCommand.hpp" +#include "se/StandardObjectType.hpp" +#include "xml/XMLHelper.hpp" +#include "se/Status.hpp" +#include "se/IntPostalInfo.hpp" +#include "se/LocalPostalInfo.hpp" +#include "se/Disclose.hpp" + +/* + * The complete set of attributes of a contact which may be updated as per + * RFC3733. + */ +ContactUpdateCommand::ContactUpdateCommand (const std::string &id, + const std::string &pw, + const std::vector *addStatuses, + const std::vector *remStatuses, + const IntPostalInfo *newIntPostalInfo, + const LocalPostalInfo *newLocPostalInfo, + const std::string *newVoice, + const std::string *newVoiceExt, + const std::string *newFax, + const std::string *newFaxExt, + const std::string *newEmail, + const Disclose *disclose) + : UpdateCommand (StandardObjectType::CONTACT(), id) +{ + if (addStatuses) + { + const std::vector &stats = *addStatuses; + + DOMElement *add = xmlWriter->appendChild (objElement, "add"); + + for (unsigned int i = 0; i < stats.size(); i++) + xmlWriter->appendChild (add, "status", stats[i].getRationale(), + "s", stats[i].toString()); + } + + if (remStatuses) + { + const std::vector &stats = *remStatuses; + + DOMElement *rem = xmlWriter->appendChild (objElement, "rem"); + + for (unsigned int i = 0; i < stats.size(); i++) + xmlWriter->appendChild (rem, "status", "s", stats[i]); + } + + if (pw == "" && + newIntPostalInfo == NULL && + newLocPostalInfo == NULL && + newVoice == NULL && + newFax == NULL && + newEmail == NULL && + disclose == NULL) return; + + DOMElement *chg = xmlWriter->appendChild (objElement, "chg"); + + if (newIntPostalInfo) + newIntPostalInfo->appendToElement (xmlWriter, chg); + + if (newLocPostalInfo) + newLocPostalInfo->appendToElement (xmlWriter, chg); + + if (newVoice) + { + DOMElement *voice = xmlWriter->appendChild (chg, "voice"); + if (newVoiceExt) + XMLHelper::setAttribute (voice, "x", *newVoiceExt); + + XMLHelper::setTextContent (voice, *newVoice); + } + + if (newFax) + { + DOMElement *fax = xmlWriter->appendChild (chg, "fax"); + if (newFaxExt) + XMLHelper::setAttribute (fax, "x", *newFaxExt); + + XMLHelper::setTextContent (fax, *newFax); + } + + if (newEmail) + XMLHelper::setTextContent + (xmlWriter->appendChild (chg, "email"), *newEmail); + + if (pw != "") + XMLHelper::setTextContent + (xmlWriter->appendChild + (xmlWriter->appendChild + (chg, + "authInfo"), + "pw"), + pw); + + if (disclose) + disclose->appendToElement (xmlWriter, chg); +} + + + diff --git a/AusRegEPPTK/se/ContactUpdateCommand.hpp b/AusRegEPPTK/se/ContactUpdateCommand.hpp new file mode 100644 index 0000000..8571ba3 --- /dev/null +++ b/AusRegEPPTK/se/ContactUpdateCommand.hpp @@ -0,0 +1,38 @@ +#ifndef __CONTACTUPDATECOMMAND_HPP +#define __CONTACTUPDATECOMMAND_HPP + +#include "se/UpdateCommand.hpp" +class Status; +class IntPostalInfo; +class LocalPostalInfo; +class Disclose; + +/** + * Use this to request the update of a contact object provisioned in an EPP + * Registry. Instances of this class generate RFC3730 and RFC3733 compliant + * contact update EPP command service elements via the toXML method. The + * response expected from a server should be handled by a Response object. + * + * @see Response + */ +class ContactUpdateCommand : public UpdateCommand +{ +public: + /** + * The complete set of attributes of a contact which may be updated as per + * RFC3733. + */ + ContactUpdateCommand (const std::string &id, + const std::string &pw, + const std::vector *addStatuses = NULL, + const std::vector *remStatuses = NULL, + const IntPostalInfo *newIntPostalInfo = NULL, + const LocalPostalInfo *newLocPostalInfo = NULL, + const std::string *newVoice = NULL, + const std::string *newVoiceExt = NULL, + const std::string *newFax = NULL, + const std::string *newFaxExt = NULL, + const std::string *newEmail = NULL, + const Disclose *disclose = NULL); +}; +#endif // __CONTACTUPDATECOMMAND_HPP diff --git a/AusRegEPPTK/se/CreateCommand.hpp b/AusRegEPPTK/se/CreateCommand.hpp new file mode 100644 index 0000000..207a020 --- /dev/null +++ b/AusRegEPPTK/se/CreateCommand.hpp @@ -0,0 +1,29 @@ +#ifndef __CREATECOMMAND_HPP +#define __CREATECOMMAND_HPP + +#include "se/ObjectCommand.hpp" +#include "se/StandardCommandType.hpp" + +/** + * Representation of the EPP create command, as defined in RFC3730. + * Subclasses of this must specify at a minimum the object to which the command + * is mapped and the object-specific identifier of the object to create. + */ +class CreateCommand : public ObjectCommand +{ +public: + /** + * Construct a create command of the given object type mapping with the + * given object identifier. + * + * @param objType The type of object to which the create command is to be + * mapped. + * + * @param ident The identifier of the object to be created. + */ + CreateCommand(const ObjectType* objType, + const std::string& ident) + : ObjectCommand(StandardCommandType::CREATE(), objType, ident) + { } +}; +#endif // __CREATECOMMAND_HPP diff --git a/AusRegEPPTK/se/CreateResponse.cpp b/AusRegEPPTK/se/CreateResponse.cpp new file mode 100644 index 0000000..a565930 --- /dev/null +++ b/AusRegEPPTK/se/CreateResponse.cpp @@ -0,0 +1,45 @@ +#include "se/CreateResponse.hpp" +#include "se/StandardCommandType.hpp" +#include "se/EPPDateFormatter.hpp" + +const std::string CreateResponse::OBJ() +{ + static std::string expr = "OBJ"; + return expr; +} + +const std::string CreateResponse::CRE_DATA_EXPR() +{ + static std::string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:creData"; + return expr; +} + +const std::string CreateResponse::CR_DATE_EXPR() +{ + static std::string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:crDate/text()"; + return expr; +} + +CreateResponse::CreateResponse(const ObjectType* objectType) + : DataResponse(StandardCommandType::CREATE(), objectType) +{ } + +void CreateResponse::fromXML(XMLDocument *xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + std::string crDateStr = xmlDoc->getNodeValue(crDateExpr()); + crDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(crDateStr)); + } + catch (IllegalArgException& iae) + { + maintLogger->LOG_WARNING(iae.getMessage()); + throw ParsingException(iae.getMessage()); + } +} diff --git a/AusRegEPPTK/se/CreateResponse.hpp b/AusRegEPPTK/se/CreateResponse.hpp new file mode 100644 index 0000000..bf7d11c --- /dev/null +++ b/AusRegEPPTK/se/CreateResponse.hpp @@ -0,0 +1,43 @@ +#ifndef __CREATE_RESPONSE_HPP +#define __CREATE_RESPONSE_HPP + +#include "se/DataResponse.hpp" +#include "se/ObjectType.hpp" +#include "se/XMLGregorianCalendar.hpp" + +#include "xml/XMLDocument.hpp" + +#include + +/** + * Representation of the EPP create response, as defined in RFC3730. + * Subclasses of this must specify the object to which the command is mapped. + * Instances of this class provide an interface to access create data for the + * object identified in a {@link CreateCommand}. + * This relies on the instance first being initialised by a suitable EPP create + * response using the method fromXML. For flexibility, this implementation + * extracts the data from the response using XPath queries, the expressions for + * which are defined statically. + * + * @see CreateCommand + */ +class CreateResponse : public DataResponse +{ +public: + CreateResponse (const ObjectType* objectType); + + const XMLGregorianCalendar* getCreateDate() const { return crDate.get(); }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + static const std::string OBJ(); + static const std::string CRE_DATA_EXPR(); + static const std::string CR_DATE_EXPR(); + + virtual const std::string & crDateExpr() const = 0; + +private: + std::auto_ptr crDate; +}; +#endif // __CREATE_RESPONSE_HPP diff --git a/AusRegEPPTK/se/DataResponse.cpp b/AusRegEPPTK/se/DataResponse.cpp new file mode 100644 index 0000000..fc676dd --- /dev/null +++ b/AusRegEPPTK/se/DataResponse.cpp @@ -0,0 +1,31 @@ +#include "se/DataResponse.hpp" +#include "se/CommandType.hpp" + +const std::string DataResponse::OBJ() +{ + static std::string expr = "OBJ"; + return expr; +} + +const std::string DataResponse::RES_DATA_EXPR() +{ + static std::string expr = Response::RESPONSE_EXPR() + "/e:resData"; + return expr; +} + +DataResponse::DataResponse (const CommandType* commandType, + const ObjectType* objectType) + : cmdType(commandType), + objType(objectType) +{ +} + +const CommandType& DataResponse::getCmdType() const +{ + return *cmdType; +} + +const ObjectType& DataResponse::getObjType() const +{ + return *objType; +} diff --git a/AusRegEPPTK/se/DataResponse.hpp b/AusRegEPPTK/se/DataResponse.hpp new file mode 100644 index 0000000..9c685ee --- /dev/null +++ b/AusRegEPPTK/se/DataResponse.hpp @@ -0,0 +1,33 @@ +#ifndef __DATARESPONSE_HPP +#define __DATARESPONSE_HPP + +#include "se/Response.hpp" +#include "se/ObjectType.hpp" + +class CommandType; + +/** + * The base class of all response classes which provide more information than + * the standard Response class. Such classes model EPP responses having a + * resData element. Subclasses must specify the command and object + * types to which the response applies. + */ +class DataResponse : public Response +{ +public: + DataResponse (const CommandType* commandType, const ObjectType* objectType); + +protected: + static const std::string OBJ(); + static const std::string RES_DATA_EXPR(); + + const CommandType &getCmdType() const; + const ObjectType &getObjType() const; + +private: + const CommandType *cmdType; + const ObjectType *objType; +}; + + +#endif // __DATARESPONSE_HPP diff --git a/AusRegEPPTK/se/DeleteCommand.hpp b/AusRegEPPTK/se/DeleteCommand.hpp new file mode 100644 index 0000000..ee59a51 --- /dev/null +++ b/AusRegEPPTK/se/DeleteCommand.hpp @@ -0,0 +1,32 @@ +#ifndef __DELETE_COMMAND_HPP +#define __DELETE_COMMAND_HPP + +#include "se/ObjectCommand.hpp" +#include "se/ObjectType.hpp" +#include "se/StandardObjectType.hpp" +#include "se/StandardCommandType.hpp" + +#include + +/** + * Representation of the EPP delete command, as defined in RFC3730. + * Subclasses of this must specify at a minimum the object to which the command + * is mapped and the object-specific identifier of the object to delete. + */ +class DeleteCommand : public ObjectCommand +{ +public: + /** + * Construct a delete command of the given object type mapping with the + * given object identifier. + * + * @param objType The type of object to which the delete command is to be + * mapped. + * + * @param ident The identifier of the object to be created. + */ + DeleteCommand (const ObjectType* objType, const std::string& ident) + : ObjectCommand (StandardCommandType::DELETE(), objType, ident) {}; +}; + +#endif // __DELETE_COMMAND_HPP diff --git a/AusRegEPPTK/se/Disclose.cpp b/AusRegEPPTK/se/Disclose.cpp new file mode 100644 index 0000000..a8f841c --- /dev/null +++ b/AusRegEPPTK/se/Disclose.cpp @@ -0,0 +1,41 @@ +#include "se/Disclose.hpp" +#include "xml/XMLWriter.hpp" + +namespace { + inline bool bitSet(unsigned int set, int bit) { return set & (0x1 << bit); } +} +using namespace xercesc; +DOMElement * Disclose::appendToElement (XMLWriter *xmlWriter, + DOMElement *parent) const +{ + DOMElement *disclose = + xmlWriter->appendChild (parent, "disclose", + "flag", allow); + + if (!setBits) // none set + { + xmlWriter->appendChild (disclose, "voice"); + return disclose; + } + + if (bitSet (setBits, bs_NameInt)) + xmlWriter->appendChild (disclose, "name", "type", "int"); + if (bitSet (setBits, bs_NameLoc)) + xmlWriter->appendChild (disclose, "name", "type", "loc"); + if (bitSet (setBits, bs_OrgInt)) + xmlWriter->appendChild (disclose, "org", "type", "int"); + if (bitSet (setBits, bs_OrgLoc)) + xmlWriter->appendChild (disclose, "org", "type", "loc"); + if (bitSet (setBits, bs_AddrInt)) + xmlWriter->appendChild (disclose, "addr", "type", "int"); + if (bitSet (setBits, bs_AddrLoc)) + xmlWriter->appendChild (disclose, "addr", "type", "loc"); + if (bitSet (setBits, bs_Voice)) + xmlWriter->appendChild (disclose, "voice"); + if (bitSet (setBits, bs_Fax)) + xmlWriter->appendChild (disclose, "fax"); + if (bitSet (setBits, bs_Email)) + xmlWriter->appendChild (disclose, "email"); + + return disclose; +} diff --git a/AusRegEPPTK/se/Disclose.hpp b/AusRegEPPTK/se/Disclose.hpp new file mode 100644 index 0000000..ebfa3b9 --- /dev/null +++ b/AusRegEPPTK/se/Disclose.hpp @@ -0,0 +1,84 @@ +#ifndef __DISCLOSE_HPP +#define __DISCLOSE_HPP + +#include "se/Appendable.hpp" +#include + +namespace { + inline void setBit(unsigned int& set, int bit) { set |= (0x1 << bit); } +} + +/** + * Disclosure preferences are configured via an instance of this class. This + * class is an interface to the EPP disclose element which is described in + * RFC3733 where uses of the element are also described. Contact information + * disclosure preferences may be set via contact transform operations, + * implemented in such classes as ContactCreateCommand and + * ContactUpdateCommand. + * + * @see ContactCreateCommand + * @see ContactUpdateCommand + */ +class Disclose : public Appendable +{ +public: + /** + * Construct a Disclose object with all items not yet set. This is an invalid + * final state for an EPP disclose element, requiring at least one setX method + * to be invoked on the instance prior to a transform command using the Disclose + * object. + * + * @param allow Whether or not elements to be set later via setX should be + * disclosed or not. This is only a request to the server and may not be + * honoured. + */ + Disclose (bool allow, + bool nameInt = false, + bool nameLoc = false, + bool orgInt = false, + bool orgLoc = false, + bool addrInt = false, + bool addrLoc = false, + bool voice = false, + bool fax = false, + bool email = false) + { + this->allow = allow ? "1" : "0"; + setBits = 0L; + }; + + virtual ~Disclose(){}; + + void setVoice() { setBit (setBits, bs_Voice); }; + void setFax() { setBit (setBits, bs_Fax); }; + void setEmail() { setBit (setBits, bs_Email); }; + void setNameInt() { setBit (setBits, bs_NameInt); }; + void setNameLoc() { setBit (setBits, bs_NameLoc); }; + void setOrgInt() { setBit (setBits, bs_OrgInt); }; + void setOrgLoc() { setBit (setBits, bs_OrgLoc); }; + void setAddrInt() { setBit (setBits, bs_AddrInt); }; + void setAddrLoc() { setBit (setBits, bs_AddrLoc); }; + + xercesc::DOMElement* appendToElement( + XMLWriter *xmlWriter, + xercesc::DOMElement *parent) const; +private: + + typedef enum + { + bs_Voice, + bs_Fax, + bs_Email, + bs_NameInt, + bs_NameLoc, + bs_OrgInt, + bs_OrgLoc, + bs_AddrInt, + bs_AddrLoc + } bsBit; + + unsigned int setBits; + std::string allow; +}; + +#endif // __DISCLOSE_HPP diff --git a/AusRegEPPTK/se/DiscloseItem.hpp b/AusRegEPPTK/se/DiscloseItem.hpp new file mode 100644 index 0000000..f4155c3 --- /dev/null +++ b/AusRegEPPTK/se/DiscloseItem.hpp @@ -0,0 +1,33 @@ +#ifndef __DISCLOSE_ITEM_HPP +#define __DISCLOSE_ITEM_HPP + +#include + +/** + * Disclosure preferences are viewed via an instances of this class. This + * class is an interface to the EPP disclose element which is described in + * RFC3733, where uses of the element are also described. Contact information + * disclosure status may be found in the result data of a command info + * response, implemented in the ContactInfoResponse class. + * + * @see ContactInfoCommand + * @see ContactInfoResponse + */ +class DiscloseItem +{ +public: + /// @TODO SWIG/Perl workaround - figure out why SWIG wants an empty constructor. + DiscloseItem () {} + + DiscloseItem (const std::string &elementName, + const std::string &type = "") + : name(elementName), type(type) + { } + + const std::string& getElementName() { return name; }; + const std::string& getType() { return type; }; + +private: + std::string name, type; +}; +#endif // __DISCLOSE_ITEM_HPP diff --git a/AusRegEPPTK/se/DomainAdd.hpp b/AusRegEPPTK/se/DomainAdd.hpp new file mode 100644 index 0000000..e13410c --- /dev/null +++ b/AusRegEPPTK/se/DomainAdd.hpp @@ -0,0 +1,26 @@ +#ifndef __DOMAINADD_HPP +#define __DOMAINADD_HPP + +#include "se/DomainAddRem.hpp" +#include "se/AddRemType.hpp" + +/** + * Use this to specify attributes to add to a domain object in a domain + * update EPP command service element. The DomainUpdateCommand uses an + * instance of this to build the appropriate elements in order to request the + * addition of these attributes to a domain object. + */ +class DomainAdd : public DomainAddRem +{ +public: + DomainAdd (const std::vector *nameservers, + const std::vector *techContacts, + const std::vector *adminContacts, + const std::vector *billingContacts, + const std::vector *statuses) + : DomainAddRem (AddRemType::ADD(), + nameservers, techContacts, adminContacts, + billingContacts, statuses) {} +}; + +#endif // __DOMAINADD_HPP diff --git a/AusRegEPPTK/se/DomainAddRem.cpp b/AusRegEPPTK/se/DomainAddRem.cpp new file mode 100644 index 0000000..a53ee2b --- /dev/null +++ b/AusRegEPPTK/se/DomainAddRem.cpp @@ -0,0 +1,98 @@ +#include "se/DomainAddRem.hpp" +#include "se/AddRemType.hpp" +#include "xml/XMLHelper.hpp" +#include "xml/XMLWriter.hpp" + +using namespace xercesc; + +DomainAddRem::DomainAddRem(const AddRemType* type, + const std::vector *nameservers, + const std::vector *techContacts, + const std::vector *adminContacts, + const std::vector *billingContacts, + const std::vector *statuses) + : type(type->toString()) +{ + if (nameservers) + this->nameservers = *nameservers; + + if (techContacts) + this->techContacts = *techContacts; + + if (adminContacts) + this->adminContacts = *adminContacts; + + if (billingContacts) + this->billingContacts = *billingContacts; + + if (statuses) + this->statuses = *statuses; +} + +DOMElement * DomainAddRem::appendToElement(XMLWriter *xmlWriter, + DOMElement *parent) const +{ + int listSize = 0; + + DOMElement *addRem = xmlWriter->appendChild (parent, type); + + if ((listSize = nameservers.size()) > 0) + { + DOMElement *ns = xmlWriter->appendChild (addRem, "ns"); + + for (int i = 0; i < listSize; i++) + XMLHelper::setTextContent + (xmlWriter->appendChild (ns, "hostObj"), + nameservers[i]); + } + + if ((listSize = techContacts.size()) > 0) + { + for (int i = 0; i < listSize; i++) + xmlWriter->appendChild (addRem, + "contact", + techContacts[i], + "type", + "tech"); + } + + if ((listSize = adminContacts.size()) > 0) + { + for (int i = 0; i < listSize; i++) + xmlWriter->appendChild (addRem, + "contact", + adminContacts[i], + "type", + "admin"); + } + + if ((listSize = billingContacts.size()) > 0) + { + for (int i = 0; i < listSize; i++) + xmlWriter->appendChild (addRem, + "contact", + billingContacts[i], + "type", + "billing"); + } + + if ((listSize = statuses.size()) > 0) + { + for (int i = 0; i < listSize; i++) + { + const Status &status = statuses[i]; + + DOMElement *s = + xmlWriter->appendChild (addRem, + "status", + status.getRationale(), + "s", + status.toString()); + if (status.getLanguage() != "") + XMLHelper::setAttribute (s, "lang", status.getLanguage()); + } + // End for + } + + return addRem; +} diff --git a/AusRegEPPTK/se/DomainAddRem.hpp b/AusRegEPPTK/se/DomainAddRem.hpp new file mode 100644 index 0000000..c3af8fb --- /dev/null +++ b/AusRegEPPTK/se/DomainAddRem.hpp @@ -0,0 +1,46 @@ +#ifndef __DOMAINADDREM_HPP +#define __DOMAINADDREM_HPP + +#include +#include "se/Appendable.hpp" +#include "se/Status.hpp" +#include +#include + +class AddRemType; + +/** + * Specification of how to write the add and rem elements to a domain update + * command. Use subclasses of this to set attributes to add or remove from a + * domain object. + */ +class DomainAddRem : public Appendable +{ +public: + /** + * Maximal specification of the attribute values which may be added or + * removed from a domain. Each of the parameters is optional, but at least + * one must be specified. + */ + DomainAddRem(const AddRemType* type, + const std::vector* nameservers, + const std::vector* techContacts, + const std::vector* adminContacts, + const std::vector* billingContacts, + const std::vector* statuses); + virtual ~DomainAddRem(){}; + + virtual xercesc::DOMElement* appendToElement( + XMLWriter *xmlWriter, xercesc::DOMElement *parent) const; + +private: + std::string type; + std::vector nameservers; + std::vector techContacts; + std::vector adminContacts; + std::vector billingContacts; + + std::vector statuses; +}; + +#endif // __DOMAINADDREM_HPP diff --git a/AusRegEPPTK/se/DomainCheckCommand.hpp b/AusRegEPPTK/se/DomainCheckCommand.hpp new file mode 100644 index 0000000..c450a45 --- /dev/null +++ b/AusRegEPPTK/se/DomainCheckCommand.hpp @@ -0,0 +1,37 @@ +#ifndef __DOMAIN_CHECK_COMMAND_HPP +#define __DOMAIN_CHECK_COMMAND_HPP + +#include "se/CheckCommand.hpp" +#include "se/StandardObjectType.hpp" + +#include +#include + +/** + * A DomainCheckCommand is used to check the availability of domain objects + * in a Registry. Instances of this class generate RFC3730 and RFC3731 + * compliant domain check EPP command service elements via the toXML method. + * + * @see DomainCheckResponse + */ +class DomainCheckCommand : public CheckCommand +{ +public: + /** + * Check the availability of the single identified domain. + * + * @param name The name of the domain to check the availability of. + */ + DomainCheckCommand (const std::string &name) + : CheckCommand (StandardObjectType::DOMAIN(), name) {}; + + /** + * Check the availability of at least one domain. + * + * @param names The names of the domains to check the availability of. + */ + DomainCheckCommand (std::vector &names) + : CheckCommand (StandardObjectType::DOMAIN(), names) {}; +}; + +#endif // __DOMAIN_CHECK_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainCheckCommandTest.cpp b/AusRegEPPTK/se/DomainCheckCommandTest.cpp new file mode 100644 index 0000000..366be08 --- /dev/null +++ b/AusRegEPPTK/se/DomainCheckCommandTest.cpp @@ -0,0 +1,31 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/DomainCheckCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + DomainCheckCommand cmd("test.com.au"); + const string xml(cmd.toXML()); + + ASSERT_EQ(cmd.getCommandType()->getCommandName(), "check"); + ASSERT_EQ(cmd.getObjectType()->getName(), "domain"); + ASSERT_EQ(xml, "test.com.auJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainCheckResponse.cpp b/AusRegEPPTK/se/DomainCheckResponse.cpp new file mode 100644 index 0000000..97108ea --- /dev/null +++ b/AusRegEPPTK/se/DomainCheckResponse.cpp @@ -0,0 +1,49 @@ +#include "se/DomainCheckResponse.hpp" +#include "common/StringUtils.hpp" +#include "se/StandardObjectType.hpp" + +const std::string& DomainCheckResponse::DOM_CHKDATA_COUNT_EXPR() +{ + static const std::string expr = DomainCheckResponse::exprReplace (CheckResponse::CHKDATA_COUNT_EXPR()); + return expr; +} + +const std::string& DomainCheckResponse::DOM_CHKDATA_IND_EXPR() +{ + static const std::string expr = DomainCheckResponse::exprReplace (CheckResponse::CHKDATA_IND_EXPR()); + return expr; +} + +const std::string& DomainCheckResponse::DOM_CHKDATA_IDENT_EXPR() +{ + static const std::string expr = DomainCheckResponse::exprReplace (CheckResponse::CHKDATA_IDENT_EXPR()); + return expr; +} + +const std::string& DomainCheckResponse::DOM_CHKDATA_AVAIL_EXPR() +{ + static const std::string expr = DomainCheckResponse::exprReplace (CheckResponse::CHKDATA_AVAIL_EXPR()); + return expr; +} + +const std::string& DomainCheckResponse::DOM_CHKDATA_REASON_EXPR() +{ + static const std::string expr = DomainCheckResponse::exprReplace (CheckResponse::CHKDATA_REASON_EXPR()); + return expr; +} + +DomainCheckResponse::DomainCheckResponse() + : CheckResponse (StandardObjectType::DOMAIN()) +{ } + +std::string DomainCheckResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll( + StringUtils::replaceAll( + expr, + DataResponse::OBJ(), + StandardObjectType::DOMAIN()->getName()), + "IDENT", + "name"); +} + diff --git a/AusRegEPPTK/se/DomainCheckResponse.hpp b/AusRegEPPTK/se/DomainCheckResponse.hpp new file mode 100644 index 0000000..1ffff3a --- /dev/null +++ b/AusRegEPPTK/se/DomainCheckResponse.hpp @@ -0,0 +1,36 @@ +#ifndef __DOMAIN_CHECK_RESPONSE_HPP +#define __DOMAIN_CHECK_RESPONSE_HPP + +#include "se/CheckResponse.hpp" + +/** + * Use this to access availability data for domains as provided in an EPP + * domain check response compliant with RFCs 3730 and 3731. Such a service + * element is sent by a compliant EPP server in response to a valid domain + * check command, implemented by the DomainCheckCommand class. + * + * @see DomainCheckCommand + */ +class DomainCheckResponse : public CheckResponse +{ +public: + DomainCheckResponse (); + +protected: + const std::string& chkDataCountExpr() const { return DOM_CHKDATA_COUNT_EXPR(); }; + const std::string& chkDataIndexExpr() const { return DOM_CHKDATA_IND_EXPR(); }; + const std::string& chkDataTextExpr() const { return DOM_CHKDATA_IDENT_EXPR(); }; + const std::string& chkDataAvailExpr() const { return DOM_CHKDATA_AVAIL_EXPR(); }; + const std::string& chkDataReasonExpr() const { return DOM_CHKDATA_REASON_EXPR(); }; + + static std::string exprReplace (const std::string &expr); + +private: + static const std::string& DOM_CHKDATA_COUNT_EXPR(); + static const std::string& DOM_CHKDATA_IND_EXPR(); + static const std::string& DOM_CHKDATA_IDENT_EXPR(); + static const std::string& DOM_CHKDATA_AVAIL_EXPR(); + static const std::string& DOM_CHKDATA_REASON_EXPR(); + +}; +#endif // __DOMAIN_CHECK_RESPONSE_HPP diff --git a/AusRegEPPTK/se/DomainCheckResponseTest.cpp b/AusRegEPPTK/se/DomainCheckResponseTest.cpp new file mode 100644 index 0000000..0ba2fb1 --- /dev/null +++ b/AusRegEPPTK/se/DomainCheckResponseTest.cpp @@ -0,0 +1,37 @@ +#include "se/DomainCheckResponse.hpp" +// #include "session/TestEnvironment.hpp" +#include "xml/XMLParser.hpp" +#include "xml/XMLDocument.hpp" + +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string xml = + "Command completed successfullyexample.comexample.netIn useexample.orgABC-1234554322-XYZ"; + XMLParser parser; + auto_ptr doc(parser.parse(xml)); + DomainCheckResponse response; + response.fromXML(doc.get()); + + ASSERT_EQ(response.isAvailable("example.com"), true); + ASSERT_EQ(response.getReason("example.net"), "In use"); + ASSERT_EQ("In use", response.getReason(1)); + ASSERT_EQ(3, response.getAvailableList().size()); + ASSERT_EQ(3, response.getReasonList().size()); + ASSERT_EQ(1000, response.getResults()[0].getResultCode()); + ASSERT_EQ("ABC-12345", response.getCLTRID()); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainCreateCommand.cpp b/AusRegEPPTK/se/DomainCreateCommand.cpp new file mode 100644 index 0000000..2c17e36 --- /dev/null +++ b/AusRegEPPTK/se/DomainCreateCommand.cpp @@ -0,0 +1,54 @@ +#include "se/DomainCreateCommand.hpp" +#include "se/StandardObjectType.hpp" +#include "xml/XMLHelper.hpp" + + +DomainCreateCommand::DomainCreateCommand (const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts, + const std::vector* nameservers, + const std::vector* adminContacts, + const std::vector* billingContacts, + const Period* period) + : CreateCommand(StandardObjectType::DOMAIN(), name) +{ + std::vector::const_iterator p; + + if (period) + period->appendPeriod (xmlWriter, objElement); + + if (nameservers) + { + DOMElement *ns = xmlWriter->appendChild (objElement, "ns"); + for (p = nameservers->begin(); p != nameservers->end(); p++) + XMLHelper::setTextContent + (xmlWriter->appendChild (ns, "hostObj"), *p); + } + + if (registrantID) + { + XMLHelper::setTextContent + (xmlWriter->appendChild(objElement, "registrant"), *registrantID); + } + + if (adminContacts) + for (p = adminContacts->begin(); p != adminContacts->end(); p++) + xmlWriter->appendChild(objElement, "contact", *p, "type", "admin"); + + if (techContacts) + for (p = techContacts->begin(); p != techContacts->end(); p++) + xmlWriter->appendChild(objElement, "contact", *p, "type", "tech"); + + if (billingContacts) + for (p = billingContacts->begin(); p != billingContacts->end(); p++) + xmlWriter->appendChild(objElement, "contact", *p, "type", "billing"); + + XMLHelper::setTextContent + (xmlWriter->appendChild + (xmlWriter->appendChild + (objElement, + "authInfo"), + "pw"), + pw); +} diff --git a/AusRegEPPTK/se/DomainCreateCommand.hpp b/AusRegEPPTK/se/DomainCreateCommand.hpp new file mode 100644 index 0000000..47ed007 --- /dev/null +++ b/AusRegEPPTK/se/DomainCreateCommand.hpp @@ -0,0 +1,32 @@ +#ifndef __DOMAINCREATECOMMAND_HPP +#define __DOMAINCREATECOMMAND_HPP + +#include "se/CreateCommand.hpp" +#include "se/Period.hpp" + +/** + * Mapping of EPP urn:ietf:params:xml:ns:domain-1.0 create command specified in + * RFC3731. Command-response extensions to the domain:create command are + * implemented as subclasses of this. + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The toXML method in Command serialises this object to + * XML. + */ +class DomainCreateCommand : public CreateCommand +{ +public: + /** + * Constructor for a domain:create EPP command. All core EPP domain:create + * attributes may be set using this constructor. + */ + DomainCreateCommand (const std::string& name, + const std::string& pw, + const std::string* registrantID, + const std::vector* techContacts = NULL, + const std::vector* nameservers = NULL, + const std::vector* adminContacts = NULL, + const std::vector* billingContacts = NULL, + const Period* period = NULL); +}; + +#endif // __DOMAINCREATECOMMAND_HPP diff --git a/AusRegEPPTK/se/DomainCreateResponse.cpp b/AusRegEPPTK/se/DomainCreateResponse.cpp new file mode 100644 index 0000000..2f77d07 --- /dev/null +++ b/AusRegEPPTK/se/DomainCreateResponse.cpp @@ -0,0 +1,54 @@ +#include "se/DomainCreateResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "se/EPPDateFormatter.hpp" +#include "common/StringUtils.hpp" + +const std::string DomainCreateResponse::DOM_CR_DATE_EXPR + (DomainCreateResponse::exprReplace + (CreateResponse::CR_DATE_EXPR())); + +const std::string DomainCreateResponse::DOM_NAME_EXPR + (DomainCreateResponse::exprReplace + (CreateResponse::CRE_DATA_EXPR()) + + "/domain:name/text()"); + +const std::string DomainCreateResponse::DOM_EX_DATE_EXPR + (DomainCreateResponse::exprReplace + (CreateResponse::CRE_DATA_EXPR()) + + "/domain:exDate/text()"); + +DomainCreateResponse::DomainCreateResponse() + : CreateResponse(StandardObjectType::DOMAIN()) +{ +} + + +void DomainCreateResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + CreateResponse::fromXML (xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + name = xmlDoc->getNodeValue (DOM_NAME_EXPR); + std::string exDateStr = xmlDoc->getNodeValue (DOM_EX_DATE_EXPR); + exDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(exDateStr)); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + +std::string DomainCreateResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + CreateResponse::OBJ(), + StandardObjectType::DOMAIN()->getName()); +} diff --git a/AusRegEPPTK/se/DomainCreateResponse.hpp b/AusRegEPPTK/se/DomainCreateResponse.hpp new file mode 100644 index 0000000..aab7cd8 --- /dev/null +++ b/AusRegEPPTK/se/DomainCreateResponse.hpp @@ -0,0 +1,38 @@ +#ifndef __DOMAIN_CREATE_RESPONSE_HPP +#define __DOMAIN_CREATE_RESPONSE_HPP + +#include "se/CreateResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +/** + * Use this to access create data for a domain as provided in an EPP domain + * create response compliant with RFCs 3730 and 3731. Such a service element + * is sent by a compliant EPP server in response to a valid domain create + * command, implemented by the DomainCreateCommand. + * + * @see DomainCreateCommand + */ +class DomainCreateResponse : public CreateResponse +{ +public: + DomainCreateResponse(); + + const std::string & getName() const { return name; }; + const XMLGregorianCalendar* getExpiryDate() const { return exDate.get(); }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + const std::string & crDateExpr() const { return DOM_CR_DATE_EXPR; }; + + static std::string exprReplace (const std::string &expr); + +private: + static const std::string DOM_CR_DATE_EXPR, + DOM_NAME_EXPR, + DOM_EX_DATE_EXPR; + std::string name; + std::auto_ptr exDate; +}; + +#endif // __DOMAIN_CREATE_RESPONSE_HPP diff --git a/AusRegEPPTK/se/DomainDeleteCommand.hpp b/AusRegEPPTK/se/DomainDeleteCommand.hpp new file mode 100644 index 0000000..757ee2c --- /dev/null +++ b/AusRegEPPTK/se/DomainDeleteCommand.hpp @@ -0,0 +1,23 @@ +#ifndef __DOMAIN_DELETE_COMMAND_HPP +#define __DOMAIN_DELETE_COMMAND_HPP + +#include "se/DeleteCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * Use this to request that a domain object be deleted from an EPP Registry. + * Instances of this class generate RFC3730 and RFC3731 compliant domain + * delete EPP command service elements via the toXML method. + */ +class DomainDeleteCommand : public DeleteCommand +{ +public: + /** + * Delete the identified domain. + * + * @param name The name of the domain to delete. + */ + DomainDeleteCommand (const std::string& name) + : DeleteCommand(StandardObjectType::DOMAIN(), name) {}; +}; +#endif // __DOMAIN_DELETE_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainDeleteCommandTest.cpp b/AusRegEPPTK/se/DomainDeleteCommandTest.cpp new file mode 100644 index 0000000..75933f3 --- /dev/null +++ b/AusRegEPPTK/se/DomainDeleteCommandTest.cpp @@ -0,0 +1,28 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/DomainDeleteCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + DomainDeleteCommand cmd("jtkutest.com.au"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainInfoCommand.hpp b/AusRegEPPTK/se/DomainInfoCommand.hpp new file mode 100644 index 0000000..cc5b62e --- /dev/null +++ b/AusRegEPPTK/se/DomainInfoCommand.hpp @@ -0,0 +1,49 @@ +#ifndef __DOMAIN_INFO_COMMAND_HPP +#define __DOMAIN_INFO_COMMAND_HPP + +#include "se/InfoCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * Use this to request information about a domain object provisioned in an EPP + * Registry. Instances of this class generate RFC3730 and RFC3731 compliant + * domain info EPP command service elements via the toXML method. + * + * @see DomainInfoResponse + */ +class DomainInfoCommand : public InfoCommand +{ +public: + /** + * Create a domain info command with the specified identifier and + * authorisation information. + * + * @param name The name of the domain to retrieve information about. + * + * @param pw The password of the identified domain object (also known as + * authInfo or authorisation information). + */ + DomainInfoCommand (const std::string &name, + const std::string &pw = "") + : InfoCommand (StandardObjectType::DOMAIN(), name, pw) {}; + + + /** + * Create a domain info command with the specified identifier and + * authorisation information of an associated contact. + * + * @param name The name of the domain to retrieve information about. + * + * @param roid The Repository Object Identifer of a contact object + * associated with the identified domain. + * + * @param pw The password of the identified domain object (also known as + * authInfo or authorisation information). + */ + DomainInfoCommand (const std::string &name, + const std::string &roid, + const std::string &pw) + : InfoCommand (StandardObjectType::DOMAIN(), name, roid, pw) {}; +}; + +#endif // __DOMAIN_INFO_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainInfoCommandTest.cpp b/AusRegEPPTK/se/DomainInfoCommandTest.cpp new file mode 100644 index 0000000..cf262a9 --- /dev/null +++ b/AusRegEPPTK/se/DomainInfoCommandTest.cpp @@ -0,0 +1,28 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/DomainInfoCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + DomainInfoCommand cmd("jtkutest.com.au"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainInfoKVResponseExtension.cpp b/AusRegEPPTK/se/DomainInfoKVResponseExtension.cpp new file mode 100644 index 0000000..26175a5 --- /dev/null +++ b/AusRegEPPTK/se/DomainInfoKVResponseExtension.cpp @@ -0,0 +1,121 @@ +#include "xml/XMLDocument.hpp" +#include "se/Response.hpp" +#include "se/ResponseExtension.hpp" +#include "se/DomainInfoKVResponseExtension.hpp" + +/* + * Have to use static funcion instead of static variable + * since there is not guarantee about the construct/destruct + * order of a static instance of any types + */ +const std::string DomainInfoKVResponseExtension::KVLIST_EXPR() +{ + return EXTENSION_EXPR() + "/kv:infData/kv:kvlist"; +} + +DomainInfoKVResponseExtension::DomainInfoKVResponseExtension() : + initialised(false), + kvLists() +{ +} + +void DomainInfoKVResponseExtension::fromXML(XMLDocument *xmlDoc) +{ + int kvListCount = xmlDoc->getNodeCount("count(" + KVLIST_EXPR() + ")"); + + if (kvListCount == 0) + { + initialised = false; + } + else + { + for (int i = 1; i <= kvListCount; i++) + { + const std::string currentKVListXPath = + ReceiveSE::replaceIndex(KVLIST_EXPR() + "[IDX]", i); + const std::string kvListName = + xmlDoc->getNodeValue(currentKVListXPath + "/@name"); + + kvLists[kvListName] = createKVList(xmlDoc, currentKVListXPath); + } + + initialised = true; + } +} + +const std::set DomainInfoKVResponseExtension::getLists() const +{ + std::set kvListNames; + + ExtensionList::const_iterator extensionListIterator; + + for (extensionListIterator = kvLists.begin(); + extensionListIterator != kvLists.end(); + extensionListIterator++) + { + kvListNames.insert(extensionListIterator->first); + } + + return kvListNames; +} + +const std::set DomainInfoKVResponseExtension::getListItems( + const std::string &listName) const +{ + std::set itemNames; + ExtensionList::const_iterator extensionListIterator = kvLists.find(listName); + + if (extensionListIterator != kvLists.end()) + { + KeyValueList::const_iterator keyValueListIterator; + + for (keyValueListIterator = extensionListIterator->second.begin(); + keyValueListIterator != extensionListIterator->second.end(); + keyValueListIterator++) + { + itemNames.insert(keyValueListIterator->first); + } + } + + return itemNames; +} + +const std::string DomainInfoKVResponseExtension::getItem( + const std::string &listName, + const std::string &key) const +{ + std::string itemValue; + ExtensionList::const_iterator extensionListIterator = kvLists.find(listName); + + if (extensionListIterator != kvLists.end()) + { + KeyValueList::const_iterator keyValueListIterator = + extensionListIterator->second.find(key); + + if (keyValueListIterator != extensionListIterator->second.end()) + { + itemValue = keyValueListIterator->second; + } + } + + return itemValue; +} + +const KeyValueList DomainInfoKVResponseExtension::createKVList( + XMLDocument *xmlDoc, + const std::string &kvListXPath) +{ + int kvItemCount = xmlDoc->getNodeCount("count(" + kvListXPath + "/kv:item)"); + + KeyValueList kvList; + + for (int i = 1; i <= kvItemCount; i++) + { + std::string itemXPath = ReceiveSE::replaceIndex(kvListXPath + "/kv:item[IDX]", i); + std::string key = xmlDoc->getNodeValue(itemXPath + "/@key"); + std::string value = xmlDoc->getNodeValue(itemXPath); + kvList[key] = value; + } + + return kvList; +} diff --git a/AusRegEPPTK/se/DomainInfoKVResponseExtension.hpp b/AusRegEPPTK/se/DomainInfoKVResponseExtension.hpp new file mode 100644 index 0000000..fce4653 --- /dev/null +++ b/AusRegEPPTK/se/DomainInfoKVResponseExtension.hpp @@ -0,0 +1,79 @@ +#ifndef DOMAIN_INFO_KV_RESPONSE_EXTENSION_H_ +#define DOMAIN_INFO_KV_RESPONSE_EXTENSION_H_ + +#include +#include + +#include +#include "se/KVDefs.hpp" + +class XMLDocument; + +/** + * Extension of the domain mapping of the EPP info response, as defined in + * RFC4930 and RFC4931, to generic domain names, the specification of which is + * in the XML schema definition urn:X-ar:params:xml:ns:kv-1.0. Instances of this + * class provide an interface to access all of the information available through + * EPP for a generic domain name. This relies on the instance first being + * initialised by a suitable EPP domain info response using the method + * fromXML(). + * + * For flexibility, this implementation extracts the data from the response + * using XPath queries. + */ + +class DomainInfoKVResponseExtension : public ResponseExtension +{ + public: + DomainInfoKVResponseExtension(); + + virtual void fromXML(XMLDocument *xmlDoc); + virtual bool isInitialised() const; + + /** + * Retrieves the names of all key-value lists that have been added to the + * object. + * + * @return the set of list names + */ + const std::set getLists() const; + + /** + * Retrieves the names of all item keys, for a specified key-value list + * name. + * + * @param listName + * the name of the key-value list + * + * @return the set of item keys + */ + const std::set getListItems(const std::string &listName) const; + + /** + * Retrieves the value of a given key-value item. + * + * @param listName + * the name of the key-value list + * @param key + * the key of the item + * + * @return the value of the item + */ + const std::string getItem(const std::string &listName, const std::string &key) const; + private: + const KeyValueList createKVList( + XMLDocument *xmlDoc, + const std::string &kvListXPath); + + bool initialised; + ExtensionList kvLists; + + static const std::string KVLIST_EXPR(); +}; + +inline bool DomainInfoKVResponseExtension::isInitialised() const +{ + return initialised; +} + +#endif /* DOMAIN_INFO_KV_RESPONSE_EXTENSION_H_ */ diff --git a/AusRegEPPTK/se/DomainInfoKVResponseExtensionTest.cpp b/AusRegEPPTK/se/DomainInfoKVResponseExtensionTest.cpp new file mode 100644 index 0000000..3d9c66c --- /dev/null +++ b/AusRegEPPTK/se/DomainInfoKVResponseExtensionTest.cpp @@ -0,0 +1,124 @@ +#include "xml/XMLParser.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" +#include "session/Timer.hpp" +#include "se/DomainKVCommandExtension.hpp" +#include "se/DomainInfoResponse.hpp" +#include "se/DomainInfoKVResponseExtension.hpp" +#include "se/CLTRID.hpp" + +using namespace std; + +void checkKeyValueList(const DomainInfoKVResponseExtension &kvExtension, const std::string &listName); + +void testNonExistentListName() +{ + DomainInfoResponse response; + DomainInfoKVResponseExtension kvExtension; + response.registerExtension(&kvExtension); + + const std::string xml = + "Command completed successfullyexample.com.aeD0000003-AREXAMPLEEXAMPLEns1.example.com.aens2.example.com.aens1.example.com.aens2.exmaple.com.aeRegistrarRegistrar2006-02-09T15:44:58.0Z2008-02-10T00:00:00.0Z0192pqowRegistrantName Pty. Ltd.Trade License123456789TrademarkRegistrant EligiTrademark9876543212ABC-12345805"; + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + ASSERT_EQ(kvExtension.isInitialised(), true); + ASSERT_EQ(kvExtension.getItem("nonExistentListName", "registrantIDValue"), ""); +} + +void testNonExistentItem() +{ + DomainInfoResponse response; + DomainInfoKVResponseExtension kvExtension; + response.registerExtension(&kvExtension); + + const std::string xml = + "Command completed successfullyexample.com.aeD0000003-AREXAMPLEEXAMPLEns1.example.com.aens2.example.com.aens1.example.com.aens2.exmaple.com.aeRegistrarRegistrar2006-02-09T15:44:58.0Z2008-02-10T00:00:00.0Z0192pqowRegistrantName Pty. Ltd.Trade License123456789TrademarkRegistrant EligiTrademark9876543212ABC-12345805"; + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + ASSERT_EQ(kvExtension.isInitialised(), true); + ASSERT_EQ(kvExtension.getItem("au", "nonExistentItem"), ""); +} + +void testNotInitialisedWhenNoKVExtensionPresent() +{ + DomainInfoResponse response; + DomainInfoKVResponseExtension kvExtension; + response.registerExtension(&kvExtension); + + const std::string xml = + "Command completed successfullyviewdomain.registrar.auD604E5509E82DF9F3105B7E182BB4DF28-ARCON-1CON-1EPPEPP2010-08-12T00:33:20.0Z2012-08-12T00:33:21.0Z123paSSword My Registrant123456789Company1TESTER1.20100812.003321.19223372036854778924"; + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + ASSERT_EQ(kvExtension.isInitialised(), false); +} + +void testSingleKVList() +{ + DomainInfoResponse response; + DomainInfoKVResponseExtension kvExtension; + response.registerExtension(&kvExtension); + + const std::string xml = + "Command completed successfullyexample.com.aeD0000003-AREXAMPLEEXAMPLEns1.example.com.aens2.example.com.aens1.example.com.aens2.exmaple.com.aeRegistrarRegistrar2006-02-09T15:44:58.0Z2008-02-10T00:00:00.0Z0192pqowRegistrantName Pty. Ltd.Trade License123456789TrademarkRegistrant EligiTrademark9876543212ABC-12345805"; + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + checkKeyValueList(kvExtension, "au"); +} + +void testMultipleKVList() +{ + DomainInfoResponse response; + DomainInfoKVResponseExtension kvExtension; + response.registerExtension(&kvExtension); + + const std::string xml = + "Command completed successfullyexample.com.aeD0000003-AREXAMPLEEXAMPLEns1.example.com.aens2.example.com.aens1.example.com.aens2.exmaple.com.aeRegistrarRegistrar2006-02-09T15:44:58.0Z2008-02-10T00:00:00.0Z0192pqowRegistrantName Pty. Ltd.Trade License123456789TrademarkRegistrant EligiTrademark9876543212RegistrantName Pty. Ltd.Trade License123456789TrademarkRegistrant EligiTrademark9876543212ABC-12345805"; + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + checkKeyValueList(kvExtension, "ae"); + checkKeyValueList(kvExtension, "au"); +} + +void checkKeyValueList(const DomainInfoKVResponseExtension &kvExtension, const std::string &listName) +{ + ASSERT_EQ(kvExtension.getItem(listName, "registrantIDValue"), "123456789"); + ASSERT_EQ(kvExtension.getItem(listName, "registrantName"), "RegistrantName Pty. Ltd."); + ASSERT_EQ(kvExtension.getItem(listName, "registrantIDType"), "Trade License"); + ASSERT_EQ(kvExtension.getItem(listName, "eligibilityType"), "Trademark"); + ASSERT_EQ(kvExtension.getItem(listName, "eligibilityName"), "Registrant Eligi"); + ASSERT_EQ(kvExtension.getItem(listName, "eligibilityIDValue"), "987654321"); + ASSERT_EQ(kvExtension.getItem(listName, "eligibilityIDType"), "Trademark"); + ASSERT_EQ(kvExtension.getItem(listName, "policyReason"), "2"); +} + +int main(int argc, char* argv[]) +{ + init("etc/toolkit2.conf"); + TEST_run(testNonExistentListName); + TEST_run(testNonExistentItem); + TEST_run(testNotInitialisedWhenNoKVExtensionPresent); + TEST_run(testSingleKVList); + TEST_run(testMultipleKVList); + + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainInfoResponse.cpp b/AusRegEPPTK/se/DomainInfoResponse.cpp new file mode 100644 index 0000000..5601685 --- /dev/null +++ b/AusRegEPPTK/se/DomainInfoResponse.cpp @@ -0,0 +1,194 @@ +#include "se/DomainInfoResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "se/EPPDateFormatter.hpp" + +const std::string& DomainInfoResponse::DOM_ROID_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::ROID_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_CR_ID_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::CR_ID_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_UP_ID_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::UP_ID_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_CL_ID_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::CL_ID_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_CR_DATE_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::CR_DATE_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_UP_DATE_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::UP_DATE_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_TR_DATE_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::TR_DATE_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_STATUS_COUNT_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::STATUS_COUNT_EXPR()); + return expr; +} +const std::string& DomainInfoResponse::DOM_STATUS_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::STATUS_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_INF_DATA_EXPR() +{ + static const std::string expr = + DomainInfoResponse::exprReplace (InfoResponse::INF_DATA_EXPR()); + return expr; +} + +const std::string& DomainInfoResponse::DOM_NAME_EXPR() +{ + static const std::string expr = + DomainInfoResponse::DOM_INF_DATA_EXPR() + "/domain:name/text()"; + return expr; +} + +const std::string& DomainInfoResponse::DOM_PW_EXPR() +{ + static const std::string expr = + DomainInfoResponse::DOM_INF_DATA_EXPR() + "/domain:authInfo/domain:pw/text()"; + return expr; +} + +const std::string& DomainInfoResponse::DOM_REGISTRANT_EXPR() +{ + static const std::string expr = + DomainInfoResponse::DOM_INF_DATA_EXPR() + "/domain:registrant/text()"; + return expr; +} + +const std::string& DomainInfoResponse::DOM_EX_DATE_EXPR() +{ + static const std::string expr = + DomainInfoResponse::DOM_INF_DATA_EXPR() + "/domain:exDate/text()"; + return expr; +} + +const std::string& DomainInfoResponse::DOM_NS_EXPR() +{ + static const std::string expr = + DomainInfoResponse::DOM_INF_DATA_EXPR() + "/domain:ns/domain:hostObj"; + return expr; +} + +const std::string& DomainInfoResponse::DOM_HOST_EXPR() +{ + static const std::string expr = + DomainInfoResponse::DOM_INF_DATA_EXPR() + "/domain:host"; + return expr; +} + +const std::string& DomainInfoResponse::DOM_CON_EXPR() +{ + static const std::string expr = + DomainInfoResponse::DOM_INF_DATA_EXPR() + "/domain:contact[@type='TYPE']"; + return expr; +} + +const std::string& DomainInfoResponse::DOM_CON_TECH_EXPR() +{ + static const std::string expr = + StringUtils::replaceFirst (DomainInfoResponse::DOM_CON_EXPR(), "TYPE", "tech"); + return expr; +} + +const std::string& DomainInfoResponse::DOM_CON_ADMIN_EXPR() +{ + static const std::string expr = + StringUtils::replaceFirst (DomainInfoResponse::DOM_CON_EXPR(), "TYPE", "admin"); + return expr; +} + +const std::string& DomainInfoResponse::DOM_CON_BILLING_EXPR() +{ + static const std::string expr = + StringUtils::replaceFirst (DomainInfoResponse::DOM_CON_EXPR(), "TYPE", "billing"); + return expr; +} + + +DomainInfoResponse::DomainInfoResponse() + : InfoResponse(StandardObjectType::DOMAIN()) +{ } + +void DomainInfoResponse::fromXML(XMLDocument *xmlDoc) throw (ParsingException) +{ + InfoResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + + name = xmlDoc->getNodeValue(DOM_NAME_EXPR()); + pw = xmlDoc->getNodeValue(DOM_PW_EXPR()); + registrantID = xmlDoc->getNodeValue (DOM_REGISTRANT_EXPR()); + exDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime + (xmlDoc->getNodeValue (DOM_EX_DATE_EXPR()))); + delHosts = xmlDoc->getNodeValues(DOM_NS_EXPR()); + subHosts = xmlDoc->getNodeValues(DOM_HOST_EXPR()); + + techContacts = xmlDoc->getNodeValues(DOM_CON_TECH_EXPR()); + adminContacts = xmlDoc->getNodeValues(DOM_CON_ADMIN_EXPR()); + billingContacts = xmlDoc->getNodeValues(DOM_CON_BILLING_EXPR()); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + +std::string DomainInfoResponse::toString() const +{ + std::string retval = InfoResponse::toString(); + retval += "(name = " + name + ")"; + return retval; +} + + +std::string DomainInfoResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + DataResponse::OBJ(), + "domain"); +} diff --git a/AusRegEPPTK/se/DomainInfoResponse.hpp b/AusRegEPPTK/se/DomainInfoResponse.hpp new file mode 100644 index 0000000..35d320f --- /dev/null +++ b/AusRegEPPTK/se/DomainInfoResponse.hpp @@ -0,0 +1,79 @@ +#ifndef __DOMAIN_INFO_RESPONSE_HPP +#define __DOMAIN_INFO_RESPONSE_HPP + +#include "se/InfoResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +#include "xml/XMLDocument.hpp" + +#include +#include + +/** + * Use this to access domain object information as provided in an EPP domain + * info response compliant with RFCs 3730 and 3731. Such a service element is + * sent by a compliant EPP server in response to a valid domain info command, + * implemented by the DomainInfoCommand class. + * + * @see DomainInfoCommand + */ +class DomainInfoResponse : public InfoResponse +{ +public: + DomainInfoResponse(); + + const std::string & getName() const { return name; }; + const std::string & getPW() const { return pw; }; + const XMLGregorianCalendar* getExpireDate() const { return exDate.get(); }; + const std::string & getRegistrantID() const { return registrantID; }; + const std::vector & getTechContacts() const { return techContacts; }; + const std::vector & getAdminContacts() const { return adminContacts; }; + const std::vector & getBillingContacts() const { return billingContacts; }; + const std::vector & getNameservers() const { return delHosts; }; + const std::vector & getSubordinateHosts() const { return subHosts; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + virtual std::string toString() const; + +protected: + static const std::string &DOM_ROID_EXPR(), + &DOM_CR_ID_EXPR(), + &DOM_UP_ID_EXPR(), + &DOM_CL_ID_EXPR(), + &DOM_CR_DATE_EXPR(), + &DOM_UP_DATE_EXPR(), + &DOM_TR_DATE_EXPR(), + &DOM_STATUS_COUNT_EXPR(), + &DOM_STATUS_EXPR(), + &DOM_INF_DATA_EXPR(), + &DOM_NAME_EXPR(), + &DOM_PW_EXPR(), + &DOM_REGISTRANT_EXPR(), + &DOM_EX_DATE_EXPR(), + &DOM_NS_EXPR(), + &DOM_HOST_EXPR(), + &DOM_CON_EXPR(), + &DOM_CON_TECH_EXPR(), + &DOM_CON_ADMIN_EXPR(), + &DOM_CON_BILLING_EXPR(); + + const std::string& roidExpr() const { return DOM_ROID_EXPR(); }; + const std::string& crIDExpr() const { return DOM_CR_ID_EXPR(); }; + const std::string& upIDExpr() const { return DOM_UP_ID_EXPR(); }; + const std::string& clIDExpr() const { return DOM_CL_ID_EXPR(); }; + const std::string& crDateExpr() const { return DOM_CR_DATE_EXPR(); }; + const std::string& upDateExpr() const { return DOM_UP_DATE_EXPR(); }; + const std::string& trDateExpr() const { return DOM_TR_DATE_EXPR(); }; + const std::string& statusExpr() const { return DOM_STATUS_EXPR(); }; + const std::string& statusCountExpr() const { return DOM_STATUS_COUNT_EXPR(); }; + + static std::string exprReplace (const std::string &expr); + +private: + std::string name, pw, registrantID; + std::vector techContacts, adminContacts, billingContacts, + delHosts, subHosts; + std::auto_ptr exDate; +}; + +#endif // __DOMAIN_INFO_RESPONSE_HPP diff --git a/AusRegEPPTK/se/DomainKVCommandExtension.cpp b/AusRegEPPTK/se/DomainKVCommandExtension.cpp new file mode 100644 index 0000000..f474745 --- /dev/null +++ b/AusRegEPPTK/se/DomainKVCommandExtension.cpp @@ -0,0 +1,64 @@ +#include "se/DomainKVCommandExtension.hpp" +#include "se/Command.hpp" +#include "se/KVExtension.hpp" +#include "xml/XMLHelper.hpp" + +namespace { + KVExtension& kvExtension() { + static KVExtension* kvExtension = new KVExtension(); + return *kvExtension; + } +}; // anonymous namespace + +DomainKVCommandExtension::DomainKVCommandExtension( + const CommandType* commandType) : + commandName(commandType->getCommandName()), + kvLists() +{ +} + +void DomainKVCommandExtension::addToCommand(const Command &command) const +{ + XMLWriter* xmlWriter = command.getXmlWriter(); + DOMElement* extensionElement = command.getExtensionElement(); + DOMElement* commandElement = xmlWriter->appendChild(extensionElement, + commandName, kvExtension().getURI()); + + createKVListElements(xmlWriter, commandElement); +} + +void DomainKVCommandExtension::createKVListElements( + XMLWriter *xmlWriter, + DOMElement *commandElement) const +{ + DOMElement *kvlistElement = NULL; + ExtensionList::const_iterator kvListsIterator; + + for (kvListsIterator = kvLists.begin(); + kvListsIterator != kvLists.end(); + kvListsIterator++) + { + kvlistElement = xmlWriter->appendChild(commandElement, "kvlist", + kvExtension().getURI()); + kvlistElement->setAttribute(XStr("name").str(), XStr(kvListsIterator->first).str()); + addItemsToList(xmlWriter, kvListsIterator->second, kvlistElement); + } +} + +void DomainKVCommandExtension::addItemsToList( + XMLWriter *xmlWriter, + const KeyValueList &keyValueList, + DOMElement *kvlistElement) const +{ + DOMElement *element = NULL; + KeyValueList::const_iterator kvItemIterator; + + for (kvItemIterator = keyValueList.begin(); + kvItemIterator != keyValueList.end(); + kvItemIterator++) + { + element = xmlWriter->appendChild(kvlistElement, "item"); + element->setAttribute(XStr("key").str(), XStr(kvItemIterator->first).str()); + element->setTextContent(XStr(kvItemIterator->second).str()); + } +} diff --git a/AusRegEPPTK/se/DomainKVCommandExtension.hpp b/AusRegEPPTK/se/DomainKVCommandExtension.hpp new file mode 100644 index 0000000..820d105 --- /dev/null +++ b/AusRegEPPTK/se/DomainKVCommandExtension.hpp @@ -0,0 +1,58 @@ +#ifndef __DOMAIN_KV_COMMAND_EXTENSION_HPP +#define __DOMAIN_KV_COMMAND_EXTENSION_HPP + +#include +#include + +#include "xercesc/dom/DOMElement.hpp" + +#include "xml/XMLWriter.hpp" +#include "se/CommandExtension.hpp" +#include "se/CommandType.hpp" + +#include "se/KVDefs.hpp" + +class Command; + +/** + * This class models the and elements as defined in the + * AusRegistry kv-1.0 EPP command extension. + */ + +class DomainKVCommandExtension : public CommandExtension +{ + public: + /** + * Creates a key-value domain extension for specified command type + * + * @param commandType + * the type of command + */ + DomainKVCommandExtension(const CommandType *commandType); + virtual void addToCommand(const Command &command) const; + void addItem( + const std::string &listName, + const std::string &key, + const std::string &value); + private: + void createKVListElements( + XMLWriter *xmlWriter, + DOMElement *commandElement) const; + void addItemsToList( + XMLWriter *xmlWriter, + const KeyValueList &keyValueList, + DOMElement *kvlistElement) const; + + std::string commandName; + ExtensionList kvLists; +}; + +inline void DomainKVCommandExtension::addItem( + const std::string &listName, + const std::string &key, + const std::string &value) +{ + kvLists[listName][key] = value; +} + +#endif // __DOMAIN_KV_COMMAND_EXTENSION_HPP diff --git a/AusRegEPPTK/se/DomainKVCommandExtensionTest.cpp b/AusRegEPPTK/se/DomainKVCommandExtensionTest.cpp new file mode 100644 index 0000000..565bff6 --- /dev/null +++ b/AusRegEPPTK/se/DomainKVCommandExtensionTest.cpp @@ -0,0 +1,91 @@ +#include "xml/XMLParser.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" +#include "session/Timer.hpp" +#include "se/DomainKVCommandExtension.hpp" +#include "se/DomainCreateCommand.hpp" +#include "se/DomainUpdateCommand.hpp" +#include "se/StandardCommandType.hpp" +#include "se/CLTRID.hpp" + +using namespace std; + +void addSampleItemsToExtension(DomainKVCommandExtension &extension, const string &listName); + +const static string registrantName = "AusRegistry"; +const static string eligibilityType = "Trademark"; +const static string policyReason = "1"; + +void testUpdateSingleKVList() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainKVCommandExtension extension(StandardCommandType::UPDATE()); + addSampleItemsToExtension(extension, "ae"); + + DomainUpdateCommand updateCommand("jtkutest.com.ae"); + + updateCommand.appendExtension(extension); + + const string xml = updateCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aeTrademark1AusRegistryJTKUTEST.20070101.010101.0" + ); +} + +void testCreateSingleKVList() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainKVCommandExtension extension(StandardCommandType::CREATE()); + addSampleItemsToExtension(extension, "ae"); + + string registrant("JTKCON"); + DomainCreateCommand createCommand("jtkutest.com.ae", "jtkUT3st", ®istrant); + + createCommand.appendExtension(extension); + + const string xml = createCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aeJTKCONjtkUT3stTrademark1AusRegistryJTKUTEST.20070101.010101.0" + ); +} + +void testMultipleKVList() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainKVCommandExtension extension(StandardCommandType::CREATE()); + addSampleItemsToExtension(extension, "ae"); + addSampleItemsToExtension(extension, "au"); + + string registrant("JTKCON"); + DomainCreateCommand createCommand("jtkutest.com.ae", "jtkUT3st", ®istrant); + + createCommand.appendExtension(extension); + + const string xml = createCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aeJTKCONjtkUT3stTrademark1AusRegistryTrademark1AusRegistryJTKUTEST.20070101.010101.0" + ); +} + +void addSampleItemsToExtension(DomainKVCommandExtension &extension, const string &listName) +{ + extension.addItem(listName, "eligibilityType", eligibilityType); + extension.addItem(listName, "policyReason", policyReason); + extension.addItem(listName, "registrantName", registrantName); +} + +int main(int argc, char* argv[]) +{ + init("etc/toolkit2.conf"); + TEST_run(testUpdateSingleKVList); + TEST_run(testCreateSingleKVList); + TEST_run(testMultipleKVList); + + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainNotificationResponse.cpp b/AusRegEPPTK/se/DomainNotificationResponse.cpp new file mode 100644 index 0000000..cd8c14c --- /dev/null +++ b/AusRegEPPTK/se/DomainNotificationResponse.cpp @@ -0,0 +1,57 @@ +#include "se/DomainNotificationResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "common/StringUtils.hpp" + +using namespace std; + +DomainNotificationResponse::DomainNotificationResponse() + : NotificationResponse(StandardObjectType::DOMAIN()) +{ +} + +string DomainNotificationResponse::exprReplace(const string& expr) +{ + return StringUtils::replaceAll( + StringUtils::replaceAll( + expr, + DataResponse::OBJ(), + StandardObjectType::DOMAIN()->getName()), + NotificationResponse::IDENT(), + StandardObjectType::DOMAIN()->getIdentType()); +} + +const string& DomainNotificationResponse::DOM_NAME_EXPR() +{ + static const string expr = DomainNotificationResponse::exprReplace( + NotificationResponse::IDENT_EXPR()); + return expr; +} + +const string& DomainNotificationResponse::DOM_RESULT_EXPR() +{ + static const string expr = DomainNotificationResponse::exprReplace( + NotificationResponse::RESULT_EXPR()); + return expr; +} + +const string& DomainNotificationResponse::DOM_CLTRID_EXPR() +{ + static const string expr = DomainNotificationResponse::exprReplace( + NotificationResponse::CLTRID_EXPR()); + return expr; +} + +const string& DomainNotificationResponse::DOM_SVTRID_EXPR() +{ + static const string expr = DomainNotificationResponse::exprReplace( + NotificationResponse::SVTRID_EXPR()); + return expr; +} + +const string& DomainNotificationResponse::DOM_PADATE_EXPR() +{ + static const string expr = DomainNotificationResponse::exprReplace( + NotificationResponse::PADATE_EXPR()); + return expr; +} + diff --git a/AusRegEPPTK/se/DomainNotificationResponse.hpp b/AusRegEPPTK/se/DomainNotificationResponse.hpp new file mode 100644 index 0000000..f114d13 --- /dev/null +++ b/AusRegEPPTK/se/DomainNotificationResponse.hpp @@ -0,0 +1,34 @@ +#ifndef DOMAIN_NOTIFICATION_RESPONSE +#define DOMAIN_NOTIFICATION_RESPONSE + +#include "se/NotificationResponse.hpp" + +using namespace std; + +/** + * Notification data specific to domain objects. Refer to + * {@link NotificationResponse} for further details. + */ +class DomainNotificationResponse : public NotificationResponse +{ + public: + DomainNotificationResponse(); + + protected: + const string& identifierExpr() const { return DOM_NAME_EXPR(); }; + const string& resultExpr() const { return DOM_RESULT_EXPR(); }; + const string& cltridExpr() const { return DOM_CLTRID_EXPR(); }; + const string& svtridExpr() const { return DOM_SVTRID_EXPR(); }; + const string& padateExpr() const { return DOM_PADATE_EXPR(); }; + + static string exprReplace(const string &expr); + + private: + static const string& DOM_NAME_EXPR(); + static const string& DOM_RESULT_EXPR(); + static const string& DOM_CLTRID_EXPR(); + static const string& DOM_SVTRID_EXPR(); + static const string& DOM_PADATE_EXPR(); +}; + +#endif /* DOMAIN_NOTIFICATION_RESPONSE */ diff --git a/AusRegEPPTK/se/DomainRegistrantTransferCommand.cpp b/AusRegEPPTK/se/DomainRegistrantTransferCommand.cpp new file mode 100644 index 0000000..79ae7af --- /dev/null +++ b/AusRegEPPTK/se/DomainRegistrantTransferCommand.cpp @@ -0,0 +1,73 @@ +#include "se/Period.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/DomainRegistrantTransferCommand.hpp" +#include "se/StandardCommandType.hpp" +#include "se/RegistrantTransferCommandType.hpp" +#include "se/EPPDateFormatter.hpp" +#include "se/Period.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/KVExtension.hpp" +#include "se/RegistrantObjectType.hpp" +#include "se/CLTRID.hpp" +#include "xml/XMLHelper.hpp" + +namespace { +RegistrantObjectType& registrantObjectType() { + static RegistrantObjectType* registrantObjectType = new RegistrantObjectType(); + return *registrantObjectType; + } + KVExtension& kvExtension() { + static KVExtension* kvExtension = new KVExtension(); + return *kvExtension; + } + const RegistrantTransferCommandType rtrnType; +} // anonymous namespace + +DomainRegistrantTransferCommand::DomainRegistrantTransferCommand(const std::string& name, + const XMLGregorianCalendar& curExpDate, + const std::string& kvListName, + const std::string& explanation, + const Period* period) : + SendSE() +{ + command = xmlWriter->appendChild(xmlWriter->appendChild( + xmlWriter->getRoot(), "extension"), "command", + registrantObjectType().getURI()); + + DOMElement *cmdElement = xmlWriter->appendChild(command, rtrnType.getCommandName()); + + XMLHelper::setTextContent(xmlWriter->appendChild(cmdElement, registrantObjectType().getIdentType()), name); + + std::string curExpDateStr = EPPDateFormatter::toXSDate(curExpDate); + XMLHelper::setTextContent( + xmlWriter->appendChild(cmdElement, "curExpDate"), curExpDateStr); + + if (period != NULL) { + period->appendPeriod(xmlWriter, cmdElement); + } + + kvListElement = xmlWriter->appendChild(cmdElement, "kvlist", kvExtension().getURI()); + XMLHelper::setAttribute(kvListElement, "name", kvListName); + + XMLHelper::setTextContent( + xmlWriter->appendChild(cmdElement, "explanation"), explanation); +} + +std::string DomainRegistrantTransferCommand::toXMLImpl() +{ + KeyValueList::const_iterator itemIterator; + for (itemIterator = kvList.begin(); + itemIterator != kvList.end(); + itemIterator++) + { + DOMElement *itemElement = xmlWriter->appendChild(kvListElement, "item"); + XMLHelper::setAttribute(itemElement, "key", itemIterator->first); + XMLHelper::setTextContent(itemElement, itemIterator->second); + } + + XMLHelper::setTextContent( + xmlWriter->appendChild(command, "clTRID"), + CLTRID::nextVal()); + + return xmlWriter->toXML(); +} diff --git a/AusRegEPPTK/se/DomainRegistrantTransferCommand.hpp b/AusRegEPPTK/se/DomainRegistrantTransferCommand.hpp new file mode 100644 index 0000000..bfaf4e3 --- /dev/null +++ b/AusRegEPPTK/se/DomainRegistrantTransferCommand.hpp @@ -0,0 +1,69 @@ +#ifndef DOMAIN_REGISTRANT_TRANSFER_COMMAND_HPP_ +#define DOMAIN_REGISTRANT_TRANSFER_COMMAND_HPP_ + +#include + +#include "se/Command.hpp" +#include "se/KVDefs.hpp" + +class XMLGregorianCalendar; +class Period; + +/** + * In cases where the legal registrant of a domain name has changed, this + * class should be used to request a transfer of registrant. This is a + * different action to correcting extension data which was originally specified + * incorrectly, and should only be used in the situation described. + * + * Use this class to generate a standards-compliant XML document, given simple + * input parameters. The \c toXML() method in Command serialises this object to + * XML. + */ +class DomainRegistrantTransferCommand : public SendSE +{ + public: + /** + * Request that the domain name be transferred to the legal entity + * specified by the extension data that is provided in the key-value list. + * + * @param name + * The domain name to transfer. + * + * @param curExpDate + * The current expiry of the identified domain name. This is + * required in order to prevent repeated transfer of the name due + * to protocol transmission failures. + * + * @param period + * The desired new validity period, starting from the time the + * transfer completes successfully. + * + * @param kvListName + * The name under which the list of key-value items are aggregated. + * + * @param explanation + * An explanation of how the transfer was effected. + */ + DomainRegistrantTransferCommand (const std::string& name, + const XMLGregorianCalendar& curExpDate, + const std::string& kvListName, + const std::string& explanation, + const Period* period = NULL); + + /** + * Adds a key-value item into the list, to be included in the command when + * the XML is generated. + */ + void addItem(const std::string &key, const std::string &value) + { + kvList[key] = value; + } + private: + virtual std::string toXMLImpl(); + + DOMElement *command; + DOMElement *kvListElement; + KeyValueList kvList; +}; + +#endif /* DOMAIN_REGISTRANT_TRANSFER_COMMAND_HPP_ */ diff --git a/AusRegEPPTK/se/DomainRegistrantTransferCommandTest.cpp b/AusRegEPPTK/se/DomainRegistrantTransferCommandTest.cpp new file mode 100644 index 0000000..98fc8de --- /dev/null +++ b/AusRegEPPTK/se/DomainRegistrantTransferCommandTest.cpp @@ -0,0 +1,74 @@ +#include "se/DomainRegistrantTransferCommand.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "se/Period.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +using namespace std; + +const static std::string registrantName = "AusRegistry"; +const static std::string registrantIDValue = "01241326211"; +const static std::string registrantIDType = "Trade License"; +const static std::string eligibilityType = "Trademark"; +const static std::string policyReason = "1"; +const static std::string eligibilityName = "Blah"; +const static std::string eligibilityIDValue = "1231239523"; +const static std::string eligibilityIDType = "Trademark"; +const auto_ptr curExpDate(EPPDateFormatter::fromXSDateTime("2007-01-01T01:01:01.0Z")); +const static std::string kvListName = "ae"; +void addSampleKVItems(DomainRegistrantTransferCommand *command); + +void testWithoutPeriod() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + auto_ptr command( + new DomainRegistrantTransferCommand("jtkutest.com.ae", *curExpDate, kvListName, "testing")); + addSampleKVItems(command.get()); + + const std::string xml = command->toXML(); + ASSERT_EQ(xml, + "jtkutest.com.ae" + + EPPDateFormatter::toXSDate(*curExpDate) + + "Trademark1231239523BlahTrademark1Trade License01241326211AusRegistrytestingJTKUTEST.20070101.010101.0" + ); +} + +void testWithPeriod() +{ + Period period(2, PeriodUnit::YEARS()); + auto_ptr command( + new DomainRegistrantTransferCommand("jtkutest.com.ae", *curExpDate, kvListName, "testing", &period)); + addSampleKVItems(command.get()); + + const std::string xml = command->toXML(); + ASSERT_EQ(xml, + "jtkutest.com.ae" + + EPPDateFormatter::toXSDate(*curExpDate) + + "2Trademark1231239523BlahTrademark1Trade License01241326211AusRegistrytestingJTKUTEST.20070101.010101.0" + ); +} + +void addSampleKVItems(DomainRegistrantTransferCommand *command) +{ + command->addItem("policyReason", policyReason); + command->addItem("eligibilityIDType", eligibilityIDType); + command->addItem("registrantIDType", registrantIDType); + command->addItem("registrantIDValue", registrantIDValue); + command->addItem("registrantName", registrantName); + command->addItem("eligibilityIDValue", eligibilityIDValue); + command->addItem("eligibilityName", eligibilityName); + command->addItem("eligibilityType", eligibilityType); +} + +int main(int argc, char* argv[]) +{ + init("etc/toolkit2.conf"); + TEST_run(testWithoutPeriod); +// TEST_run(testWithPeriod); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/DomainRegistrantTransferResponse.cpp b/AusRegEPPTK/se/DomainRegistrantTransferResponse.cpp new file mode 100644 index 0000000..1c6d011 --- /dev/null +++ b/AusRegEPPTK/se/DomainRegistrantTransferResponse.cpp @@ -0,0 +1,37 @@ +#include "se/DomainRegistrantTransferResponse.hpp" +#include "se/RegistrantObjectType.hpp" +#include "se/RegistrantTransferCommandType.hpp" +#include "se/EPPDateFormatter.hpp" + +namespace { + const RegistrantTransferCommandType rtrnType; + const RegistrantObjectType registrantType; +} // anonymous namespace + +using namespace std; + +const string DomainRegistrantTransferResponse::REGISTRANT_NAME_EXPR = + "/e:epp/e:response/e:resData/registrant:rtrnData/registrant:name/text()"; + +const string DomainRegistrantTransferResponse::REGISTRANT_EX_DATE_EXPR = + "/e:epp/e:response/e:resData/registrant:rtrnData/registrant:exDate/text()"; + +DomainRegistrantTransferResponse::DomainRegistrantTransferResponse() + : DataResponse(&rtrnType, ®istrantType) +{ +} + +void DomainRegistrantTransferResponse::fromXML(XMLDocument* xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + name = xmlDoc->getNodeValue(REGISTRANT_NAME_EXPR); + std::string exDateStr = xmlDoc->getNodeValue(REGISTRANT_EX_DATE_EXPR); + exDate = std::auto_ptr( + EPPDateFormatter::fromXSDateTime(exDateStr)); +} + diff --git a/AusRegEPPTK/se/DomainRegistrantTransferResponse.hpp b/AusRegEPPTK/se/DomainRegistrantTransferResponse.hpp new file mode 100644 index 0000000..52188b1 --- /dev/null +++ b/AusRegEPPTK/se/DomainRegistrantTransferResponse.hpp @@ -0,0 +1,35 @@ +#ifndef __DOMAIN_REGISTRANT_TRANSFER_RESPONSE +#define __DOMAIN_REGISTRANT_TRANSFER_RESPONSE + +#include "se/DataResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +/** + * Use this to access registrant transfer data for a domain as provided in an + * EPP registrantTransfer response using the + * \c urn:X-ar:params:xml:ns:registrant-1.0 namespace. Such a service + * element is sent by a compliant EPP server in response to a valid domain + * registrant transfer command, implemented by the + * DomainRegistrantTransferCommand. + * + * @see DomainRegistrantTransferCommand + */ + +class DomainRegistrantTransferResponse : public DataResponse +{ +public: + DomainRegistrantTransferResponse(); + + const std::string& getName() const { return name; } + const XMLGregorianCalendar* getExpiryDate() const { return exDate.get(); } + void fromXML(XMLDocument* xmlDoc) throw (ParsingException); + +private: + static const std::string REGISTRANT_NAME_EXPR; + static const std::string REGISTRANT_EX_DATE_EXPR; + + std::string name; + std::auto_ptr exDate; +}; + +#endif // __DOMAIN_REGISTRANT_TRANSFER_RESPONSE diff --git a/AusRegEPPTK/se/DomainRegistrantTransferResponseTest.cpp b/AusRegEPPTK/se/DomainRegistrantTransferResponseTest.cpp new file mode 100644 index 0000000..cc2e950 --- /dev/null +++ b/AusRegEPPTK/se/DomainRegistrantTransferResponseTest.cpp @@ -0,0 +1,38 @@ +#include "se/DomainRegistrantTransferResponse.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" +#include "se/EPPDateFormatter.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + const string xml = + "Command completed successfullyexample.com2009-04-03T22:00:00.0ZABC-1234554321-XYZ"; + + DomainRegistrantTransferResponse response; + + XMLParser parser; + auto_ptr doc(parser.parse(xml)); + response.fromXML(doc.get()); + { + ASSERT_EQ(response.getName(), "example.com"); + const XMLGregorianCalendar *exDate = response.getExpiryDate(); + string res = EPPDateFormatter::toXSDateTime(*exDate); + ASSERT_EQ(res, "2009-04-03T22:00:00.0Z"); + const vector& results(response.getResults()); + ASSERT_EQ(response.getCLTRID(), "ABC-12345"); + ASSERT_EQ(results[0].getResultCode(), 1000); + ASSERT_EQ(results[0].getResultMessage(), + "Command completed successfully"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainRem.hpp b/AusRegEPPTK/se/DomainRem.hpp new file mode 100644 index 0000000..6f53bed --- /dev/null +++ b/AusRegEPPTK/se/DomainRem.hpp @@ -0,0 +1,26 @@ +#ifndef __DOMAINREM_HPP +#define __DOMAINREM_HPP + +#include "se/DomainAddRem.hpp" + +/** + * Use this to specify attributes to remove from a domain object in a domain + * update EPP command service element. The DomainUpdateCommand uses an + * instance of this to build the appropriate elements in order to request the + * removal of these attributes from a domain object. + */ +class DomainRem : public DomainAddRem +{ +public: + DomainRem(const std::vector *nameservers, + const std::vector *techContacts, + const std::vector *adminContacts, + const std::vector *billingContacts, + const std::vector *statuses) + : DomainAddRem(AddRemType::REM(), + nameservers, techContacts, adminContacts, + billingContacts, statuses) + { } +}; + +#endif // __DOMAINREM_HPP diff --git a/AusRegEPPTK/se/DomainRenewCommand.cpp b/AusRegEPPTK/se/DomainRenewCommand.cpp new file mode 100644 index 0000000..664c705 --- /dev/null +++ b/AusRegEPPTK/se/DomainRenewCommand.cpp @@ -0,0 +1,37 @@ +#include "se/DomainRenewCommand.hpp" + +#include "se/StandardCommandType.hpp" +#include "se/StandardObjectType.hpp" +#include "xml/XMLHelper.hpp" +#include "se/EPPDateFormatter.hpp" + +DomainRenewCommand::DomainRenewCommand (const std::string &name, + const XMLGregorianCalendar &exDate) + : ObjectCommand(StandardCommandType::RENEW(), + StandardObjectType::DOMAIN(), + name) +{ + Init(name, exDate); +} + + +DomainRenewCommand::DomainRenewCommand (const std::string &name, + const XMLGregorianCalendar &exDate, + const Period &period) + : ObjectCommand(StandardCommandType::RENEW(), + StandardObjectType::DOMAIN(), + name) +{ + Init(name, exDate); + + period.appendPeriod (xmlWriter, objElement); +} + + +void DomainRenewCommand::Init (const std::string &name, + const XMLGregorianCalendar &exDate) +{ + XMLHelper::setTextContent + (xmlWriter->appendChild (objElement, "curExpDate"), + EPPDateFormatter::toXSDateTime(exDate)); +} diff --git a/AusRegEPPTK/se/DomainRenewCommand.hpp b/AusRegEPPTK/se/DomainRenewCommand.hpp new file mode 100644 index 0000000..b15e433 --- /dev/null +++ b/AusRegEPPTK/se/DomainRenewCommand.hpp @@ -0,0 +1,30 @@ +#ifndef __DOMAIN_RENEW_COMMAND_HPP +#define __DOMAIN_RENEW_COMMAND_HPP + +#include "se/ObjectCommand.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/Period.hpp" + +/** + * Use this to request the renewal of a domain object provisioned in an EPP + * Registry. The requesting client must be the sponsoring client of the domain + * object. Instances of this class generate RFC3730 and RFC3731 compliant + * domain renew EPP command service elements via the toXML method. The + * response expected from a server should be handled by a DomainRenewResponse + * object. + * + * @see DomainRenewResponse + */ +class DomainRenewCommand : public ObjectCommand +{ +public: + DomainRenewCommand (const std::string &name, const XMLGregorianCalendar& exDate); + DomainRenewCommand (const std::string &name, + const XMLGregorianCalendar &exDate, + const Period &period); +private: + void Init (const std::string &name, + const XMLGregorianCalendar &exDate); +}; + +#endif // __DOMAIN_RENEW_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainRenewResponse.cpp b/AusRegEPPTK/se/DomainRenewResponse.cpp new file mode 100644 index 0000000..b1e4035 --- /dev/null +++ b/AusRegEPPTK/se/DomainRenewResponse.cpp @@ -0,0 +1,40 @@ +#include "se/DomainRenewResponse.hpp" +#include "se/StandardCommandType.hpp" +#include "se/StandardObjectType.hpp" +#include "se/EPPDateFormatter.hpp" + +const std::string DomainRenewResponse::DOM_NAME_EXPR + (DataResponse::RES_DATA_EXPR() + "/domain:renData/domain:name/text()"); + +const std::string DomainRenewResponse::DOM_EX_DATE_EXPR + (DataResponse::RES_DATA_EXPR() + "/domain:renData/domain:exDate/text()"); + +DomainRenewResponse::DomainRenewResponse () + : DataResponse(StandardCommandType::RENEW(), StandardObjectType::DOMAIN()) +{ +} + +void DomainRenewResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML (xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + name = xmlDoc->getNodeValue (DOM_NAME_EXPR); + std::string exDateStr = xmlDoc->getNodeValue (DOM_EX_DATE_EXPR); + exDate = std::auto_ptr( + EPPDateFormatter::fromXSDateTime(exDateStr)); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + diff --git a/AusRegEPPTK/se/DomainRenewResponse.hpp b/AusRegEPPTK/se/DomainRenewResponse.hpp new file mode 100644 index 0000000..14fe3e4 --- /dev/null +++ b/AusRegEPPTK/se/DomainRenewResponse.hpp @@ -0,0 +1,34 @@ +#ifndef __DOMAIN_RENEW_RESPONSE_HPP +#define __DOMAIN_RENEW_RESPONSE_HPP + +#include "se/DataResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +#include + +/** + * Use this to access domain object renewal response data as provided in an EPP + * domain renew response compliant with RFCs 3730 and 3731. Such a service + * element is sent by a compliant EPP server in response to a valid domain renew + * command, implemented by the DomainRenewCommand class. + * + * @see DomainRenewCommand + */ +class DomainRenewResponse : public DataResponse +{ +public: + DomainRenewResponse (); + + const std::string & getName() const { return name; }; + const XMLGregorianCalendar* getExpiryDate() const { return exDate.get(); }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +private: + static const std::string DOM_NAME_EXPR, + DOM_EX_DATE_EXPR; + std::string name; + std::auto_ptr exDate; +}; + +#endif // __DOMAIN_RENEW_RESPONSE_HPP diff --git a/AusRegEPPTK/se/DomainTransferApproveCommand.hpp b/AusRegEPPTK/se/DomainTransferApproveCommand.hpp new file mode 100644 index 0000000..3c2853f --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferApproveCommand.hpp @@ -0,0 +1,51 @@ +#ifndef __DOMAIN_TRANSFER_APPROVE_COMMAND_HPP +#define __DOMAIN_TRANSFER_APPROVE_COMMAND_HPP + +#include "se/DomainTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to approve the transfer of a domain object currently pending + * transfer. The domain object must be sponsored by the client attempting to + * approve the transfer. Instances of this class generate RFC3730 and RFC3731 + * compliant domain transfer EPP command service elements via the toXML method + * with the transfer operation set to "approve". + * + * @see DomainTransferResponse + */ +class DomainTransferApproveCommand : public DomainTransferCommand +{ +public: + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'approve' transfer operation. + * + * @param name The name of the domain to approve transfer of. + * + * @param pw The identified domain's password. + */ + DomainTransferApproveCommand (const std::string &name, + const std::string &pw) + : DomainTransferCommand (TransferOp::APPROVE(), name, pw) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'approve' transfer operation. + * + * @param name The name of the domain to approve transfer of. + * + * @param roid The repository object identifier of the contact for which + * the password is specified. The identified contact must be a contact + * associated with the domain object being transferred. + * + * @param pw The password of the contact identified by the supplied roid. + */ + DomainTransferApproveCommand (const std::string &name, + const std::string &roid, + const std::string &pw) + : DomainTransferCommand (TransferOp::APPROVE(), name, roid, pw) + { } +}; + +#endif // __DOMAIN_TRANSFER_APPROVE_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainTransferCancelCommand.hpp b/AusRegEPPTK/se/DomainTransferCancelCommand.hpp new file mode 100644 index 0000000..a5a3758 --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferCancelCommand.hpp @@ -0,0 +1,50 @@ +#ifndef __DOMAIN_TRANSFER_CANCEL_COMMAND_HPP +#define __DOMAIN_TRANSFER_CANCEL_COMMAND_HPP + +#include "se/DomainTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to cancel the transfer of a domain object currently pending + * transfer. The transfer must have been initiated via a transfer request by + * the client attempting to cancel the transfer. Instances of this class + * generate RFC3730 and RFC3731 compliant domain transfer EPP command service + * elements via the toXML method with the transfer operation set to "cancel". + * + * @see DomainTransferResponse + */ +class DomainTransferCancelCommand : public DomainTransferCommand +{ +public: + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'cancel' transfer operation. + * + * @param name The name of the domain to cancel transfer of. + * + * @param pw The identified domain's password. + */ + DomainTransferCancelCommand (const std::string &name, const std::string &pw) + : DomainTransferCommand (TransferOp::CANCEL(), name, pw) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'cancel' transfer operation. + * + * @param name The name of the domain to cancel transfer of. + * + * @param roid The repository object identifier of the contact for which + * the password is specified. The identified contact must be a contact + * associated with the domain object being transferred. + * + * @param pw The password of the contact identified by the supplied roid. + */ + DomainTransferCancelCommand (const std::string &name, + const std::string &roid, + const std::string &pw) + : DomainTransferCommand (TransferOp::CANCEL(), name, roid, pw) + { } +}; + +#endif // __DOMAIN_TRANSFER_CANCEL_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainTransferCommand.hpp b/AusRegEPPTK/se/DomainTransferCommand.hpp new file mode 100644 index 0000000..c7b4b6d --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferCommand.hpp @@ -0,0 +1,48 @@ +#ifndef __DOMAIN_TRANSFER_COMMAND_HPP +#define __DOMAIN_TRANSFER_COMMAND_HPP + +#include "se/TransferCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * The superclass of all domain transfer command classes. Subclasses are + * responsible for specifying the kind of transfer operation, but hiding the + * implementation from the user. + */ +class DomainTransferCommand : public TransferCommand +{ +public: + DomainTransferCommand (const TransferOp *operation, + const std::string &name) + : TransferCommand (StandardObjectType::DOMAIN(), operation, name) {}; + + DomainTransferCommand (const TransferOp *operation, + const std::string &name, + const std::string &pw) + : TransferCommand (StandardObjectType::DOMAIN(), + operation, name, pw) {}; + + DomainTransferCommand (const TransferOp *operation, + const std::string &name, + const std::string &roid, + const std::string &pw) + : TransferCommand (StandardObjectType::DOMAIN(), + operation, name, roid, pw) {}; + + DomainTransferCommand (const TransferOp *operation, + const std::string &name, + const Period &period, + const std::string &pw) + : TransferCommand (StandardObjectType::DOMAIN(), + operation, name, period, pw) {}; + + DomainTransferCommand (const TransferOp *operation, + const std::string &name, + const Period &period, + const std::string &roid, + const std::string &pw) + : TransferCommand (StandardObjectType::DOMAIN(), + operation, name, period, roid, pw) {}; +}; + +#endif // __DOMAIN_TRANSFER_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainTransferQueryCommand.hpp b/AusRegEPPTK/se/DomainTransferQueryCommand.hpp new file mode 100644 index 0000000..83adb08 --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferQueryCommand.hpp @@ -0,0 +1,59 @@ +#ifndef __DOMAIN_TRANSFER_QUERY_COMMAND_HPP +#define __DOMAIN_TRANSFER_QUERY_COMMAND_HPP + +#include "se/DomainTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to query the transfer state of a domain object. Instances of this + * class generate RFC3730 and RFC3731 compliant domain transfer EPP command + * service elements via the toXML method with the transfer operation set to + * "query". + * + * @see DomainTransferResponse + */ +class DomainTransferQueryCommand : public DomainTransferCommand +{ +public: + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the 'query' transfer operation. + * + * @param name The name of the domain to query the transfer state of. + */ + DomainTransferQueryCommand (const std::string &name) + : DomainTransferCommand (TransferOp::QUERY(), name) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'query' transfer operation. + * + * @param name The name of the domain to query the transfer state of. + * + * @param pw The identified domain's password. + */ + DomainTransferQueryCommand (const std::string &name, const std::string &pw) + : DomainTransferCommand (TransferOp::QUERY(), name, pw) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'query' transfer operation. + * + * @param name The name of the domain to query the transfer state of. + * + * @param roid The repository object identifier of the contact for which + * the password is specified. The identified contact must be a contact + * associated with the domain object being transferred. + * + * @param pw The password of the contact identified by the supplied roid. + */ + DomainTransferQueryCommand (const std::string &name, + const std::string &roid, + const std::string &pw) + : DomainTransferCommand (TransferOp::QUERY(), name, roid, pw) + { } +}; + +#endif // __DOMAIN_TRANSFER_QUERY_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainTransferQueryCommandTest.cpp b/AusRegEPPTK/se/DomainTransferQueryCommandTest.cpp new file mode 100644 index 0000000..8939ce8 --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferQueryCommandTest.cpp @@ -0,0 +1,50 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/DomainTransferQueryCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + DomainTransferQueryCommand cmd("jtkutest.com.au"); + const string xml(cmd.toXML()); + + ASSERT_EQ(xml, "jtkutest.com.auJTKUTEST.20070101.010101.0"); + } + + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + DomainTransferQueryCommand cmd("jtkutest.com.au", "jtkUt3st"); + const string xml(cmd.toXML()); + + ASSERT_EQ(xml, "jtkutest.com.aujtkUt3stJTKUTEST.20070101.010101.0"); + } + + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + DomainTransferQueryCommand cmd("jtkutest.com.au", "C100000-AR", "jtkUt3st"); + const string xml(cmd.toXML()); + + ASSERT_EQ(xml, "jtkutest.com.aujtkUt3stJTKUTEST.20070101.010101.0"); + } + +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainTransferRejectCommand.hpp b/AusRegEPPTK/se/DomainTransferRejectCommand.hpp new file mode 100644 index 0000000..77d021f --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferRejectCommand.hpp @@ -0,0 +1,49 @@ +#ifndef __DOMAIN_TRANSFER_REJECT_COMMAND_HPP +#define __DOMAIN_TRANSFER_REJECT_COMMAND_HPP + +#include "se/DomainTransferCommand.hpp" + +/** + * Use this to reject the transfer of a domain object currently pending + * transfer. The domain object must be sponsored by the client attempting to + * reject the transfer. Instances of this class generate RFC3730 and RFC3731 + * compliant domain transfer EPP command service elements via the toXML method + * with the transfer operation set to "reject". + * + * @see DomainTransferResponse + */ +class DomainTransferRejectCommand : public DomainTransferCommand +{ +public: + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'reject' transfer operation. + * + * @param name The name of the domain to reject transfer of. + * + * @param pw The identified domain's password. + */ + DomainTransferRejectCommand (const std::string &name, const std::string &pw) + : DomainTransferCommand (TransferOp::REJECT(), name, pw) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'reject' transfer operation. + * + * @param name The name of the domain to reject transfer of. + * + * @param roid The repository object identifier of the contact for which + * the password is specified. The identified contact must be a contact + * associated with the domain object being transferred. + * + * @param pw The password of the contact identified by the supplied roid. + */ + DomainTransferRejectCommand (const std::string &name, + const std::string &roid, + const std::string &pw) + : DomainTransferCommand (TransferOp::REJECT(), name, roid, pw) + { } +}; + +#endif // __DOMAIN_TRANSFER_REJECT_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainTransferRequestCommand.hpp b/AusRegEPPTK/se/DomainTransferRequestCommand.hpp new file mode 100644 index 0000000..2ced10e --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferRequestCommand.hpp @@ -0,0 +1,90 @@ +#ifndef __DOMAIN_TRANSFER_REQUEST_COMMAND_HPP +#define __DOMAIN_TRANSFER_REQUEST_COMMAND_HPP + +#include "se/DomainTransferCommand.hpp" +#include "se/TransferOp.hpp" + +/** + * Use this to request the transfer of a domain object from another client. + * The domain object MUST NOT be sponsored by the client attempting to request + * the transfer. Instances of this class generate RFC3730 and RFC3731 + * compliant domain transfer EPP command service elements via the toXML method + * with the transfer operation set to "request". + * + * @see DomainTransferResponse + */ +class DomainTransferRequestCommand : public DomainTransferCommand +{ +public: + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'request' transfer operation. + * + * @param name The name of the domain to request transfer of. + * + * @param pw The identified domain's password. + */ + DomainTransferRequestCommand (const std::string &name, + const std::string &pw) + : DomainTransferCommand (TransferOp::REQUEST(), name, pw) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'request' transfer operation. + * + * @param name The name of the domain to request transfer of. + * + * @param roid The repository object identifier of the contact for which + * the password is specified. The identified contact must be a contact + * associated with the domain object being transferred. + * + * @param pw The password of the contact identified by the supplied roid. + */ + DomainTransferRequestCommand (const std::string &name, + const std::string &roid, + const std::string &pw) + : DomainTransferCommand (TransferOp::REQUEST(), name, roid, pw) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'request' transfer operation. + * + * @param name The name of the domain to request transfer of. + * + * @param period The period of time to extend the validity period of the + * domain by upon approval of the transfer. + * + * @param pw The identified domain's password. + */ + DomainTransferRequestCommand (const std::string &name, + const Period &period, + const std::string &pw) + : DomainTransferCommand (TransferOp::REQUEST(), name, period, pw) + { } + + /** + * Create a domain transfer command for the idenfitied domain, specifying + * the designated password and the 'request' transfer operation. + * + * @param name The name of the domain to request transfer of. + * + * @param period The period of time to extend the validity period of the + * domain by upon approval of the transfer. + * + * @param roid The repository object identifier of the contact for which + * the password is specified. The identified contact must be a contact + * associated with the domain object being transferred. + * + * @param pw The password of the contact identified by the supplied roid. + */ + DomainTransferRequestCommand(const std::string &name, + const Period &period, + const std::string &roid, + const std::string &pw) + : DomainTransferCommand(TransferOp::REQUEST(), name, period, roid, pw) + { } +}; + +#endif // __DOMAIN_TRANSFER_REQUEST_COMMAND_HPP diff --git a/AusRegEPPTK/se/DomainTransferResponse.cpp b/AusRegEPPTK/se/DomainTransferResponse.cpp new file mode 100644 index 0000000..bd83417 --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferResponse.cpp @@ -0,0 +1,68 @@ +#include "se/DomainTransferResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "se/EPPDateFormatter.hpp" +#include "common/StringUtils.hpp" + +const std::string DomainTransferResponse::DOM_NAME_EXPR + (DataResponse::RES_DATA_EXPR() + "/domain:trnData/domain:name/text()"); + +const std::string DomainTransferResponse::DOM_EXDATE_EXPR + (DataResponse::RES_DATA_EXPR() + "/domain:trnData/domain:exDate/text()"); + +const std::string DomainTransferResponse::DOM_TR_STATUS_EXPR + (DomainTransferResponse::exprReplace + (TransferResponse::TR_STATUS_EXPR())); + +const std::string DomainTransferResponse::DOM_REID_EXPR + (DomainTransferResponse::exprReplace + (TransferResponse::REID_EXPR())); + +const std::string DomainTransferResponse::DOM_REDATE_EXPR + (DomainTransferResponse::exprReplace + (TransferResponse::REDATE_EXPR())); + +const std::string DomainTransferResponse::DOM_ACID_EXPR + (DomainTransferResponse::exprReplace + (TransferResponse::ACID_EXPR())); + +const std::string DomainTransferResponse::DOM_ACDATE_EXPR + (DomainTransferResponse::exprReplace + (TransferResponse::ACDATE_EXPR())); + + +DomainTransferResponse::DomainTransferResponse() + : TransferResponse(StandardObjectType::DOMAIN()) +{ +} + +void DomainTransferResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + TransferResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + name = xmlDoc->getNodeValue(DOM_NAME_EXPR); + std::string exDateStr = xmlDoc->getNodeValue(DOM_EXDATE_EXPR); + if (exDateStr.length() > 0) + exDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(exDateStr)); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + + +std::string DomainTransferResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + TransferResponse::OBJ(), + StandardObjectType::DOMAIN()->getName()); +} diff --git a/AusRegEPPTK/se/DomainTransferResponse.hpp b/AusRegEPPTK/se/DomainTransferResponse.hpp new file mode 100644 index 0000000..53dd4c9 --- /dev/null +++ b/AusRegEPPTK/se/DomainTransferResponse.hpp @@ -0,0 +1,54 @@ +#ifndef __DOMAIN_TRANSFER_RESPONSE_HPP +#define __DOMAIN_TRANSFER_RESPONSE_HPP + +#include "se/TransferResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" + +#include + +/** + * Use this to access domain object transfer information as provided in an EPP + * domain transfer response compliant with RFCs 3730 and 3731. Such a service + * element is sent by a compliant EPP server in response to a valid domain + * transfer command, implemented by a subclass of the DomainTransferCommand + * class. + * + * @see DomainTransferCommand + * @see DomainTransferRequestCommand + * @see DomainTransferApproveCommand + * @see DomainTransferCancelCommand + * @see DomainTransferRejectCommand + * @see DomainTransferQueryCommand + */ +class DomainTransferResponse : public TransferResponse +{ +public: + DomainTransferResponse(); + + const std::string & getName() const { return name; }; + const XMLGregorianCalendar* getExpiryDate() const { return exDate.get(); }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + static std::string exprReplace (const std::string &expr); + + const std::string & trStatusExpr() const { return DOM_TR_STATUS_EXPR; }; + const std::string & reIDExpr() const { return DOM_REID_EXPR; }; + const std::string & reDateExpr() const { return DOM_REDATE_EXPR; }; + const std::string & acIDExpr() const { return DOM_ACID_EXPR; }; + const std::string & acDateExpr() const { return DOM_ACDATE_EXPR; }; + +private: + static const std::string DOM_NAME_EXPR, + DOM_EXDATE_EXPR, + DOM_TR_STATUS_EXPR, + DOM_REID_EXPR, + DOM_REDATE_EXPR, + DOM_ACID_EXPR, + DOM_ACDATE_EXPR; + std::auto_ptr exDate; + std::string name; +}; + +#endif // __DOMAIN_TRANSFER_RESPONSE_HPP diff --git a/AusRegEPPTK/se/DomainUpdateCommand.cpp b/AusRegEPPTK/se/DomainUpdateCommand.cpp new file mode 100644 index 0000000..cac6480 --- /dev/null +++ b/AusRegEPPTK/se/DomainUpdateCommand.cpp @@ -0,0 +1,39 @@ +#include "se/DomainUpdateCommand.hpp" +#include "se/DomainAdd.hpp" +#include "se/DomainRem.hpp" + +#include "se/StandardObjectType.hpp" +#include "xml/XMLHelper.hpp" + + +DomainUpdateCommand::DomainUpdateCommand (const std::string& name, + const std::string* pw, + const DomainAdd* add, + const DomainRem* rem, + const std::string* registrantID) + : UpdateCommand(StandardObjectType::DOMAIN(), name) +{ + if (add != NULL) + add->appendToElement (xmlWriter, objElement); + + if (rem != NULL) + rem->appendToElement (xmlWriter, objElement); + + if (pw != NULL || registrantID != NULL) + { + DOMElement *chg = xmlWriter->appendChild (objElement, "chg"); + + if (registrantID) + XMLHelper::setTextContent + (xmlWriter->appendChild (chg, "registrant"), + *registrantID); + + if (pw) + XMLHelper::setTextContent + (xmlWriter->appendChild + (xmlWriter->appendChild + (chg, "authInfo"), + "pw"), + *pw); + } +} diff --git a/AusRegEPPTK/se/DomainUpdateCommand.hpp b/AusRegEPPTK/se/DomainUpdateCommand.hpp new file mode 100644 index 0000000..de8957f --- /dev/null +++ b/AusRegEPPTK/se/DomainUpdateCommand.hpp @@ -0,0 +1,30 @@ +#ifndef __DOMAINUPDATECOMMAND_HPP +#define __DOMAINUPDATECOMMAND_HPP + +#include "se/UpdateCommand.hpp" + +class DomainAdd; +class DomainRem; + +/** + * Use this to request the update of a domain object provisioned in an EPP + * Registry. Instances of this class generate RFC3730 and RFC3731 compliant + * domain update EPP command service elements via the toXML method. The + * response expected from a server should be handled by a Response object. + * + * @see Response + */ +class DomainUpdateCommand : public UpdateCommand +{ +public: + /** + * The set of attributes of a domain which may be updated as per + * RFC3731. + */ + DomainUpdateCommand (const std::string& name, + const std::string* pw = NULL, + const DomainAdd* add = NULL, + const DomainRem* rem = NULL, + const std::string* registrantID = NULL); +}; +#endif // __DOMAINUPDATECOMMAND_HPP diff --git a/AusRegEPPTK/se/DomainUpdateCommandTest.cpp b/AusRegEPPTK/se/DomainUpdateCommandTest.cpp new file mode 100644 index 0000000..79eccac --- /dev/null +++ b/AusRegEPPTK/se/DomainUpdateCommandTest.cpp @@ -0,0 +1,122 @@ +#include "se/DomainUpdateCommand.hpp" +#include "se/DomainUpdateSyncCommandExtension.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "se/DomainAdd.hpp" +#include "se/Status.hpp" +#include "se/DomainRem.hpp" +#include "se/IllegalArgException.hpp" +#include "xml/XMLParser.hpp" +#include "common/init.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/ErrorPkg.hpp" + +#include + +using namespace std; + +void testSimpleUpdate() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainUpdateCommand cmd("jtkutest.com.au"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auJTKUTEST.20070101.010101.0"); + +} + +void testFullUpdate() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + const char* addNsText[] = { "ns1.jtkutest.com.au", "ns2.jtkutest.com.au" }; + const vector addNs(addNsText, addNsText + 2); + + const vector addTechContacts(1, "JTKCON"); + const vector addAdminContacts(1, "JTKCON2"); + const vector addBillingContacts(1, "JTKCON3"); + + + vector addStatus; + addStatus.push_back(Status("clientHold", "non-payment")); + + // Could take the address of temporaries here since we 'know' DomainAdd + // only dereferences during construction and does so to deep copy, but + // this is more conventional. + const DomainAdd add( + &addNs, + &addTechContacts, + &addAdminContacts, + &addBillingContacts, + &addStatus); + + + const char* remNsText[] = { "ns3.jtkutest.com.au", "ns4.jtkutest.com.au" }; + const vector remNs(remNsText, remNsText + 2); + + const vector remTechContacts(1, "JTKCON2"); + const vector remAdminContacts(1, "JTKCON"); + + const char* remStatusText[] = { "clientDeleteProhibited" }; + const vector remStatus(remStatusText, remStatusText + 1 ); + + const DomainRem rem( + &remNs, + &remTechContacts, + &remAdminContacts, + NULL, + &remStatus); + + const string name("jtkutest.com.au"); + const string pw("jtkUT3st"); + const string registrantID("JTKCON"); + + DomainUpdateCommand cmd("jtkutest.com.au", &pw, &add, &rem, ®istrantID); + + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "jtkutest.com.auns1.jtkutest.com.auns2.jtkutest.com.auJTKCONJTKCON2JTKCON3non-paymentns3.jtkutest.com.auns4.jtkutest.com.auJTKCON2JTKCONJTKCONjtkUT3stJTKUTEST.20070101.010101.0"); +} + +void testSyncExpiryDateExtension(void) +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainUpdateCommand cmd("jtkutest.com.au"); + XMLGregorianCalendar *newExpiryDate = EPPDateFormatter::fromXSDateTime("2005-04-03T22:00:00.0Z"); + + DomainUpdateSyncCommandExtension extension(newExpiryDate); + cmd.appendExtension(extension); + const string xml(cmd.toXML()); + + delete newExpiryDate; + ASSERT_EQ(xml, + "jtkutest.com.au2005-04-03T22:00:00.0ZJTKUTEST.20070101.010101.0"); +} + +void testSyncExpiryDateExtensionWithNullDate(void) +{ + try + { + DomainUpdateSyncCommandExtension extension(NULL); + FAIL("Null exDate should have generated an exception"); + } + catch (IllegalArgException &e) + { + ASSERT_EQ(e.getMessage(), + ErrorPkg::getMessage("se.domain.update.sync.exDate.missing")); + } +} + +int main(int argc, char* argv[]) +{ + init("etc/toolkit2.conf"); + TEST_run(testSimpleUpdate); + TEST_run(testFullUpdate); + TEST_run(testSyncExpiryDateExtension); + TEST_run(testSyncExpiryDateExtensionWithNullDate); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/DomainUpdateSyncCommandExtension.cpp b/AusRegEPPTK/se/DomainUpdateSyncCommandExtension.cpp new file mode 100644 index 0000000..b539565 --- /dev/null +++ b/AusRegEPPTK/se/DomainUpdateSyncCommandExtension.cpp @@ -0,0 +1,21 @@ +#include "se/DomainUpdateSyncCommandExtension.hpp" +#include "se/Command.hpp" +#include "se/SyncExtension.hpp" +#include "xml/XMLHelper.hpp" + +namespace { + SyncExtension& syncExtension() { + static SyncExtension* syncExtension = new SyncExtension(); + return *syncExtension; + } +}; // anonymous namespace + +void DomainUpdateSyncCommandExtension::addToCommand(const Command &command) const +{ + XMLWriter* xmlWriter = command.getXmlWriter(); + DOMElement* extensionElement = command.getExtensionElement(); + DOMElement* updateElement = xmlWriter->appendChild(extensionElement, + "update", syncExtension().getURI()); + DOMElement* exDateElement = xmlWriter->appendChild(updateElement, "exDate"); + XMLHelper::setTextContent(exDateElement, syncExpiryDate); +} diff --git a/AusRegEPPTK/se/DomainUpdateSyncCommandExtension.hpp b/AusRegEPPTK/se/DomainUpdateSyncCommandExtension.hpp new file mode 100644 index 0000000..84d839d --- /dev/null +++ b/AusRegEPPTK/se/DomainUpdateSyncCommandExtension.hpp @@ -0,0 +1,39 @@ +#ifndef __DOMAIN_UPDATE_COMMAND_EXTENSION_HPP +#define __DOMAIN_UPDATE_COMMAND_EXTENSION_HPP + +#include + +#include "common/ErrorPkg.hpp" +#include "se/Command.hpp" +#include "se/CommandExtension.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/EPPDateFormatter.hpp" +#include "se/IllegalArgException.hpp" + +/** + * This class models the element as documented in 'Domain Expiry + * Synchronisation Mapping for the Extensible Provisioning Protocol'. + */ +class DomainUpdateSyncCommandExtension : public CommandExtension +{ + public: + DomainUpdateSyncCommandExtension(const XMLGregorianCalendar *exDate); + virtual void addToCommand(const Command &command) const; + private: + std::string syncExpiryDate; + +}; + +inline DomainUpdateSyncCommandExtension::DomainUpdateSyncCommandExtension( + const XMLGregorianCalendar *exDate) +{ + if (exDate == NULL) + { + throw IllegalArgException( + ErrorPkg::getMessage("se.domain.update.sync.exDate.missing")); + } + + syncExpiryDate = EPPDateFormatter::toXSDateTime(*exDate); +} + +#endif // __DOMAIN_UPDATE_COMMAND_EXTENSION_HPP diff --git a/AusRegEPPTK/se/E164Extension.cpp b/AusRegEPPTK/se/E164Extension.cpp new file mode 100644 index 0000000..dd1f2c6 --- /dev/null +++ b/AusRegEPPTK/se/E164Extension.cpp @@ -0,0 +1,15 @@ +#include "se/E164Extension.hpp" + +std::string& E164Extension::getURI() const +{ + static std::string uri = "urn:ietf:params:xml:ns:e164epp-1.0"; + return uri; +} + +std::string& E164Extension::getSchemaLocation() const +{ + static std::string schemaLocation = + "urn:ietf:params:xml:ns:e164epp-1.0 e164epp-1.0.xsd"; + return schemaLocation; +} + diff --git a/AusRegEPPTK/se/E164Extension.hpp b/AusRegEPPTK/se/E164Extension.hpp new file mode 100644 index 0000000..3ad8ec1 --- /dev/null +++ b/AusRegEPPTK/se/E164Extension.hpp @@ -0,0 +1,26 @@ +#ifndef __E164EXTENSION_HPP +#define __E164EXTENSION_HPP + +#include "se/Extension.hpp" + +/** + * A bundled set of constants representing the E164 EPP extension + * schema (ENUM). The namespace URI uniquely identifies the extension. + */ +class E164Extension : public Extension +{ +public: + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __E164EXTENSION_HPP + diff --git a/AusRegEPPTK/se/EPPDateFormatter.cpp b/AusRegEPPTK/se/EPPDateFormatter.cpp new file mode 100644 index 0000000..f897272 --- /dev/null +++ b/AusRegEPPTK/se/EPPDateFormatter.cpp @@ -0,0 +1,25 @@ +#include "se/EPPDateFormatter.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include + +std::string EPPDateFormatter::toXSDateTime(const XMLGregorianCalendar& date) +{ + return date.toXMLFormat(); +} + +std::string EPPDateFormatter::toXSDate(const XMLGregorianCalendar& date) +{ + return date.format("%Y-%M-%D"); +} + +XMLGregorianCalendar* EPPDateFormatter::fromXSDateTime(const std::string &dateTime) +{ + try + { + return new XMLGregorianCalendar(dateTime); + } + catch (MalformedDateException& e) + { + return NULL; + } +} diff --git a/AusRegEPPTK/se/EPPDateFormatter.hpp b/AusRegEPPTK/se/EPPDateFormatter.hpp new file mode 100644 index 0000000..fc797bd --- /dev/null +++ b/AusRegEPPTK/se/EPPDateFormatter.hpp @@ -0,0 +1,16 @@ +#ifndef __EPPDATEFORMATTER_HPP +#define __EPPDATEFORMATTER_HPP + +#include +#include +#include "se/XMLGregorianCalendar.hpp" + +class EPPDateFormatter +{ +public: + static std::string toXSDateTime(const XMLGregorianCalendar& date); + static std::string toXSDate(const XMLGregorianCalendar& date); + static XMLGregorianCalendar* fromXSDateTime(const std::string& dateStr); +}; + +#endif // __EPPDATEFORMATTER_HPP diff --git a/AusRegEPPTK/se/EPPDateFormatterTest.cpp b/AusRegEPPTK/se/EPPDateFormatterTest.cpp new file mode 100644 index 0000000..e5e1619 --- /dev/null +++ b/AusRegEPPTK/se/EPPDateFormatterTest.cpp @@ -0,0 +1,22 @@ +#include "se/EPPDateFormatter.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include +#include +#include + +#include "common/Test.hpp" + +void doWork() +{ + const std::string dateStr = "2008-02-11T01:02:03.3Z"; + XMLGregorianCalendar* dt = EPPDateFormatter::fromXSDateTime(dateStr); + std::string res; + if (dt) res = EPPDateFormatter::toXSDateTime(*dt); + ASSERT_EQ(res, "2008-02-11T01:02:03.0Z"); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/EnumDomainCreateCommand.cpp b/AusRegEPPTK/se/EnumDomainCreateCommand.cpp new file mode 100644 index 0000000..b232bea --- /dev/null +++ b/AusRegEPPTK/se/EnumDomainCreateCommand.cpp @@ -0,0 +1,82 @@ +#include "se/EnumDomainCreateCommand.hpp" +#include "se/E164Extension.hpp" + +namespace { + Extension& e164Extension() { + static Extension* extension = new E164Extension(); + return *extension; + } +}; // anonymous namespace + +EnumDomainCreateCommand::EnumDomainCreateCommand ( + const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts) : DomainCreateCommand ( + name, pw, registrantID, &techContacts) +{ } + + +EnumDomainCreateCommand::EnumDomainCreateCommand ( + const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts, + const std::vector *naptrs) : DomainCreateCommand ( + name, pw, registrantID, &techContacts) +{ + setExtension (naptrs); +} + +EnumDomainCreateCommand::EnumDomainCreateCommand ( + const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts, + const std::vector &adminContacts, + const std::vector &billingContacts, + const std::vector *naptrs, + const Period &period) : DomainCreateCommand ( + name, pw, registrantID, &techContacts, + &adminContacts, &billingContacts, + NULL, &period) +{ + setExtension (naptrs); +} + +EnumDomainCreateCommand::EnumDomainCreateCommand ( + const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts, + const std::vector &adminContacts, + const std::vector &billingContacts, + const std::vector &nameservers, + const Period &period) : DomainCreateCommand ( + name, pw, registrantID, &techContacts, + &adminContacts, &billingContacts, &nameservers, + &period) +{ +} + +void EnumDomainCreateCommand::setExtension (const std::vector *naptrs) +{ + if (naptrs == NULL || naptrs->size() == 0) + return; + + DOMElement *e164Create = xmlWriter->appendChild( + xmlWriter->appendChild( + command, + "extension"), + "create", + e164Extension().getURI()); + + std::vector::const_iterator p = naptrs->begin(); + + while (p != naptrs->end()) + { + p->appendToElement (xmlWriter, e164Create); + p++; + } +} + diff --git a/AusRegEPPTK/se/EnumDomainCreateCommand.hpp b/AusRegEPPTK/se/EnumDomainCreateCommand.hpp new file mode 100644 index 0000000..5fabd10 --- /dev/null +++ b/AusRegEPPTK/se/EnumDomainCreateCommand.hpp @@ -0,0 +1,70 @@ +#ifndef __ENUMDOMAINCREATECOMMAND_HPP +#define __ENUMDOMAINCREATECOMMAND_HPP + +#include "se/DomainCreateCommand.hpp" +#include "se/NAPTR.hpp" +#include "se/Period.hpp" + +#include +#include + +/** + * Use this to request provisioning of an ENUM domain object in an EPP + * Registry. Instances of this class generate domain create EPP service + * elements compliant with RFCs 3730, 3731 and 4114 via the toXML method. + */ +class EnumDomainCreateCommand : public DomainCreateCommand +{ +public: + /** + * Minimal constructor for creating a domain:create + e164epp:create + * EPP command. These parameters are the least required for a valid + * ENUM domain create command. + */ + EnumDomainCreateCommand (const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts); + /** + * Construct a domain:create + e164epp:create EPP command with NAPTR + * records. This is the least information required to provision an ENUM + * domain with NAPTR records. + */ + EnumDomainCreateCommand (const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts, + const std::vector *naptrs); + /** + * Full data specification constructor for a domain:create + e164epp:create + * EPP command with NAPTR records. Please refer to the + * urn:ietf:params:xml:ns:e164epp-1.0 schema for specification of the + * required fields. + */ + EnumDomainCreateCommand (const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts, + const std::vector &adminContacts, + const std::vector &billingContacts, + const std::vector *naptrs, + const Period &period); + /** + * Full data specification constructor for a domain:create + e164epp:create + * EPP command with nameservers rather than NAPTR records. This + * constructor does not cause the e164epp extension element to be created, + * since NAPTR records are not specified. + */ + EnumDomainCreateCommand (const std::string &name, + const std::string &pw, + const std::string *registrantID, + const std::vector &techContacts, + const std::vector &adminContacts, + const std::vector &billingContacts, + const std::vector &nameservers, + const Period &period); +private: + void setExtension (const std::vector * naptrs); +}; + +#endif // __ENUMDOMAINCREATECOMMAND_HPP diff --git a/AusRegEPPTK/se/EnumDomainInfoResponse.cpp b/AusRegEPPTK/se/EnumDomainInfoResponse.cpp new file mode 100644 index 0000000..eacdb27 --- /dev/null +++ b/AusRegEPPTK/se/EnumDomainInfoResponse.cpp @@ -0,0 +1,86 @@ +#include "se/EnumDomainInfoResponse.hpp" + +const std::string EnumDomainInfoResponse::E164_INF_DATA_EXPR + ("/e:epp/e:response/e:extension/e164epp:infData"); + +const std::string EnumDomainInfoResponse::NAPTR_COUNT_EXPR + ("count(" + + EnumDomainInfoResponse::E164_INF_DATA_EXPR + + "/e164epp:naptr)"); + +const std::string EnumDomainInfoResponse::NAPTR_IND_EXPR + (EnumDomainInfoResponse::exprReplace + (EnumDomainInfoResponse::E164_INF_DATA_EXPR) + + "/e164epp:naptr[IDX]"); + +const std::string EnumDomainInfoResponse::NAPTR_ORDER_EXPR + ("/e164epp:order/text()"); + +const std::string EnumDomainInfoResponse::NAPTR_PREF_EXPR + ("/e164epp:pref/text()"); + +const std::string EnumDomainInfoResponse::NAPTR_FLAGS_EXPR + ("/e164epp:flags/text()"); + +const std::string EnumDomainInfoResponse::NAPTR_SVC_EXPR + ("/e164epp:svc/text()"); + +const std::string EnumDomainInfoResponse::NAPTR_REGEX_EXPR + ("/e164epp:regex/text()"); + +const std::string EnumDomainInfoResponse::NAPTR_REPL_EXPR + ("/e164epp:repl/text()"); + + +EnumDomainInfoResponse::EnumDomainInfoResponse() + : DomainInfoResponse() +{ +} + +void EnumDomainInfoResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + DomainInfoResponse::fromXML (xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + int naptrCount = xmlDoc->getNodeCount (NAPTR_COUNT_EXPR); + naptrs.clear(); + + for (int i = 0; i < naptrCount; i++) + { + std::string qry = ReceiveSE::replaceIndex(NAPTR_IND_EXPR, i+1); + + std::string order = xmlDoc->getNodeValue (qry + NAPTR_ORDER_EXPR); + std::string pref = xmlDoc->getNodeValue (qry + NAPTR_PREF_EXPR); + std::string flags = xmlDoc->getNodeValue (qry + NAPTR_FLAGS_EXPR); + std::string svc = xmlDoc->getNodeValue (qry + NAPTR_SVC_EXPR); + std::string regex = xmlDoc->getNodeValue (qry + NAPTR_REGEX_EXPR); + std::string repl = xmlDoc->getNodeValue (qry + NAPTR_REPL_EXPR); + + naptrs.push_back (NAPTR (atoi(order.c_str()), + atoi(pref.c_str()), + flags.c_str(), + svc, + regex, + repl)); + } + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + +std::string EnumDomainInfoResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + DataResponse::OBJ(), + "e164epp"); +} diff --git a/AusRegEPPTK/se/EnumDomainInfoResponse.hpp b/AusRegEPPTK/se/EnumDomainInfoResponse.hpp new file mode 100644 index 0000000..847a79d --- /dev/null +++ b/AusRegEPPTK/se/EnumDomainInfoResponse.hpp @@ -0,0 +1,32 @@ +#ifndef __ENUM_DOMAIN_INFO_RESPONSE_HPP +#define __ENUM_DOMAIN_INFO_RESPONSE_HPP + +#include "se/DomainInfoResponse.hpp" +#include "se/NAPTR.hpp" + +class EnumDomainInfoResponse : public DomainInfoResponse +{ +public: + EnumDomainInfoResponse(); + + const std::vector & getNAPTRs() const { return naptrs; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + static std::string exprReplace (const std::string &expr); + +private: + static const std::string E164_INF_DATA_EXPR, + NAPTR_COUNT_EXPR, + NAPTR_IND_EXPR, + NAPTR_ORDER_EXPR, + NAPTR_PREF_EXPR, + NAPTR_FLAGS_EXPR, + NAPTR_SVC_EXPR, + NAPTR_REGEX_EXPR, + NAPTR_REPL_EXPR; + std::vector naptrs; +}; + +#endif // __ENUM_DOMAIN_INFO_RESPONSE_HPP diff --git a/AusRegEPPTK/se/EnumDomainInfoResponseTest.cpp b/AusRegEPPTK/se/EnumDomainInfoResponseTest.cpp new file mode 100644 index 0000000..9d3c6c5 --- /dev/null +++ b/AusRegEPPTK/se/EnumDomainInfoResponseTest.cpp @@ -0,0 +1,95 @@ +#include "se/ContactCheckResponse.hpp" +#include "se/EnumDomainInfoResponse.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" +#include "se/EPPDateFormatter.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + const string xml = + "Command completed successfully3.8.0.0.6.9.2.3.6.1.4.4.e164.arpaEXAMPLE1-REPjd1234sh8013sh8013ns1.example.comns2.example.comns1.example.comns2.example.comClientXClientY1999-04-03T22:00:00.0ZClientX1999-12-03T09:00:00.0Z2005-04-03T22:00:00.0Z2000-04-08T09:00:00.0Z2fooBAR10100uE2U+sip\"!^.*$!sip:info@example.com!\"10102uE2U+msg\"!^.*$!mailto:info@example.com!\"ABC-1234554322-XYZ"; + + EnumDomainInfoResponse response; + XMLParser parser; + auto_ptr doc(parser.parse(xml)); + try + { + response.fromXML(doc.get()); + } + catch (ParsingException& pe) + { + cerr << pe.getMessage() << endl; + exit(1); + } + + { + vector naptrs(response.getNAPTRs()); + ASSERT_EQ(2, naptrs.size()); + if (naptrs.size() != 2) exit(1); + ASSERT_EQ(10, naptrs[0].getOrder()); + ASSERT_EQ(100, naptrs[0].getPreference()); + ASSERT_EQ("u", naptrs[0].getFlags()); + ASSERT_EQ("E2U+sip", naptrs[0].getService()); + ASSERT_EQ("\"!^.*$!sip:info@example.com!\"", naptrs[0].getRegex()); + ASSERT_EQ("", naptrs[0].getReplacement()); + ASSERT_EQ(10, naptrs[1].getOrder()); + ASSERT_EQ(102, naptrs[1].getPreference()); + ASSERT_EQ("u", naptrs[1].getFlags()); + ASSERT_EQ("E2U+msg", naptrs[1].getService()); + ASSERT_EQ("\"!^.*$!mailto:info@example.com!\"", naptrs[1].getRegex()); + ASSERT_EQ("", naptrs[1].getReplacement()); + } + + { + vector statuses = response.getStatuses(); + ASSERT_EQ(statuses.size(), 1); + ASSERT_EQ(statuses[0].toString(), statuses[0].toString()); + ASSERT_EQ("3.8.0.0.6.9.2.3.6.1.4.4.e164.arpa", response.getName()); + ASSERT_EQ("2fooBAR", response.getPW()); + ASSERT_EQ("jd1234", response.getRegistrantID()); + + vector contacts(response.getTechContacts()); + ASSERT_EQ(1, contacts.size()); + ASSERT_EQ("sh8013", contacts[0]); + + vector contacts2(response.getAdminContacts()); + ASSERT_EQ(1, contacts2.size()); + ASSERT_EQ("sh8013", contacts2[0]); + + const vector& contacts3(response.getBillingContacts()); + ASSERT_EQ(contacts3.size(), 0); + + vector ns(response.getNameservers()); + ASSERT_EQ(2, ns.size()); + ASSERT_EQ("ns1.example.com", ns[0]); + ASSERT_EQ("ns2.example.com", ns[1]); + + ASSERT_EQ(2, response.getSubordinateHosts().size()); + ASSERT_EQ("ns1.example.com", response.getSubordinateHosts()[0]); + ASSERT_EQ("ns2.example.com", response.getSubordinateHosts()[1]); + + ASSERT_EQ("EXAMPLE1-REP", response.getROID()); +#if 0 + ASSERT_EQ( + EPPDateFormatter.fromXSDateTime("1999-04-03T22:00:00.0Z"), + response.getCreateDate()); + ASSERT_EQ( + EPPDateFormatter.fromXSDateTime("1999-12-03T09:00:00.0Z"), + response.getUpdateDate()); +#endif + ASSERT_EQ("ClientY", response.getCreateClient()); + ASSERT_EQ("ClientX", response.getUpdateClient()); + ASSERT_EQ("ClientX", response.getSponsorClient()); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/EnumDomainUpdateCommand.cpp b/AusRegEPPTK/se/EnumDomainUpdateCommand.cpp new file mode 100644 index 0000000..5046a94 --- /dev/null +++ b/AusRegEPPTK/se/EnumDomainUpdateCommand.cpp @@ -0,0 +1,60 @@ +#include "se/EnumDomainUpdateCommand.hpp" +#include "se/E164Extension.hpp" + +namespace { + Extension& e164Extension() { + static Extension* extension = new E164Extension(); + return *extension; + } +}; // anonymous namespace + +EnumDomainUpdateCommand::EnumDomainUpdateCommand ( + const std::string &name, + const std::vector &addNaptrs, + const std::vector &remNaptrs) : DomainUpdateCommand (name) +{ + setExtension (addNaptrs, remNaptrs); +} + +EnumDomainUpdateCommand::EnumDomainUpdateCommand ( + const std::string &name, + const std::string &pw, + const DomainAdd *add, + const DomainRem *rem, + const std::string ®istrantID, + const std::vector &addNaptrs, + const std::vector &remNaptrs) : DomainUpdateCommand ( + name, &pw, add, rem, ®istrantID) +{ + setExtension (addNaptrs, remNaptrs); +} + +void EnumDomainUpdateCommand::setExtension ( + const std::vector &addNaptrs, + const std::vector &remNaptrs) +{ + if (addNaptrs.size() == 0 && remNaptrs.size() == 0) + return; + + DOMElement * e164Update = xmlWriter->appendChild( + xmlWriter->appendChild( + command, + "extension"), + "update", + e164Extension().getURI()); + + if (addNaptrs.size() > 0) + { + DOMElement *e164Add = xmlWriter->appendChild (e164Update, "add"); + for (unsigned int i = 0; i < addNaptrs.size(); i++) + addNaptrs[i].appendToElement (xmlWriter, e164Add); + } + + if (remNaptrs.size() > 0) + { + DOMElement *e164Add = xmlWriter->appendChild (e164Update, "rem"); + for (unsigned int i = 0; i < remNaptrs.size(); i++) + remNaptrs[i].appendToElement (xmlWriter, e164Add); + } +} + diff --git a/AusRegEPPTK/se/EnumDomainUpdateCommand.hpp b/AusRegEPPTK/se/EnumDomainUpdateCommand.hpp new file mode 100644 index 0000000..ab081c7 --- /dev/null +++ b/AusRegEPPTK/se/EnumDomainUpdateCommand.hpp @@ -0,0 +1,49 @@ +#ifndef __ENUMDOMAINUPDATECOMMAND_HPP +#define __ENUMDOMAINUPDATECOMMAND_HPP + +#include "se/DomainUpdateCommand.hpp" +#include "se/NAPTR.hpp" +#include "se/DomainAdd.hpp" +#include "se/DomainRem.hpp" + +/** + * Use this to request the update of an ENUM domain object provisioned in an + * EPP Registry. Instances of this class generate RFC 3730, 3731 and 4114- + * compliant ENUM domain update EPP command service elements via the toXML + * method. The response expected from a server should be handled by a Response + * object. + * + * @see Response + */ +class EnumDomainUpdateCommand : public DomainUpdateCommand +{ +public: + /** + * Minimal constructor for an ENUM domain update command. No domain add, + * rem or chg elements are generated by instances constructed this way. + * + * @param addNaptrs a set of NAPTR records to be associated with this + * domain which are not already associated with the domain. + * + * @param remNaptrs a set of NAPTR records currently associated with this + * domain to be removed. + */ + EnumDomainUpdateCommand (const std::string &name, + const std::vector &addNaptrs, + const std::vector &remNaptrs); + /** + * Verbose constructor for an ENUM domain update command, supporting the + * modification of every atttribute of an ENUM domain. + */ + EnumDomainUpdateCommand (const std::string &name, + const std::string &pw, + const DomainAdd *add, + const DomainRem *rem, + const std::string ®istrantID, + const std::vector &addNaptrs, + const std::vector &remNaptrs); +private: + void setExtension (const std::vector &addNaptrs, + const std::vector &remNapts); +}; +#endif // __ENUMDOMAINUPDATECOMMAND_HPP diff --git a/AusRegEPPTK/se/EnumType.cpp b/AusRegEPPTK/se/EnumType.cpp new file mode 100644 index 0000000..b48de6a --- /dev/null +++ b/AusRegEPPTK/se/EnumType.cpp @@ -0,0 +1,30 @@ +#include "se/EnumType.hpp" +#include "common/ErrorPkg.hpp" + + +EnumType::EnumType(std::vector &values, + const std::string &first, + const std::string &second /* = "" */, + const std::string &third /* = "" */, + const std::string &fourth /* = "" */) + : first(first), second(second), third(third), fourth(fourth) +{ + values.push_back (this); +} + +const EnumType* EnumType::value(const std::string &name, + std::vector &values) + throw (IllegalArgException) +{ + for (unsigned int i = 0; i < values.size(); i++) + { + if (values[i]->toString() == name) + { + return values[i]; + } + } + throw IllegalArgException( + ErrorPkg::getMessage( + "common.exception.illegal.arg.enum", "<>", name)); + +} diff --git a/AusRegEPPTK/se/EnumType.hpp b/AusRegEPPTK/se/EnumType.hpp new file mode 100644 index 0000000..705e056 --- /dev/null +++ b/AusRegEPPTK/se/EnumType.hpp @@ -0,0 +1,47 @@ +#ifndef __ENUMTYPE_HPP +#define __ENUMTYPE_HPP + +#include "se/IllegalArgException.hpp" +#include +#include + +/// An enumeration of unique name to values mappings. Decendants are expected +// to vector (per the first argument of EnumType's ctr) that prepresents the +// pool of possible values. Decendents are then expected to create well-known +// static instances of themseleves that pass their address to this base class. +// +// Note: Decendant classes will need to ensure their well-known static instances +// are initialised before any other class attempts to use them. +// +class EnumType +{ +public: + /// @TODO SWIG/Perl workaround - figure out why SWIG wants an empty constructor. + EnumType() {} + + EnumType(std::vector& values, + const std::string& first, + const std::string& second = "", + const std::string& third = "", + const std::string& fourth = ""); + + virtual ~EnumType() { } + + virtual std::string toString() const { return first; }; + + static const EnumType* value( + const std::string& name, + std::vector& values) + throw (IllegalArgException); + +protected: + const std::string& getFirst() const { return first; }; + const std::string& getSecond() const { return second; }; + const std::string& getThird() const { return third; }; + const std::string& getFourth() const { return fourth; }; + +private: + std::string first, second, third, fourth; +}; + +#endif // __ENUMTYPE_HPP diff --git a/AusRegEPPTK/se/Error.hpp b/AusRegEPPTK/se/Error.hpp new file mode 100644 index 0000000..4d91e3d --- /dev/null +++ b/AusRegEPPTK/se/Error.hpp @@ -0,0 +1,17 @@ +#ifndef __ERROR_HPP +#define __ERROR_HPP + +#include + +class Error +{ +public: + Error (std::string const& msg) : myText(msg) {}; + + virtual const std::string & getMessage() const { return myText; }; + +private: + std::string myText; +}; + +#endif // __ERROR_HPP diff --git a/AusRegEPPTK/se/Extension.hpp b/AusRegEPPTK/se/Extension.hpp new file mode 100644 index 0000000..2201adb --- /dev/null +++ b/AusRegEPPTK/se/Extension.hpp @@ -0,0 +1,37 @@ +#ifndef __EXTENSION_H +#define __EXTENSION_H + +#include + +/** + * Represent features of EPP extensions of interest to the + * toolkit library. This is implemented as an abstract class + * instead of interface because an interface can't declare + * static (class) methods. + */ +class Extension +{ +public: +#ifndef SWIG + virtual ~Extension(void) = 0; + + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const = 0; + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const = 0; +#endif /* SWIG */ +}; + +#ifndef SWIG +inline Extension::~Extension(void) +{ + return; +} +#endif /* SWIG */ + +#endif // __EXTENSION_H diff --git a/AusRegEPPTK/se/Greeting.cpp b/AusRegEPPTK/se/Greeting.cpp new file mode 100644 index 0000000..d043112 --- /dev/null +++ b/AusRegEPPTK/se/Greeting.cpp @@ -0,0 +1,87 @@ +#include "se/Greeting.hpp" +#include "se/EPPDateFormatter.hpp" +#include "xml/ParsingException.hpp" + +const std::string Greeting::GREETING_EXPR ("/e:epp/e:greeting"); +const std::string Greeting::DCP_EXPR (GREETING_EXPR + "/e:dcp"); +const std::string Greeting::SVID_EXPR(GREETING_EXPR + "/e:svID/text()"); +const std::string Greeting::SVDATE_EXPR(GREETING_EXPR + "/e:svDate/text()"); +const std::string Greeting::VERSIONS_EXPR (GREETING_EXPR + "/e:svcMenu/e:version"); +const std::string Greeting::LANGS_EXPR (GREETING_EXPR + "/e:svcMenu/e:lang"); +const std::string Greeting::OBJ_URIS_EXPR (GREETING_EXPR + "/e:svcMenu/e:objURI"); +const std::string Greeting::EXT_URIS_EXPR (GREETING_EXPR + "/e:svcMenu/e:svcExtension/e:extURI"); +const std::string Greeting::ACCESS_EXPR (DCP_EXPR + "/e:access/*[1]"); +const std::string Greeting::STMT_COUNT_EXPR ("count(" + DCP_EXPR + "/e:statement)"); +const std::string Greeting::STMT_IND_EXPR (DCP_EXPR + "/e:statement[IDX]"); +const std::string Greeting::PURPOSE_EXPR ("/e:purpose"); +const std::string Greeting::RECIPIENT_EXPR ("/e:recipient"); +const std::string Greeting::RETENTION_EXPR ("/e:retention/*[1]"); +const std::string Greeting::EXPIRY_EXPR ("/e:expiry/*[1]"); + + +std::string Greeting::toString() const +{ + unsigned int i; + std::string versionString = versions[0]; + + for (i = 1; i < versions.size(); i++) + versionString += "," + versions[i]; + + std::string langString = langs[0]; + for (i = 1; i < langs.size(); i++) + langString += "," + langs[i]; + + std::string objURIString = objURIs[0]; + for (i = 1; i < objURIs.size(); i++) + objURIString += "," + objURIs[i]; + + std::string retval = + "(svID = " + getServerID() + ")" + + (getServerDateTime() != NULL ? "(svDate = " + getServerDateTime()->toXMLFormat() + ")" : "") + + "(versions = (" + versionString + "))" + + "(languages = (" + langString + "))" + + "(objURIs = (" + objURIString + "))"; + + return retval; +} + + +void Greeting::fromXML(XMLDocument *xmlDoc) throw (ParsingException) +{ + debugLogger->LOG_FINEST("enter"); + + try + { + // debugLogger->info (xmlDoc->toString()); + svID = xmlDoc->getNodeValue (SVID_EXPR); + std::string svDateText = xmlDoc->getNodeValue (SVDATE_EXPR); + svDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(svDateText)); + versions = xmlDoc->getNodeValues(VERSIONS_EXPR); + langs = xmlDoc->getNodeValues(LANGS_EXPR); + objURIs = xmlDoc->getNodeValues(OBJ_URIS_EXPR); + extURIs = xmlDoc->getNodeValues(EXT_URIS_EXPR); + dcpAccess = xmlDoc->getNodeValue(ACCESS_EXPR); + + int dcpStmtCount = xmlDoc->getNodeCount(STMT_COUNT_EXPR); + for (int i = 0; i < dcpStmtCount; i++) + { + std::string qry = ReceiveSE::replaceIndex(STMT_IND_EXPR, i+1); + + dcpStatements.push_back( + DCPStatement( + xmlDoc->getChildNames(qry + PURPOSE_EXPR), + xmlDoc->getChildNames(qry + RECIPIENT_EXPR), + xmlDoc->getNodeName(qry + RETENTION_EXPR))); + } + } + catch (XPathExpressionException& e) + { + ParsingException pe; + pe.causedBy(e); + throw pe; + } + + debugLogger->info (toString()); + debugLogger->LOG_FINEST("exit"); +} + diff --git a/AusRegEPPTK/se/Greeting.hpp b/AusRegEPPTK/se/Greeting.hpp new file mode 100644 index 0000000..4d64e8d --- /dev/null +++ b/AusRegEPPTK/se/Greeting.hpp @@ -0,0 +1,87 @@ +#ifndef __GREETING_HPP +#define __GREETING_HPP + +#include "se/ReceiveSE.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "xml/ParsingException.hpp" + +/** + * Provides access to the data collection policy statement parameter values + * reported by an EPP server in a Greeting compliant with the greeting + * specification in RFC3730. + */ +class DCPStatement +{ +public: + /// @TODO SWIG/Perl workaround - figure out why SWIG wants an empty constructor. + DCPStatement () {} + + DCPStatement (const std::vector& purposes, + const std::vector& recipients, + const std::string &retentionPolicy) + : purposes(purposes), + recipients(recipients), + retention(retentionPolicy) + { } + + const std::vector & getPurpose() const + { return purposes; }; + const std::vector & getRecipients() const + { return recipients; }; + + const std::string & getRetentionPolicy() const { return retention; }; + std::vector purposes, recipients; + std::string retention; +}; + + +/** + * Provides access to EPP server parameters as published in an EPP greeting + * service element. + * + */ +class Greeting : public ReceiveSE +{ +public: + Greeting() : ReceiveSE(){}; + + const std::string & getServerID() const { return svID; }; + const XMLGregorianCalendar* getServerDateTime() const { return svDate.get(); }; + const std::vector& getProtocolVersions() const { return versions; }; + const std::vector& getLanguages() const { return langs; }; + const std::vector& getObjURIs() const { return objURIs; }; + const std::vector& getExtURIs() const { return extURIs; }; + const std::string& getDcpAccess() const { return dcpAccess; }; + const std::vector& getDataCollectionPolicyStatements() + const { return dcpStatements; }; + + std::string toString() const; + + virtual void fromXML(XMLDocument *xmlDoc) throw (ParsingException); + +private: + std::string svID; + std::auto_ptr svDate; + std::vector versions, langs, objURIs, extURIs; + std::string dcpAccess; + std::vector dcpStatements; + + static const std::string GREETING_EXPR; + static const std::string DCP_EXPR; + static const std::string SVID_EXPR; + static const std::string SVDATE_EXPR; + static const std::string VERSIONS_EXPR; + static const std::string LANGS_EXPR; + static const std::string OBJ_URIS_EXPR; + static const std::string EXT_URIS_EXPR; + static const std::string ACCESS_EXPR; + static const std::string STMT_COUNT_EXPR; + static const std::string STMT_IND_EXPR; + static const std::string PURPOSE_EXPR; + static const std::string RECIPIENT_EXPR; + static const std::string RETENTION_EXPR; + static const std::string EXPIRY_EXPR; +}; + +#endif // __GREETING_HPP diff --git a/AusRegEPPTK/se/GreetingError.hpp b/AusRegEPPTK/se/GreetingError.hpp new file mode 100644 index 0000000..3bece8e --- /dev/null +++ b/AusRegEPPTK/se/GreetingError.hpp @@ -0,0 +1,10 @@ +#ifndef __GREETINGERROR_HPP +#define __GREETINGERROR_HPP + +class GreetingError : public Error +{ +public: + GreetingError (const std::string & msg) : Error(msg) {}; +}; + +#endif // __GREETINGERROR_HPP diff --git a/AusRegEPPTK/se/Hello.hpp b/AusRegEPPTK/se/Hello.hpp new file mode 100644 index 0000000..34a392d --- /dev/null +++ b/AusRegEPPTK/se/Hello.hpp @@ -0,0 +1,25 @@ +#ifndef __HELLO_HPP +#define __HELLO_HPP + +#include "se/SendSE.hpp" + +/** + * Use this to request service information in the form of an EPP greeting + * from an EPP server. Instances of this class generate via the toXML method + * hello service elements compliant with the specification of hello in RFC3730. + */ +class Hello : public SendSE +{ +public: + Hello() + { + xmlWriter->appendChild (xmlWriter->getRoot(), "hello"); + } +protected: + std::string toXMLImpl() + { + return xmlWriter->toXML(); + } +}; + +#endif // __HELLO_HPP diff --git a/AusRegEPPTK/se/HelloTest.cpp b/AusRegEPPTK/se/HelloTest.cpp new file mode 100644 index 0000000..dc98552 --- /dev/null +++ b/AusRegEPPTK/se/HelloTest.cpp @@ -0,0 +1,24 @@ +#include "se/Hello.hpp" +#include "se/CLTRID.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + CLTRID::setClID("JTKUTEST"); + + Hello cmd; + const string xml(cmd.toXML()); + ASSERT_EQ(xml, ""); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/HostAddRem.cpp b/AusRegEPPTK/se/HostAddRem.cpp new file mode 100644 index 0000000..f0024de --- /dev/null +++ b/AusRegEPPTK/se/HostAddRem.cpp @@ -0,0 +1,26 @@ +#include "se/HostAddRem.hpp" +#include "xml/XMLWriter.hpp" + +using namespace std; + +HostAddRem::HostAddRem (const vector& addresses, + const vector& statuses) + : addresses(addresses), statuses(statuses) +{ } + +DOMElement* HostAddRem::appendToElement(XMLWriter *xmlWriter, + DOMElement *parent) const +{ + vector::const_iterator inaddr; + + for (inaddr = addresses.begin(); inaddr != addresses.end(); inaddr++) + inaddr->appendToElement(xmlWriter, parent); + + vector::const_iterator status; + + for (status = statuses.begin(); status != statuses.end(); status++) + xmlWriter->appendChild( + parent, "status", status->getRationale(), "s", status->toString()); + + return parent; +} diff --git a/AusRegEPPTK/se/HostAddRem.hpp b/AusRegEPPTK/se/HostAddRem.hpp new file mode 100644 index 0000000..d387052 --- /dev/null +++ b/AusRegEPPTK/se/HostAddRem.hpp @@ -0,0 +1,34 @@ +#ifndef __HOST_ADD_REM_HPP +#define __HOST_ADD_REM_HPP + +#include "se/InetAddress.hpp" +#include "se/Status.hpp" + +#include +#include + +class XMLWriter; + +/** + * Use this to specify attributes to add to or remove from a host object via a + * host update EPP service element, implemented in HostUpdateCommand. This + * class implements writing the add and rem elements to a host update command. + */ +class HostAddRem +{ +public: + /** + * Each of the parameters is optional, but at least one must be specified. + */ + HostAddRem (const std::vector &addresses, + const std::vector &statuses); + + xercesc::DOMElement* appendToElement( + XMLWriter *xmlWriter, xercesc::DOMElement *parent) const; + +private: + std::vector addresses; + std::vector statuses; +}; + +#endif // __HOST_ADD_REM_HPP diff --git a/AusRegEPPTK/se/HostCheckCommand.hpp b/AusRegEPPTK/se/HostCheckCommand.hpp new file mode 100644 index 0000000..02333f9 --- /dev/null +++ b/AusRegEPPTK/se/HostCheckCommand.hpp @@ -0,0 +1,34 @@ +#ifndef __HOST_CHECK_COMMAND_HPP +#define __HOST_CHECK_COMMAND_HPP + +#include "se/CheckCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * A HostCheckCommand is used to check the availability of host objects + * in a Registry. Instances of this class generate RFC3730 and RFC3732 + * compliant host check EPP command service elements via the toXML method. + * + * @see HostCheckResponse + */ +class HostCheckCommand : public CheckCommand +{ +public: + /** + * Check the availability of the single identified host. + * + * @param name The name of the host to check the availability of. + */ + HostCheckCommand (const std::string &name) + : CheckCommand(StandardObjectType::HOST(), name) {}; + + /** + * Check the availability of at least one host. + * + * @param names The names of the hosts to check the availability of. + */ + HostCheckCommand (const std::vector &names) + : CheckCommand(StandardObjectType::HOST(), names) {}; +}; + +#endif // __HOST_CHECK_COMMAND_HPP diff --git a/AusRegEPPTK/se/HostCheckCommandTest.cpp b/AusRegEPPTK/se/HostCheckCommandTest.cpp new file mode 100644 index 0000000..75627df --- /dev/null +++ b/AusRegEPPTK/se/HostCheckCommandTest.cpp @@ -0,0 +1,40 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/HostCheckCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + HostCheckCommand hcc("ns1.jtkutest.com.au"); + const string xml(hcc.toXML()); + ASSERT_EQ(xml, "ns1.jtkutest.com.auJTKUTEST.20070101.010101.0"); + } + + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + std::vector names; + names.push_back("ns1.jtkutest.com.au"); + names.push_back("ns2.jtkutest.com.au"); + + HostCheckCommand hcc(names); + const string xml(hcc.toXML()); + ASSERT_EQ(xml, "ns1.jtkutest.com.auns2.jtkutest.com.auJTKUTEST.20070101.010101.0"); + } + +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/HostCheckResponse.cpp b/AusRegEPPTK/se/HostCheckResponse.cpp new file mode 100644 index 0000000..a0b976b --- /dev/null +++ b/AusRegEPPTK/se/HostCheckResponse.cpp @@ -0,0 +1,56 @@ +#include "se/HostCheckResponse.hpp" +#include "se/CheckResponse.hpp" +#include "se/StandardObjectType.hpp" + +#include "common/StringUtils.hpp" + +const std::string& HostCheckResponse::chkDataCountExpr() const +{ + static const std::string expr + = HostCheckResponse::exprReplace(CheckResponse::CHKDATA_COUNT_EXPR()); + return expr; +} + +const std::string& HostCheckResponse::chkDataIndexExpr() const +{ + static const std::string expr + = HostCheckResponse::exprReplace (CheckResponse::CHKDATA_IND_EXPR()); + return expr; +} + +const std::string& HostCheckResponse::chkDataTextExpr() const +{ + static const std::string expr + = HostCheckResponse::exprReplace (CheckResponse::CHKDATA_IDENT_EXPR()); + return expr; +} + +const std::string& HostCheckResponse::chkDataAvailExpr() const +{ + static const std::string expr + = HostCheckResponse::exprReplace (CheckResponse::CHKDATA_AVAIL_EXPR()); + return expr; +} + +const std::string& HostCheckResponse::chkDataReasonExpr() const +{ + static const std::string expr + = HostCheckResponse::exprReplace (CheckResponse::CHKDATA_REASON_EXPR()); + return expr; +} + + +HostCheckResponse::HostCheckResponse() + : CheckResponse (StandardObjectType::HOST()) +{ } + +std::string HostCheckResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll + (StringUtils::replaceAll + (expr, + DataResponse::OBJ(), + StandardObjectType::HOST()->getName()), + "IDENT", + "name"); +} diff --git a/AusRegEPPTK/se/HostCheckResponse.hpp b/AusRegEPPTK/se/HostCheckResponse.hpp new file mode 100644 index 0000000..5c393e0 --- /dev/null +++ b/AusRegEPPTK/se/HostCheckResponse.hpp @@ -0,0 +1,32 @@ +#ifndef __HOST_CHECK_RESPONSE_HPP +#define __HOST_CHECK_RESPONSE_HPP + +#include "se/CheckResponse.hpp" + +/** + * Use this to access availability data for hosts as provided in an EPP host + * check response compliant with RFCs 3730 and 3732. Such a service element is + * sent by a compliant EPP server in response to a valid host check command, + * implemented by the HostCheckCommand class. + * + * @see HostCheckCommand + */ +class HostCheckResponse : public CheckResponse +{ +public: + HostCheckResponse(); + +protected: + const std::string& chkDataCountExpr() const; + const std::string& chkDataIndexExpr() const; + const std::string& chkDataTextExpr() const; + const std::string& chkDataAvailExpr() const; + const std::string& chkDataReasonExpr() const; + +private: + + static std::string exprReplace (const std::string &expr); +}; + + +#endif // __HOST_CHECK_RESPONSE_HPP diff --git a/AusRegEPPTK/se/HostCreateCommand.cpp b/AusRegEPPTK/se/HostCreateCommand.cpp new file mode 100644 index 0000000..ccf6cc4 --- /dev/null +++ b/AusRegEPPTK/se/HostCreateCommand.cpp @@ -0,0 +1,16 @@ +#include "se/HostCreateCommand.hpp" +#include "se/StandardObjectType.hpp" + + +HostCreateCommand::HostCreateCommand (const std::string &name, + const std::vector *addresses) + : CreateCommand(StandardObjectType::HOST(), name) +{ + if (addresses) + { + std::vector::const_iterator inaddr; + + for (inaddr = addresses->begin(); inaddr != addresses->end(); inaddr++) + inaddr->appendToElement (xmlWriter, objElement); + } +} diff --git a/AusRegEPPTK/se/HostCreateCommand.hpp b/AusRegEPPTK/se/HostCreateCommand.hpp new file mode 100644 index 0000000..ff946f7 --- /dev/null +++ b/AusRegEPPTK/se/HostCreateCommand.hpp @@ -0,0 +1,33 @@ +#ifndef __HOST_CREATE_COMMAND_HPP +#define __HOST_CREATE_COMMAND_HPP + +#include "se/CreateCommand.hpp" +#include "se/InetAddress.hpp" + +/** + * Use this to request that a host object be provisioned in an EPP Registry. + * Instances of this class generate RFC3730 and RFC3732 compliant host create + * EPP command service elements via the toXML method. + * + * @see HostCreateResponse + */ +class HostCreateCommand : public CreateCommand +{ +public: + /** + * Provision a host with the specified details. This constructor allows + * specification of any and all parameters for a host create command. + * + * @param name The new host's name. + * + * @param addresses The Internet addresses of the host to be provisioned. + * These should only be specified if the parent domain is sponsored by the + * client provisioning this host and the parent domain is provisioned in + * the domain name registry in which this host is being provisioned. That + * is, external hosts must not be assigned Internet addresses. + */ + HostCreateCommand (const std::string &name, + const std::vector *addresses = NULL); +}; + +#endif // __HOST_CREATE_COMMAND_HPP diff --git a/AusRegEPPTK/se/HostCreateCommandTest.cpp b/AusRegEPPTK/se/HostCreateCommandTest.cpp new file mode 100644 index 0000000..af34dc9 --- /dev/null +++ b/AusRegEPPTK/se/HostCreateCommandTest.cpp @@ -0,0 +1,42 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/HostCreateCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + HostCreateCommand hcc("ns1.jtkutest.com.au"); + const string xml(hcc.toXML()); + ASSERT_EQ(xml, "ns1.jtkutest.com.auJTKUTEST.20070101.010101.0"); + } + + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + vector addrs; + addrs.push_back(InetAddress("192.168.0.1", IPVersion::IPv4())); + addrs.push_back(InetAddress("::1", IPVersion::IPv6())); + + HostCreateCommand hcc("ns1.jtkutest.com.au", &addrs); + const string xml(hcc.toXML()); + ASSERT_EQ(xml, "ns1.jtkutest.com.au192.168.0.1::1JTKUTEST.20070101.010101.0"); + } + +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/HostCreateResponse.cpp b/AusRegEPPTK/se/HostCreateResponse.cpp new file mode 100644 index 0000000..e65a6b6 --- /dev/null +++ b/AusRegEPPTK/se/HostCreateResponse.cpp @@ -0,0 +1,44 @@ +#include "se/HostCreateResponse.hpp" +#include "se/StandardObjectType.hpp" +#include "common/StringUtils.hpp" + +const std::string HostCreateResponse::HOS_CR_DATE_EXPR + (HostCreateResponse::exprReplace + (CreateResponse::CR_DATE_EXPR())); + +const std::string HostCreateResponse::HOS_NAME_EXPR + (HostCreateResponse::exprReplace + (CreateResponse::CRE_DATA_EXPR()) + "/host:name/text()"); + +HostCreateResponse::HostCreateResponse() + : CreateResponse(StandardObjectType::HOST()) +{ +} + +void HostCreateResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + CreateResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + name = xmlDoc->getNodeValue(HOS_NAME_EXPR); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + +std::string HostCreateResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + CreateResponse::OBJ(), + StandardObjectType::HOST()->getName()); +} diff --git a/AusRegEPPTK/se/HostCreateResponse.hpp b/AusRegEPPTK/se/HostCreateResponse.hpp new file mode 100644 index 0000000..1f33990 --- /dev/null +++ b/AusRegEPPTK/se/HostCreateResponse.hpp @@ -0,0 +1,32 @@ +#ifndef __HOST_CREATE_RESPONSE_HPP +#define __HOST_CREATE_RESPONSE_HPP + +#include "se/CreateResponse.hpp" + +/** + * Use this to access create data for a host as provided in an EPP host create + * response compliant with RFCs 3730 and 3732. Such a service element is sent + * by a compliant EPP server in response to a valid host create command, + * implemented by the HostCreateCommand. + * + * @see HostCreateCommand + */ +class HostCreateResponse : public CreateResponse +{ +public: + HostCreateResponse(); + + const std::string & getName() const { return name; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + const std::string & crDateExpr() const { return HOS_CR_DATE_EXPR; }; + + static std::string exprReplace (const std::string &expr); +private: + static const std::string HOS_CR_DATE_EXPR, + HOS_NAME_EXPR; + std::string name; +}; +#endif // __HOST_CREATE_RESPONSE_HPP diff --git a/AusRegEPPTK/se/HostDeleteCommand.hpp b/AusRegEPPTK/se/HostDeleteCommand.hpp new file mode 100644 index 0000000..d0965df --- /dev/null +++ b/AusRegEPPTK/se/HostDeleteCommand.hpp @@ -0,0 +1,26 @@ +#ifndef __HOST_DELETE_COMMAND_HPP +#define __HOST_DELETE_COMMAND_HPP + +#include "se/DeleteCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * Use this to request that a host object be deleted from an EPP Registry. + * Instances of this class generate RFC3730 and RFC3732 compliant host delete + * EPP command service elements via the toXML method. + * + * @see Response + */ +class HostDeleteCommand : public DeleteCommand +{ +public: + /** + * Delete the identified host. + * + * @param name The name of the host to delete. + */ + HostDeleteCommand (const std::string &name) + : DeleteCommand (StandardObjectType::HOST(), name) {}; +}; + +#endif // __HOST_DELETE_COMMAND_HPP diff --git a/AusRegEPPTK/se/HostDeleteCommandTest.cpp b/AusRegEPPTK/se/HostDeleteCommandTest.cpp new file mode 100644 index 0000000..1fdaea8 --- /dev/null +++ b/AusRegEPPTK/se/HostDeleteCommandTest.cpp @@ -0,0 +1,27 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/HostDeleteCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + HostDeleteCommand hcc("ns1.jtkutest.com.au"); + const string xml(hcc.toXML()); + ASSERT_EQ(xml, "ns1.jtkutest.com.auJTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/HostInfoCommand.hpp b/AusRegEPPTK/se/HostInfoCommand.hpp new file mode 100644 index 0000000..5439e98 --- /dev/null +++ b/AusRegEPPTK/se/HostInfoCommand.hpp @@ -0,0 +1,25 @@ +#ifndef __HOST_INFO_COMMAND_HPP +#define __HOST_INFO_COMMAND_HPP + +#include "se/InfoCommand.hpp" +#include "se/StandardObjectType.hpp" + +/** + * Use this to request information about a host object provisioned in an EPP + * Registry. Instances of this class generate RFC3730 and RFC3732 compliant + * host info EPP command service elements via the toXML method. + * + * @see HostInfoResponse + */ +class HostInfoCommand : public InfoCommand +{ +public: + /** + * Create a host info command with the specified identifier. + * + * @param name The name of the host to retrieve information about. + */ + HostInfoCommand (const std::string &name) + : InfoCommand (StandardObjectType::HOST(), name) {}; +}; +#endif // __HOST_INFO_COMMAND_HPP diff --git a/AusRegEPPTK/se/HostInfoCommandTest.cpp b/AusRegEPPTK/se/HostInfoCommandTest.cpp new file mode 100644 index 0000000..58cf91a --- /dev/null +++ b/AusRegEPPTK/se/HostInfoCommandTest.cpp @@ -0,0 +1,24 @@ +#include "se/HostInfoCommand.hpp" +#include "se/CLTRID.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + HostInfoCommand cmd("ns1.jtkutest.com.au"); + const string xml = cmd.toXML(); + ASSERT_EQ("ns1.jtkutest.com.auJTKUTEST.20070101.010101.0", xml); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/HostInfoResponse.cpp b/AusRegEPPTK/se/HostInfoResponse.cpp new file mode 100644 index 0000000..252fa6e --- /dev/null +++ b/AusRegEPPTK/se/HostInfoResponse.cpp @@ -0,0 +1,92 @@ +#include "se/HostInfoResponse.hpp" +#include "se/StandardObjectType.hpp" + +const std::string HostInfoResponse::HOS_ROID_EXPR + (HostInfoResponse::exprReplace (InfoResponse::ROID_EXPR())); + +const std::string HostInfoResponse::HOS_CR_ID_EXPR + (HostInfoResponse::exprReplace (InfoResponse::CR_ID_EXPR())); + +const std::string HostInfoResponse::HOS_UP_ID_EXPR + (HostInfoResponse::exprReplace (InfoResponse::UP_ID_EXPR())); + +const std::string HostInfoResponse::HOS_CL_ID_EXPR + (HostInfoResponse::exprReplace (InfoResponse::CL_ID_EXPR())); + +const std::string HostInfoResponse::HOS_CR_DATE_EXPR + (HostInfoResponse::exprReplace (InfoResponse::CR_DATE_EXPR())); + +const std::string HostInfoResponse::HOS_UP_DATE_EXPR + (HostInfoResponse::exprReplace (InfoResponse::UP_DATE_EXPR())); + +const std::string HostInfoResponse::HOS_TR_DATE_EXPR + (HostInfoResponse::exprReplace (InfoResponse::TR_DATE_EXPR())); + +const std::string HostInfoResponse::HOS_STATUS_COUNT_EXPR + (HostInfoResponse::exprReplace (InfoResponse::STATUS_COUNT_EXPR())); + +const std::string HostInfoResponse::HOS_STATUS_EXPR + (HostInfoResponse::exprReplace (InfoResponse::STATUS_EXPR())); + +const std::string HostInfoResponse::HOS_INF_DATA_EXPR + (HostInfoResponse::exprReplace (InfoResponse::INF_DATA_EXPR())); + +const std::string HostInfoResponse::HOS_NAME_EXPR + (HostInfoResponse::HOS_INF_DATA_EXPR + "/host:name/text()"); + +const std::string HostInfoResponse::HOS_ADDR_EXPR + (HostInfoResponse::HOS_INF_DATA_EXPR + "/host:addr[IDX]"); + +const std::string HostInfoResponse::HOS_ADDR_COUNT_EXPR + ("count(" + HostInfoResponse::HOS_INF_DATA_EXPR + "/host:addr)"); + +const std::string HostInfoResponse::HOS_ADDR_TXT_EXPR ("/text()"); + +const std::string HostInfoResponse::HOS_ADDR_IP_EXPR ("/@ip"); + + +HostInfoResponse::HostInfoResponse() + : InfoResponse(StandardObjectType::HOST()) +{ } + + +void HostInfoResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + debugLogger->LOG_FINEST("enter"); + InfoResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + name = xmlDoc->getNodeValue(HOS_NAME_EXPR); + + int addrCount = xmlDoc->getNodeCount (HOS_ADDR_COUNT_EXPR); + addresses.clear(); + + for (int i = 0; i < addrCount; i++) + { + std::string qry = ReceiveSE::replaceIndex(HOS_ADDR_EXPR, i+1); + std::string addr = xmlDoc->getNodeValue(qry + HOS_ADDR_TXT_EXPR); + std::string version = xmlDoc->getNodeValue(qry + HOS_ADDR_IP_EXPR); + addresses.push_back(InetAddress (addr, IPVersion::value(version))); + } + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } + debugLogger->LOG_FINEST("exit"); +} + +std::string HostInfoResponse::exprReplace (const std::string &expr) +{ + return StringUtils::replaceAll (expr, + DataResponse::OBJ(), + StandardObjectType::HOST()->getName()); +} diff --git a/AusRegEPPTK/se/HostInfoResponse.hpp b/AusRegEPPTK/se/HostInfoResponse.hpp new file mode 100644 index 0000000..3965f34 --- /dev/null +++ b/AusRegEPPTK/se/HostInfoResponse.hpp @@ -0,0 +1,58 @@ +#ifndef __HOST_INFO_RESPONSE_HPP +#define __HOST_INFO_RESPONSE_HPP + +#include "se/InfoResponse.hpp" +#include "se/InetAddress.hpp" + +/** + * Use this to access host object information as provided in an EPP host + * info response compliant with RFCs 3730 and 3732. Such a service element is + * sent by a compliant EPP server in response to a valid host info command, + * implemented by the HostInfoCommand class. + * + * @see HostInfoCommand + */ +class HostInfoResponse : public InfoResponse +{ +public: + HostInfoResponse (); + + const std::string& getName() const { return name; }; + const std::vector& getAddresses() const { return addresses; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + const std::string & roidExpr() const { return HOS_ROID_EXPR; }; + const std::string & clIDExpr() const { return HOS_CL_ID_EXPR; }; + const std::string & crIDExpr() const { return HOS_CR_ID_EXPR; }; + const std::string & upIDExpr() const { return HOS_UP_ID_EXPR; }; + const std::string & crDateExpr() const { return HOS_CR_DATE_EXPR; }; + const std::string & upDateExpr() const { return HOS_UP_DATE_EXPR; }; + const std::string & trDateExpr() const { return HOS_TR_DATE_EXPR; }; + const std::string & statusExpr() const { return HOS_STATUS_EXPR; }; + const std::string & statusCountExpr() const { return HOS_STATUS_COUNT_EXPR; }; + + static std::string exprReplace (const std::string &expr); + +private: + static const std::string HOS_ROID_EXPR, + HOS_CR_ID_EXPR, + HOS_UP_ID_EXPR, + HOS_CL_ID_EXPR, + HOS_CR_DATE_EXPR, + HOS_UP_DATE_EXPR, + HOS_TR_DATE_EXPR, + HOS_STATUS_COUNT_EXPR, + HOS_STATUS_EXPR, + HOS_INF_DATA_EXPR, + HOS_NAME_EXPR, + HOS_ADDR_EXPR, + HOS_ADDR_COUNT_EXPR, + HOS_ADDR_TXT_EXPR, + HOS_ADDR_IP_EXPR; + std::string name; + std::vector addresses; + +}; +#endif // __HOST_INFO_RESPONSE_HPP diff --git a/AusRegEPPTK/se/HostInfoResponseTest.cpp b/AusRegEPPTK/se/HostInfoResponseTest.cpp new file mode 100644 index 0000000..760398d --- /dev/null +++ b/AusRegEPPTK/se/HostInfoResponseTest.cpp @@ -0,0 +1,66 @@ +#include "se/HostInfoResponse.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + + const string xml( + "Command completed successfullyns1.example.comNS1_EXAMPLE1-REP192.0.2.2192.0.2.291080:0:0:0:8:800:200C:417AClientYClientX1999-04-03T22:00:00.0ZClientX1999-12-03T09:00:00.0Z2000-04-08T09:00:00.0ZABC-1234554322-XYZ"); + + HostInfoResponse response; + XMLParser parser; + std::auto_ptr doc(parser.parse(xml)); + response.fromXML(doc.get()); + + { + ASSERT_EQ(response.getName(), "ns1.example.com"); + + const vector& addrs(response.getAddresses()); + ASSERT_EQ(addrs.size(), 3); + if (addrs.size() != 3) exit(1); + ASSERT_EQ("192.0.2.2", addrs[0].getTextRep()); + ASSERT_EQ("192.0.2.29", addrs[1].getTextRep()); + ASSERT_EQ("1080:0:0:0:8:800:200C:417A", addrs[2].getTextRep()); + ASSERT_EQ("v4", addrs[0].getVersion()); + ASSERT_EQ("v4", addrs[1].getVersion()); + ASSERT_EQ("v6", addrs[2].getVersion()); + } + + { + ASSERT_EQ("NS1_EXAMPLE1-REP", response.getROID()); + auto_ptr dt( + EPPDateFormatter::fromXSDateTime("1999-04-03T22:00:00.0Z")); + ASSERT_EQ(EPPDateFormatter::toXSDateTime(*dt), "1999-04-03T22:00:00.0Z"); + + auto_ptr dt2( + EPPDateFormatter::fromXSDateTime("1999-04-03T22:00:00.0Z")); + ASSERT_EQ(EPPDateFormatter::toXSDateTime(*dt2), "1999-04-03T22:00:00.0Z"); + + ASSERT_EQ("ClientX", response.getCreateClient()); + ASSERT_EQ("ClientX", response.getUpdateClient()); + ASSERT_EQ("ClientY", response.getSponsorClient()); + const vector& statuses(response.getStatuses()); + ASSERT_EQ(2, statuses.size()); + if (statuses.size() != 2) exit(1); + ASSERT_EQ("linked", statuses[0].toString()); + ASSERT_EQ("clientUpdateProhibited", statuses[1].toString()); + ASSERT_EQ("ABC-12345", response.getCLTRID()); + } + +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/HostUpdateCommand.cpp b/AusRegEPPTK/se/HostUpdateCommand.cpp new file mode 100644 index 0000000..4883e0b --- /dev/null +++ b/AusRegEPPTK/se/HostUpdateCommand.cpp @@ -0,0 +1,30 @@ +#include "se/HostUpdateCommand.hpp" +#include "se/StandardObjectType.hpp" +#include "xml/XMLHelper.hpp" + + +HostUpdateCommand::HostUpdateCommand (const std::string &name, + const HostAddRem *add, + const HostAddRem *rem, + const std::string *newName) + : UpdateCommand(StandardObjectType::HOST(), name) +{ + if (add) + { + DOMElement *addElement = xmlWriter->appendChild (objElement, "add"); + add->appendToElement (xmlWriter, addElement); + } + + if (rem) + { + DOMElement *remElement = xmlWriter->appendChild (objElement, "rem"); + rem->appendToElement (xmlWriter, remElement); + } + + if (newName) + { + DOMElement *chgElement = xmlWriter->appendChild (objElement, "chg"); + XMLHelper::setTextContent + (xmlWriter->appendChild (chgElement, "name"), *newName); + } +} diff --git a/AusRegEPPTK/se/HostUpdateCommand.hpp b/AusRegEPPTK/se/HostUpdateCommand.hpp new file mode 100644 index 0000000..cd5d46a --- /dev/null +++ b/AusRegEPPTK/se/HostUpdateCommand.hpp @@ -0,0 +1,28 @@ +#ifndef __HOSTUPDATECOMMAND_HPP +#define __HOSTUPDATECOMMAND_HPP + +#include "se/UpdateCommand.hpp" +#include "se/HostAddRem.hpp" + +/** + * Use this to request the update of a host object provisioned in an EPP + * Registry. Instances of this class generate RFC3730 and RFC3732 compliant + * host update EPP command service elements via the toXML method. The + * response expected from a server should be handled by a Response object. + * + * @see Response + */ +class HostUpdateCommand : public UpdateCommand +{ +public: + /** + * The set of attributes of a host which may be updated as per + * RFC3732. + */ + HostUpdateCommand (const std::string &name, + const HostAddRem *add = NULL, + const HostAddRem *rem = NULL, + const std::string *newName = NULL); +}; + +#endif // __HOSTUPDATECOMMAND_HPP diff --git a/AusRegEPPTK/se/IPVersion.cpp b/AusRegEPPTK/se/IPVersion.cpp new file mode 100644 index 0000000..d42aba4 --- /dev/null +++ b/AusRegEPPTK/se/IPVersion.cpp @@ -0,0 +1,33 @@ +#include "se/IPVersion.hpp" + +using namespace std; + +// Static member initialisation. +vector IPVersion::values; + +const IPVersion* IPVersion::IPv4() +{ + static const IPVersion ver("v4"); + return &ver; +} + +const IPVersion* IPVersion::IPv6() +{ + static const IPVersion ver("v6"); + return &ver; +} + +void IPVersion::init() +{ + IPv4(); + IPv6(); +} + +IPVersion::IPVersion (const string &ip) + : EnumType (values, ip) +{ } + +const IPVersion* IPVersion::value (const string &name) +{ + return (const IPVersion *)EnumType::value (name, values); +} diff --git a/AusRegEPPTK/se/IPVersion.hpp b/AusRegEPPTK/se/IPVersion.hpp new file mode 100644 index 0000000..01e2425 --- /dev/null +++ b/AusRegEPPTK/se/IPVersion.hpp @@ -0,0 +1,25 @@ +#ifndef __IPVERSION_HPP +#define __IPVERSION_HPP + +#include "se/EnumType.hpp" + +/** + * Enumeration of Internet Protocol versions supported by EPP. + */ +class IPVersion : public EnumType +{ +public: + IPVersion (const std::string& ip); + + static const IPVersion* IPv4(); + static const IPVersion* IPv6(); + + static const IPVersion* value(const std::string &name); + + static void init(); + +private: + static std::vector values; +}; + +#endif // __IPVERSION_HPP diff --git a/AusRegEPPTK/se/IPVersionTest.cpp b/AusRegEPPTK/se/IPVersionTest.cpp new file mode 100644 index 0000000..47288bc --- /dev/null +++ b/AusRegEPPTK/se/IPVersionTest.cpp @@ -0,0 +1,24 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/IPVersion.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + ASSERT_EQ(IPVersion::IPv4()->toString(), "v4"); + ASSERT_EQ(IPVersion::IPv6()->toString(), "v6"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/IllegalArgException.hpp b/AusRegEPPTK/se/IllegalArgException.hpp new file mode 100644 index 0000000..05888cf --- /dev/null +++ b/AusRegEPPTK/se/IllegalArgException.hpp @@ -0,0 +1,15 @@ +#ifndef __ILLEGAL_ARGUMENT_EXCEPTION_HPP +#define __ILLEGAL_ARGUMENT_EXCEPTION_HPP + +#include "common/EPPException.hpp" + +class IllegalArgException : public EPPException +{ +public: + IllegalArgException(const std::string &msg) + : EPPException (msg) + { } + EPP_EXCEPTION(IllegalArgException); +}; + +#endif // __ILLEGAL_ARGUMENT_EXCEPTION_HPP diff --git a/AusRegEPPTK/se/InetAddress.cpp b/AusRegEPPTK/se/InetAddress.cpp new file mode 100644 index 0000000..bd1f3af --- /dev/null +++ b/AusRegEPPTK/se/InetAddress.cpp @@ -0,0 +1,8 @@ +#include "se/InetAddress.hpp" +#include "xml/XMLWriter.hpp" + +xercesc::DOMElement* InetAddress::appendToElement( + XMLWriter* xmlWriter, xercesc::DOMElement* parent) const +{ + return xmlWriter->appendChild(parent, "addr", textRep, "ip", getVersion()); +} diff --git a/AusRegEPPTK/se/InetAddress.hpp b/AusRegEPPTK/se/InetAddress.hpp new file mode 100644 index 0000000..d211156 --- /dev/null +++ b/AusRegEPPTK/se/InetAddress.hpp @@ -0,0 +1,59 @@ +#ifndef __INETADDRESS_HPP +#define __INETADDRESS_HPP + +#include +#include "se/IPVersion.hpp" +#include "se/Appendable.hpp" + +class XMLWriter; + +/** + * Host Internet addresses are configured and viewed via instances of this + * class. InetAddress instances may be supplied to the HostCreateCommand and + * HostUpdateCommand (indirectly via HostAddRem) constructors in order to + * assign or remove Internet addresses to and from host objects. They are also + * used to view Internet address information retrieved from a HostInfoResponse + * instance. + */ +class InetAddress : public Appendable +{ +public: + /// @TODO SWIG/Perl workaround - figure out why SWIG wants an empty constructor. + InetAddress() {} + + /** + * Construct an InetAddress of the specified version (either IPv4 or IPv6) + * using its textual representation. + */ + InetAddress(const std::string& textRep, + const IPVersion* version = IPVersion::IPv4()) + : version(version), textRep(textRep) + { } + + virtual ~InetAddress(){}; + + // static InetAddress getByName(const std::string& name); + + /** + * Get the Internet Protocol version of this address. + * + * @see IPVersion Enumerates possible return + * values. + */ + const std::string getVersion() const { return version->toString(); } + + /** + * Get the textual representation of this Internet address. + */ + const std::string& getTextRep() const { return textRep; } + + xercesc::DOMElement* appendToElement( + XMLWriter* xmlWriter, xercesc::DOMElement* parent) const; + +private: + + const IPVersion* version; + std::string textRep; +}; + +#endif // __INETADDRESS_HPP diff --git a/AusRegEPPTK/se/InfoCommand.hpp b/AusRegEPPTK/se/InfoCommand.hpp new file mode 100644 index 0000000..f72b95f --- /dev/null +++ b/AusRegEPPTK/se/InfoCommand.hpp @@ -0,0 +1,79 @@ +#ifndef __INFO_COMMAND_HPP +#define __INFO_COMMAND_HPP + +#include "se/ObjectCommand.hpp" +#include "se/StandardCommandType.hpp" +#include "xml/XStr.hpp" + +/** + * Representation of the EPP info command, as defined in RFC3730. + * Subclasses of this must specify the object to which the command is mapped + * and specify the object-specific identifier of the object to request + * information about. + * + * @see InfoResponse + */ +class InfoCommand : public ObjectCommand +{ +public: + /** + * Create an info command mapped to the specified object type to retrieve + * information about the identified object. + * + * @param objType The type of object to which the info command is to be + * mapped. + * + * @param ident An object type-specific label identifying the object to + * retrieve information about. + * + * @param pw The password of the object to retrieve information about. + * This is used to retrieve complete information about an object when the + * object is sponsored by another client. + */ + InfoCommand (const ObjectType *objType, + const std::string &ident, + const std::string &pw = "") + : ObjectCommand (StandardCommandType::INFO(), objType, ident) + { + if (pw == "") + return; + + xmlWriter->appendChild( + xmlWriter->appendChild( + objElement, "authInfo"), + "pw")->setTextContent(XStr(pw).str()); + }; + + /** + * Create an info command mapped to the specified object type to retrieve + * information about the identified object. + * + * @param objType The type of object to which the info command is to be + * mapped. + * + * @param ident An object type-specific label identifying the object to + * retrieve information about. + * + * @param roid The Repository Object Identifer of an object associated with + * the object to be queried. + * + * @param pw The password of the object to retrieve information about. + * This is used to retrieve complete information about an object when the + * object is sponsored by another client. + */ + InfoCommand(const ObjectType* objType, + const std::string& ident, + const std::string& roid, + const std::string& pw) + : ObjectCommand(StandardCommandType::INFO(), objType, ident) + { + xmlWriter->appendChild( + xmlWriter->appendChild(objElement, "authInfo"), + "pw", + "roid", + roid)->setTextContent(XStr(pw).str()); + + } +}; + +#endif // __INFO_COMMAND_HPP diff --git a/AusRegEPPTK/se/InfoResponse.cpp b/AusRegEPPTK/se/InfoResponse.cpp new file mode 100644 index 0000000..f147f61 --- /dev/null +++ b/AusRegEPPTK/se/InfoResponse.cpp @@ -0,0 +1,135 @@ +#include "se/InfoResponse.hpp" + +#include "se/StandardCommandType.hpp" +#include "se/EPPDateFormatter.hpp" + +#include + +const std::string InfoResponse::INF_DATA_EXPR() +{ + static std::string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:infData"; + return expr; +} +const std::string InfoResponse::ROID_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:roid/text()"; + return expr; +} + +const std::string InfoResponse::CR_ID_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:crID/text()"; + return expr; +} +const std::string InfoResponse::UP_ID_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:upID/text()"; + return expr; +} +const std::string InfoResponse::CL_ID_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:clID/text()"; + return expr; +} +const std::string InfoResponse::CR_DATE_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:crDate/text()"; + return expr; +} +const std::string InfoResponse::UP_DATE_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:upDate/text()"; + return expr; +} +const std::string InfoResponse::TR_DATE_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:trDate/text()"; + return expr; +} +const std::string InfoResponse::STATUS_COUNT_EXPR() +{ + static std::string expr = "count(" + InfoResponse::INF_DATA_EXPR() + "/OBJ:status)"; + return expr; +} +const std::string InfoResponse::STATUS_EXPR() +{ + static std::string expr = InfoResponse::INF_DATA_EXPR() + "/OBJ:status[IDX]"; + return expr; +} +const std::string InfoResponse::STATUS_S_EXPR() +{ + static std::string expr = "/@s"; + return expr; +} +const std::string InfoResponse::STATUS_REASON_EXPR() +{ + static std::string expr = "/text()"; + return expr; +} +const std::string InfoResponse::STATUS_LANG_EXPR() +{ + static std::string expr = "/@lang"; + return expr; +} + +InfoResponse::InfoResponse (const ObjectType* objectType) + : DataResponse(StandardCommandType::INFO(), objectType) +{ } + +void InfoResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML (xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + roid = xmlDoc->getNodeValue (roidExpr()); + + crID = xmlDoc->getNodeValue (crIDExpr()); + upID = xmlDoc->getNodeValue (upIDExpr()); + clID = xmlDoc->getNodeValue (clIDExpr()); + + std::string crDateStr = xmlDoc->getNodeValue(crDateExpr()); + std::string upDateStr = xmlDoc->getNodeValue(upDateExpr()); + std::string trDateStr = xmlDoc->getNodeValue(trDateExpr()); + + crDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(crDateStr)); + upDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(upDateStr)); + trDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(trDateStr)); + + int statusCount = xmlDoc->getNodeCount (statusCountExpr()); + statuses.clear(); + + for (int i = 0; i < statusCount; i++) + { + std::string qry = ReceiveSE::replaceIndex (statusExpr(), i + 1); + std::string reason = xmlDoc->getNodeValue (qry + STATUS_REASON_EXPR()); + std::string s = xmlDoc->getNodeValue (qry + STATUS_S_EXPR()); + std::string lang = xmlDoc->getNodeValue (qry + STATUS_LANG_EXPR()); + statuses.push_back (Status(s, reason, lang)); + } + } + catch (MalformedDateException& e) + { + ParsingException pe; + pe.causedBy(e); + throw pe; + } + catch (XPathExpressionException& e) + { + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} +// End InfoResponse::fromXML() + +std::string InfoResponse::toString() const +{ + std::string retval = DataResponse::toString(); + retval += "(roid = " + roid + ")"; + return retval; +} diff --git a/AusRegEPPTK/se/InfoResponse.hpp b/AusRegEPPTK/se/InfoResponse.hpp new file mode 100644 index 0000000..cef9ef9 --- /dev/null +++ b/AusRegEPPTK/se/InfoResponse.hpp @@ -0,0 +1,67 @@ +#ifndef __INFORESPONSE_HPP +#define __INFORESPONSE_HPP + +#include "se/DataResponse.hpp" +#include "se/Status.hpp" +#include "se/XMLGregorianCalendar.hpp" + +#include +#include +#include + +/** + * Use this to retrieve the values of attributes common to all EPP info response + * service elements. + */ +class InfoResponse : public DataResponse +{ +public: + InfoResponse (const ObjectType* objectType); + + const std::string & getROID() const { return roid; }; + const XMLGregorianCalendar* getCreateDate() const { return crDate.get(); }; + const XMLGregorianCalendar* getUpdateDate() const { return upDate.get(); }; + const XMLGregorianCalendar* getTransferDate() const { return trDate.get(); }; + const std::string & getCreateClient() const { return crID; }; + const std::string & getUpdateClient() const { return upID; }; + const std::string & getSponsorClient() const { return clID; }; + const std::vector &getStatuses() const { return statuses; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + + virtual std::string toString() const; + +protected: + static const std::string INF_DATA_EXPR(); + static const std::string ROID_EXPR(); + static const std::string CR_ID_EXPR(); + static const std::string UP_ID_EXPR(); + static const std::string CL_ID_EXPR(); + static const std::string CR_DATE_EXPR(); + static const std::string UP_DATE_EXPR(); + static const std::string TR_DATE_EXPR(); + static const std::string STATUS_COUNT_EXPR(); + static const std::string STATUS_EXPR(); + static const std::string STATUS_S_EXPR(); + static const std::string STATUS_REASON_EXPR(); + static const std::string STATUS_LANG_EXPR(); + + virtual const std::string & roidExpr() const = 0; + virtual const std::string & crIDExpr() const = 0; + virtual const std::string & upIDExpr() const = 0; + virtual const std::string & clIDExpr() const = 0; + virtual const std::string & crDateExpr() const = 0; + virtual const std::string & upDateExpr() const = 0; + virtual const std::string & trDateExpr() const = 0; + virtual const std::string & statusExpr() const = 0; + virtual const std::string & statusCountExpr() const = 0; + +private: + std::string roid; + std::string clID, crID, upID; + std::auto_ptr crDate, upDate, trDate; + std::vector statuses; +}; + + +#endif // __INFORESPONSE_HPP diff --git a/AusRegEPPTK/se/IntPostalInfo.hpp b/AusRegEPPTK/se/IntPostalInfo.hpp new file mode 100644 index 0000000..86d8e8f --- /dev/null +++ b/AusRegEPPTK/se/IntPostalInfo.hpp @@ -0,0 +1,38 @@ +#ifndef __INTPOSTALINFO_HPP +#define __INTPOSTALINFO_HPP + +#include "se/PostalInfo.hpp" +#include "se/PostalInfoType.hpp" + +#include +#include + +/** + * A restricted subclass of PostalInfo which supports only US ASCII character + * encoding as attribute values. + */ +class IntPostalInfo : public PostalInfo +{ +public: + IntPostalInfo (const std::string &name, + const std::string &city, + const std::string &countryCode) + : PostalInfo(PostalInfoType::INTERNATIONAL(), name, city, countryCode) + { } + + IntPostalInfo (const std::string &name, + const std::string &org, + const std::vector &street, + const std::string &city, + const std::string &stateProv, + const std::string &postcode, + const std::string &countryCode) + : PostalInfo (PostalInfoType::INTERNATIONAL(), + name, org, street, city, stateProv, + postcode, countryCode) + { } + + virtual ~IntPostalInfo() { } +}; + +#endif // __INTPOSTALINFO_HPP diff --git a/AusRegEPPTK/se/ItemNotFoundException.hpp b/AusRegEPPTK/se/ItemNotFoundException.hpp new file mode 100644 index 0000000..b413586 --- /dev/null +++ b/AusRegEPPTK/se/ItemNotFoundException.hpp @@ -0,0 +1,15 @@ +#ifndef __ITEM_NOT_FOUND_EXCEPTION_HPP +#define __ITEM_NOT_FOUND_EXCEPTION_HPP + +#include "common/EPPException.hpp" + +class ItemNotFoundException : public EPPException +{ +public: + ItemNotFoundException() + : EPPException("Item not found.") + { } + EPP_EXCEPTION(ItemNotFoundException); +}; + +#endif // __ITEM_NOT_FOUND_EXCEPTION_HPP diff --git a/AusRegEPPTK/se/KVDefs.hpp b/AusRegEPPTK/se/KVDefs.hpp new file mode 100644 index 0000000..82b339d --- /dev/null +++ b/AusRegEPPTK/se/KVDefs.hpp @@ -0,0 +1,14 @@ +/* + * KVDefs.hpp + * + * Created on: 06/09/2010 + * Author: qiao.zhao + */ + +#ifndef KVDEFS_HPP_ +#define KVDEFS_HPP_ + +typedef std::map KeyValueList; +typedef std::map ExtensionList; + +#endif /* KVDEFS_HPP_ */ diff --git a/AusRegEPPTK/se/KVExtension.cpp b/AusRegEPPTK/se/KVExtension.cpp new file mode 100644 index 0000000..0debded --- /dev/null +++ b/AusRegEPPTK/se/KVExtension.cpp @@ -0,0 +1,15 @@ +#include + +#include "se/KVExtension.hpp" + +std::string& KVExtension::getURI() const +{ + static std::string uri = "urn:X-ar:params:xml:ns:kv-1.0"; + return uri; +} + +std::string& KVExtension::getSchemaLocation() const +{ + static std::string loc = "urn:X-ar:params:xml:ns:kv-1.0 kv-1.0.xsd"; + return loc; +} diff --git a/AusRegEPPTK/se/KVExtension.hpp b/AusRegEPPTK/se/KVExtension.hpp new file mode 100644 index 0000000..ddbea25 --- /dev/null +++ b/AusRegEPPTK/se/KVExtension.hpp @@ -0,0 +1,31 @@ +#ifndef __KVEXTENSION_HPP +#define __KVEXTENSION_HPP + +#include + +#include "se/Extension.hpp" + +/** + * A bundled set of constants representing the KV + * EPP extension schema. The namespace URI uniquely identifies the extension. + */ +class KVExtension : public Extension +{ +public: + + virtual ~KVExtension(void) { } + + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __KVEXTENSION_HPP + diff --git a/AusRegEPPTK/se/LocalPostalInfo.hpp b/AusRegEPPTK/se/LocalPostalInfo.hpp new file mode 100644 index 0000000..1e163a3 --- /dev/null +++ b/AusRegEPPTK/se/LocalPostalInfo.hpp @@ -0,0 +1,37 @@ +#ifndef __LOCALPOSTALINFO_HPP +#define __LOCALPOSTALINFO_HPP + +#include "se/PostalInfo.hpp" +#include "se/PostalInfoType.hpp" + +#include +#include + +/** + * A character encoding-flexible subclass of PostalInfo which supports full + * UTF-8 character encoding for all attribute values. + */ +class LocalPostalInfo : public PostalInfo +{ +public: + LocalPostalInfo (const std::string &name, + const std::string &city, + const std::string &countryCode) + : PostalInfo (PostalInfoType::LOCAL(), + name, + city, + countryCode) {}; + + LocalPostalInfo (const std::string &name, + const std::string &org, + const std::vector &street, + const std::string &city, + const std::string &stateProv, + const std::string &postcode, + const std::string &countryCode) + : PostalInfo (PostalInfoType::LOCAL(), + name, org, street, city, stateProv, + postcode, countryCode) {}; +}; + +#endif // __LOCALPOSTALINFO_HPP diff --git a/AusRegEPPTK/se/LoginCommand.cpp b/AusRegEPPTK/se/LoginCommand.cpp new file mode 100644 index 0000000..4a7eede --- /dev/null +++ b/AusRegEPPTK/se/LoginCommand.cpp @@ -0,0 +1,109 @@ +#include "se/LoginCommand.hpp" +#include "se/StandardCommandType.hpp" +#include "se/StandardObjectType.hpp" +#include "xml/XMLHelper.hpp" + +#include + +using namespace std; + +const string LoginCommand::DEFAULT_VERSION("1.0"); +const string LoginCommand::DEFAULT_LANG("en"); + +LoginCommand::LoginCommand(const string &clID, + const string &password) + : Command (StandardCommandType::LOGIN()) +{ + const vector& stdURIs = StandardObjectType::getStandardURIs(); + + init(clID, password, DEFAULT_VERSION, DEFAULT_LANG, NULL, stdURIs, vector()); +} + + +LoginCommand::LoginCommand(const string& clID, + const string& password, + const string* newPW) + : Command(StandardCommandType::LOGIN()) +{ + const vector& stdURIs = StandardObjectType::getStandardURIs(); + + init(clID, password, DEFAULT_VERSION, DEFAULT_LANG, newPW, stdURIs, vector()); +} + + +LoginCommand::LoginCommand(const string& clID, + const string& password, + const vector objURIs, + const vector extURIs) + : Command(StandardCommandType::LOGIN()) +{ + init(clID, password, DEFAULT_VERSION, DEFAULT_LANG, NULL, objURIs, extURIs); +} + +LoginCommand::LoginCommand (const string& clID, + const string& password, + const string& version, + const string& lang, + const vector objURIs, + const vector extURIs) + : Command(StandardCommandType::LOGIN()) +{ + init(clID, password, version, lang, NULL, objURIs, extURIs); +} + +LoginCommand::LoginCommand (const string& clID, + const string& password, + const string* newPassword, + const string& version, + const string& lang, + const vector objURIs, + const vector extURIs) + : Command(StandardCommandType::LOGIN()) +{ + init(clID, password, version, lang, newPassword, objURIs, extURIs); +} + +void LoginCommand::init(const string& clID, + const string& password, + const string& version, + const string& lang, + const string* newPassword, + const vector objURIs, + const vector extURIs) +{ + XMLHelper::setTextContent + (xmlWriter->appendChild (cmdElement, "clID"), clID); + XMLHelper::setTextContent + (xmlWriter->appendChild (cmdElement, "pw"), password); + + if (newPassword) + XMLHelper::setTextContent + (xmlWriter->appendChild(cmdElement, "newPW"), *newPassword); + + DOMElement *options = xmlWriter->appendChild(cmdElement, "options"); + + XMLHelper::setTextContent + (xmlWriter->appendChild(options, "version"), version); + XMLHelper::setTextContent + (xmlWriter->appendChild(options, "lang"), lang); + + if (objURIs.size() > 0) + { + DOMElement *svcs = xmlWriter->appendChild(cmdElement, "svcs"); + for (unsigned int i = 0; i < objURIs.size(); i++) + { + XMLHelper::setTextContent(xmlWriter->appendChild(svcs, "objURI"), objURIs[i]); + } + + if (extURIs.size() > 0) + { + DOMElement *svcExtension = + xmlWriter->appendChild (svcs, "svcExtension"); + + for (unsigned int i = 0; i < extURIs.size(); i++) + XMLHelper::setTextContent + (xmlWriter->appendChild (svcExtension, "extURI"), + extURIs[i]); + } + } +} diff --git a/AusRegEPPTK/se/LoginCommand.hpp b/AusRegEPPTK/se/LoginCommand.hpp new file mode 100644 index 0000000..e6d5a9e --- /dev/null +++ b/AusRegEPPTK/se/LoginCommand.hpp @@ -0,0 +1,53 @@ +#ifndef __LOGIN_COMMAND_HPP +#define __LOGIN_COMMAND_HPP + +#include "se/Command.hpp" + +/** + * Use this to open an EPP session in order to perform commands only permitted + * from within the context of a session. Instances of this class generate, via + * the toXML method, login service elements compliant with the login + * specification in RFC3730. + * + * @see Greeting For services available to be used + * in the login command on the chosen EPP server. + * + * @see LogoutCommand To end a session opened + * using LoginCommand. + */ +class LoginCommand : public Command +{ +public: + LoginCommand(const std::string& clID, const std::string& password); + LoginCommand(const std::string& clID, const std::string& password, + const std::string* newPW); + LoginCommand(const std::string& clID, const std::string& password, + const std::vector objURIs, + const std::vector extURIs); + LoginCommand(const std::string& clID, const std::string& password, + const std::string& version, const std::string& lang, + const std::vector objURIs, + const std::vector extURIs); + LoginCommand(const std::string& clID, + const std::string& password, + const std::string* newPassword, + const std::string& version, + const std::string& lang, + const std::vector objURIs, + const std::vector extURIs); +private: + static const std::string DEFAULT_VERSION, DEFAULT_LANG; + + std::string clID, pw, newPW, version, lang; + std::vector objURIs, extURIs; + + void init(const std::string& clID, + const std::string& password, + const std::string& version, + const std::string& lang, + const std::string* newPassword, + const std::vector objURIs, + const std::vector extURIs); +}; + +#endif // __LOGIN_COMMAND_HPP diff --git a/AusRegEPPTK/se/LoginCommandTest.cpp b/AusRegEPPTK/se/LoginCommandTest.cpp new file mode 100644 index 0000000..ebfb82c --- /dev/null +++ b/AusRegEPPTK/se/LoginCommandTest.cpp @@ -0,0 +1,65 @@ +#include "se/LoginCommand.hpp" +#include "se/CLTRID.hpp" +#include "se/Period.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void doWork() +{ + const char* objU[] = { + "urn:ietf:params:xml:ns:domain-1.0", + "urn:ietf:params:xml:ns:host-1.0", + "urn:ietf:params:xml:ns:contact-1.0" }; + const vector objURIs(objU, objU + 3); + const vector extURIs(1, "urn:au:params:xml:ns:auext-1.0"); + + + init("etc/toolkit2.conf"); + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + LoginCommand cmd("JTKUTEST", "1234abcd!@#$JTK"); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "JTKUTEST1234abcd!@#$JTK1.0enurn:ietf:params:xml:ns:domain-1.0urn:ietf:params:xml:ns:host-1.0urn:ietf:params:xml:ns:contact-1.0JTKUTEST.20070101.010101.0"); + } + + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + LoginCommand cmd("JTKUTEST", "1234abcd!@#$JTK", objURIs, extURIs); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "JTKUTEST1234abcd!@#$JTK1.0enurn:ietf:params:xml:ns:domain-1.0urn:ietf:params:xml:ns:host-1.0urn:ietf:params:xml:ns:contact-1.0urn:au:params:xml:ns:auext-1.0JTKUTEST.20070101.010101.0"); + } + + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + LoginCommand cmd("JTKUTEST", "1234abcd!@#$JTK", "1.0", "fr", objURIs, extURIs); + const string xml(cmd.toXML()); + ASSERT_EQ("JTKUTEST1234abcd!@#$JTK1.0frurn:ietf:params:xml:ns:domain-1.0urn:ietf:params:xml:ns:host-1.0urn:ietf:params:xml:ns:contact-1.0urn:au:params:xml:ns:auext-1.0JTKUTEST.20070101.010101.0", xml); + } + + { + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + const string newPw("n(-w18PW*"); + LoginCommand cmd("JTKUTEST", "1234abcd!@#$JTK", &newPw, "1.0", "fr", objURIs, extURIs); + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "JTKUTEST1234abcd!@#$JTKn(-w18PW*1.0frurn:ietf:params:xml:ns:domain-1.0urn:ietf:params:xml:ns:host-1.0urn:ietf:params:xml:ns:contact-1.0urn:au:params:xml:ns:auext-1.0JTKUTEST.20070101.010101.0"); + } + +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/LogoutCommand.hpp b/AusRegEPPTK/se/LogoutCommand.hpp new file mode 100644 index 0000000..b513f97 --- /dev/null +++ b/AusRegEPPTK/se/LogoutCommand.hpp @@ -0,0 +1,23 @@ +#ifndef __LOGOUT_COMMAND_HPP +#define __LOGOUT_COMMAND_HPP + +#include "se/Command.hpp" +#include "se/StandardCommandType.hpp" + +/** + * Use this to close an open EPP session. This should be used to cleanly end a + * session which is no longer needed, or when changing an EPP client password. + * Instances of this class generate, via the toXML method, logout service elements + * compliant with the logout specification in RFC3730. + * + * @see LoginCommand The session should have been + * opened using this command prior to logging out. + */ +class LogoutCommand : public Command +{ +public: + LogoutCommand () + : Command(StandardCommandType::LOGOUT()) { } +}; + +#endif // __LOGOUT_COMMAND_HPP diff --git a/AusRegEPPTK/se/LogoutCommandTest.cpp b/AusRegEPPTK/se/LogoutCommandTest.cpp new file mode 100644 index 0000000..fc0781e --- /dev/null +++ b/AusRegEPPTK/se/LogoutCommandTest.cpp @@ -0,0 +1,29 @@ +#include "common/init.hpp" +#include "common/Test.hpp" +#include "se/CLTRID.hpp" +#include "se/LogoutCommand.hpp" +#include "session/Timer.hpp" + +#include + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + { + CLTRID::setClID("JTKUTEST"); + Timer::setTime("20070101.010101"); + + LogoutCommand cmd; + + const string xml(cmd.toXML()); + ASSERT_EQ(xml, "JTKUTEST.20070101.010101.0"); + } +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/NAPTR.cpp b/AusRegEPPTK/se/NAPTR.cpp new file mode 100644 index 0000000..c0399fa --- /dev/null +++ b/AusRegEPPTK/se/NAPTR.cpp @@ -0,0 +1,52 @@ +#include "se/NAPTR.hpp" +#include "common/StringUtils.hpp" +#include "xml/XMLHelper.hpp" +#include "xml/XMLWriter.hpp" +#include + +using namespace xercesc; + +NAPTR::NAPTR (int order, + int preference, + const char *flags, + const std::string &service, + const std::string ®ex, + const std::string &replacement) + : order(order), + preference(preference), + flags(flags), + svc(service), + regex(regex), + replacement(replacement) +{ +} + + +DOMElement * NAPTR::appendToElement (XMLWriter *xmlWriter, + DOMElement *parent) const +{ + DOMElement *e164Naptr = xmlWriter->appendChild (parent, "naptr"); + + if (e164Naptr) + { + XMLHelper::setTextContent + (xmlWriter->appendChild (e164Naptr, "order"), order); + + XMLHelper::setTextContent + (xmlWriter->appendChild (e164Naptr, "pref"), preference); + + XMLHelper::setTextContent + (xmlWriter->appendChild (e164Naptr, "flags"), flags); + + XMLHelper::setTextContent + (xmlWriter->appendChild (e164Naptr, "svc"), svc); + + XMLHelper::setTextContent + (xmlWriter->appendChild (e164Naptr, "regex"), regex); + + XMLHelper::setTextContent + (xmlWriter->appendChild (e164Naptr, "repl"), replacement); + } + + return e164Naptr; +} diff --git a/AusRegEPPTK/se/NAPTR.hpp b/AusRegEPPTK/se/NAPTR.hpp new file mode 100644 index 0000000..b1c1d9a --- /dev/null +++ b/AusRegEPPTK/se/NAPTR.hpp @@ -0,0 +1,54 @@ +#ifndef __NAPTR_HPP +#define __NAPTR_HPP + +#include +#include "se/Appendable.hpp" +#include + +/** + * This class models Naming Authority Pointer (NAPTR) resource records. + * Naming Authority Pointer (NAPTR) resource records are associated with + * ENUM domain names via the e164 extended create and update EPP commands. + * Instances of this class are used to construct NAPTR records to assign + * to ENUM domain objects, or to view attributes of NAPTR records already + * assigned to ENUM domain objects provisioned in an EPP Registry. + * + * @see EnumDomainCreateCommand Associate NAPTR + * records with a new ENUM domain object, rather than delegating to + * nameservers. + * + * @see EnumDomainUpdateCommand Add or remove + * NAPTR record associations to/from an ENUM domain object. + * + * @see EnumDomainInfoResponse Report assocations + * between a domain object and NAPTRs. + */ +class NAPTR : public Appendable +{ +public: + /// @TODO SWIG/Perl workaround - figure out why SWIG wants an empty constructor. + NAPTR () {} + + NAPTR (int order, + int preference, + const char *flags, + const std::string &service, + const std::string ®ex = "", + const std::string &replacement = ""); + virtual ~NAPTR(){}; + + int getOrder() const { return order; }; + int getPreference() const { return preference; }; + const std::string &getFlags() const { return flags; }; + const std::string &getService() const { return svc; }; + const std::string &getRegex() const { return regex; }; + const std::string &getReplacement() const { return replacement; }; + + virtual xercesc::DOMElement* appendToElement( + XMLWriter *xmlWriter, xercesc::DOMElement *parent) const; +private: + int order, preference; + std::string flags, svc, regex, replacement; +}; + +#endif // __NAPTR_HPP diff --git a/AusRegEPPTK/se/NotificationResponse.cpp b/AusRegEPPTK/se/NotificationResponse.cpp new file mode 100644 index 0000000..df1f4ca --- /dev/null +++ b/AusRegEPPTK/se/NotificationResponse.cpp @@ -0,0 +1,115 @@ +#include + +#include "se/NotificationResponse.hpp" +#include "se/EPPDateFormatter.hpp" +#include "se/StandardCommandType.hpp" +#include "common/StringUtils.hpp" + +using namespace std; + +NotificationResponse::NotificationResponse (const ObjectType* objectType) + : DataResponse(StandardCommandType::POLL(), objectType) +{ +} + +// BEGIN Class constants + +const string NotificationResponse::IDENT() +{ + static string expr = "IDENT"; + return expr; +} + +const string NotificationResponse::PAN_DATA_EXPR() +{ + static string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:panData"; + + return expr; +} + +const string NotificationResponse::IDENT_EXPR() +{ + static string expr = NotificationResponse::PAN_DATA_EXPR() + + "/OBJ:IDENT/text()"; + + return expr; +} + +const string NotificationResponse::RESULT_EXPR() +{ + static string expr = NotificationResponse::PAN_DATA_EXPR() + + "/OBJ:IDENT/@paResult"; + + return expr; +} + +const string NotificationResponse::CLTRID_EXPR() +{ + static string expr = NotificationResponse::PAN_DATA_EXPR() + + "/OBJ:paTRID/e:clTRID/text()"; + + return expr; +} + +const string NotificationResponse::SVTRID_EXPR() +{ + static string expr = NotificationResponse::PAN_DATA_EXPR() + + "/OBJ:paTRID/e:svTRID/text()"; + + return expr; +} + +const string NotificationResponse::PADATE_EXPR() +{ + static string expr = NotificationResponse::PAN_DATA_EXPR() + + "/OBJ:paDate/text()"; + + return expr; +} + +// END Class Constants + + +void NotificationResponse::fromXML(XMLDocument *xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) + return; + + try + { + identifier = xmlDoc->getNodeValue(identifierExpr()); + string resultStr = xmlDoc->getNodeValue(resultExpr()); + cltrid = xmlDoc->getNodeValue(cltridExpr()); + svtrid = xmlDoc->getNodeValue(svtridExpr()); + padateStr = xmlDoc->getNodeValue(padateExpr()); + + result = (resultStr == "1"); + paDate = std::auto_ptr( + EPPDateFormatter::fromXSDateTime(padateStr)); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} + +string NotificationResponse::toString(void) +{ + string retval = DataResponse::toString(); + string identType = getObjType().getIdentType(); + + retval += "(panData = (" + + identType + " = " + identifier + + ")(result = " + StringUtils::makeString(result) + + ")(clTRID = " + cltrid + + ")(svTRID = " + svtrid + + ")(paDate = " + padateStr + "))"; + + return retval; +} + diff --git a/AusRegEPPTK/se/NotificationResponse.hpp b/AusRegEPPTK/se/NotificationResponse.hpp new file mode 100644 index 0000000..f7fc442 --- /dev/null +++ b/AusRegEPPTK/se/NotificationResponse.hpp @@ -0,0 +1,90 @@ +#ifndef NOTIFICATION_RESPONSE +#define NOTIFICATION_RESPONSE + +#include + +#include "se/DataResponse.hpp" + +using namespace std; + +/** + * When offline processing of an action has been completed by the server + * operator, a message is enqueued for the client who requested the action. + * The NotificationResponse class models the pending action notification data + * informing the client of the completion of offline processing. A + * NotificationResponse is always specific to a particular object mapping, and + * so a subclass of this models the specific object data - such an object is + * returned by methods in {@link PollResponse}. + * + * @see PollRequestCommand + * @see PollResponse + */ +class NotificationResponse : public DataResponse +{ + public: + /** + * The identifier of the object which is the subject of this Pending Action + * Notification Data. + */ + string& getIdentifier() { return identifier; }; + + /** + * A positive boolean value indicates that the request has been approved + * and completed. A negative boolean value indicates that the request has + * been denied and the requested action has not been taken. + */ + bool getResult() { return result; }; + + /** + * The client transaction identifier identifier returned with the original + * response to process the command. The client transaction identifier is + * optional and will only be returned if the client provided an identifier + * with the original associated command. + */ + string getPaClTrID() { return cltrid; }; + + /** + * The server transaction identifier identifier returned with the original + * response to process the command. + */ + string& getPaSvTrID() { return svtrid; }; + + /** + * The date and time describing when review of the requested action was + * completed. + */ + XMLGregorianCalendar* getPaDate() { return paDate.get(); }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + virtual string toString(void); + + protected: + NotificationResponse(const ObjectType* objectType); + + static const string IDENT(); + + static const string IDENT_EXPR(); + static const string RESULT_EXPR(); + static const string CLTRID_EXPR(); + static const string SVTRID_EXPR(); + static const string PADATE_EXPR(); + + virtual const string& identifierExpr() const = 0; + virtual const string& resultExpr() const = 0; + virtual const string& cltridExpr() const = 0; + virtual const string& svtridExpr() const = 0; + virtual const string& padateExpr() const = 0; + + private: + static const string PAN_DATA_EXPR(); + + string identifier; + bool result; + string cltrid; + string svtrid; + string padateStr; + auto_ptr paDate; +}; + +#endif /* NOTIFICATION_RESPONSE */ + diff --git a/AusRegEPPTK/se/ObjectCommand.cpp b/AusRegEPPTK/se/ObjectCommand.cpp new file mode 100644 index 0000000..42c932e --- /dev/null +++ b/AusRegEPPTK/se/ObjectCommand.cpp @@ -0,0 +1,42 @@ +#include "se/ObjectCommand.hpp" +#include "xml/XStr.hpp" +#include "se/CommandType.hpp" +#include "se/IllegalArgException.hpp" +#include "common/ErrorPkg.hpp" + +ObjectCommand::ObjectCommand (const CommandType* commandType, + const ObjectType* objectType, + const std::string& ident) + : Command(commandType), objType(objectType) +{ + const std::vector idents (1, ident); + + Init(commandType, objectType, idents); +} + +ObjectCommand::ObjectCommand (const CommandType* commandType, + const ObjectType* objectType, + const std::vector& idents) + : Command(commandType), objType(objectType) +{ + Init(commandType, objectType, idents); +} + +void ObjectCommand::Init(const CommandType* commandType, + const ObjectType* objectType, + const std::vector& idents) +{ + if (commandType == NULL || objectType == NULL || idents.size() == 0) + { + throw IllegalArgException(ErrorPkg::getMessage("se.object.missing_arg")); + } + objElement = xmlWriter->appendChild(cmdElement, + commandType->getCommandName(), + objectType->getURI()); + objElement->setAttribute( + XStr("xsi:schemaLocation").str(), + XStr(objType->getSchemaLocation()).str()); + + xmlWriter->appendChildren(objElement, objectType->getIdentType(), idents); +} + diff --git a/AusRegEPPTK/se/ObjectCommand.hpp b/AusRegEPPTK/se/ObjectCommand.hpp new file mode 100644 index 0000000..bf01c06 --- /dev/null +++ b/AusRegEPPTK/se/ObjectCommand.hpp @@ -0,0 +1,48 @@ +#ifndef __OBJECTCOMMAND_HPP +#define __OBJECTCOMMAND_HPP + +#include "se/Command.hpp" +#include "se/Extension.hpp" +#include "se/ObjectType.hpp" + +/** + * Superclass of all command classes which implement an object-mapped EPP + * command such as create, delete, update, transfer, info and check. + * Non-abstract subclasses must specify the command and object type, and not + * expose assignment of those to the user. + */ +class ObjectCommand : public Command +{ +public: + /** + * Construct the DOM tree component common to all object-mapped commands + * which take multiple object identifiers as parameters. + */ + ObjectCommand (const CommandType* commandType, + const ObjectType* objectType, + const std::string& ident); + + /** + * Construct the DOM tree component common to all object-mapped commands + * which operate on a single object. + */ + ObjectCommand (const CommandType* commandType, + const ObjectType* objectType, + const std::vector& idents); + + const ObjectType* getObjectType() const { return objType; }; + + +protected: + DOMElement *objElement; + +private: + const ObjectType *objType; + + void Init(const CommandType* commandType, + const ObjectType* objectType, + const std::vector& idents); +}; + +#endif // __OBJECTCOMMAND_HPP + diff --git a/AusRegEPPTK/se/ObjectType.hpp b/AusRegEPPTK/se/ObjectType.hpp new file mode 100644 index 0000000..4e793fa --- /dev/null +++ b/AusRegEPPTK/se/ObjectType.hpp @@ -0,0 +1,44 @@ +#ifndef __OBJECTTYPE_HPP +#define __OBJECTTYPE_HPP + +#include + +/** + * The Extensible Provisioning Protocol defines object-specific commands. + * Object mappings for EPP map those commands to the defined object. Such + * objects are identified definitively by namespace URI. Instances of the + * ObjectType class provide that identification within the toolkit, as well + * as convenience methods for simplifying the usage of EPP object-specific + * commands. + */ +class ObjectType +{ +public: + virtual ~ObjectType(void) = 0; + /** + * Get the commonly used name for the object identified by this type. + */ + virtual const std::string & getName() const = 0; + /** + * Get the namespace URI of the object identified by this type. This is + * the authoritative key for distinguishing between object types. + */ + virtual const std::string & getURI() const = 0; + /** + * Get the schema location hint normally prescribed for this object type. + */ + virtual const std::string & getSchemaLocation() const = 0; + /** + * Get the label name of the primary identifier used in EPP service elements + * mapped to the object identified by this type. + */ + virtual const std::string & getIdentType() const = 0; +}; + +inline ObjectType::~ObjectType(void) +{ + return; +} + +#endif // __OBJECTTYPE_HPP + diff --git a/AusRegEPPTK/se/Period.cpp b/AusRegEPPTK/se/Period.cpp new file mode 100644 index 0000000..e866655 --- /dev/null +++ b/AusRegEPPTK/se/Period.cpp @@ -0,0 +1,19 @@ +#include "se/Period.hpp" +#include "xml/XMLWriter.hpp" + +#include "xml/XMLHelper.hpp" + +using namespace xercesc; + +DOMElement* Period::appendPeriod(XMLWriter *xmlWriter, + DOMElement *parent) const +{ + DOMElement *retval = + xmlWriter->appendChild( + parent, + "period", + "unit", + unit->toString()); + XMLHelper::setTextContent (retval, period); + return retval; +} diff --git a/AusRegEPPTK/se/Period.hpp b/AusRegEPPTK/se/Period.hpp new file mode 100644 index 0000000..e95fe7d --- /dev/null +++ b/AusRegEPPTK/se/Period.hpp @@ -0,0 +1,42 @@ +#ifndef __PERIOD_HPP +#define __PERIOD_HPP + +#include "se/PeriodUnit.hpp" + +#include + +class XMLWriter; + +/** + * This class models the period element specified in RFC3731, used to specify + * domain validity periods. + */ +class Period +{ +public: + /** + * A validity period specified in the given unit (default years). + */ + Period(int period, const PeriodUnit* unit = PeriodUnit::YEARS()) + : unit(unit), period(period) + { } + + /** + * Append an xml representation of this Period instance to the list of + * child elements of the given parent Element. The XMLWriter is used to + * insert the new Element into the DOM tree in which the parent resides. + * + * @param xmlWriter The XMLWriter that maintains the DOM tree. The work + * of creating and inserting the new element is delegated to this object. + * + * @param parent The Element which will parent the new element. + */ + xercesc::DOMElement* appendPeriod( + XMLWriter *xmlWriter, xercesc::DOMElement *parent) const; + +private: + const PeriodUnit* unit; + int period; +}; + +#endif // __PERIOD_HPP diff --git a/AusRegEPPTK/se/PeriodUnit.cpp b/AusRegEPPTK/se/PeriodUnit.cpp new file mode 100644 index 0000000..2a3dd4e --- /dev/null +++ b/AusRegEPPTK/se/PeriodUnit.cpp @@ -0,0 +1,37 @@ +#include "se/PeriodUnit.hpp" + +std::vector PeriodUnit::values; + +const PeriodUnit* PeriodUnit::MONTHS() +{ + static const PeriodUnit unit("m"); + return &unit; +} + +const PeriodUnit* PeriodUnit::YEARS() +{ + static const PeriodUnit unit("y"); + return &unit; +} + +PeriodUnit::PeriodUnit(const std::string &description) + : EnumType(values, description) +{ } + +const PeriodUnit* PeriodUnit::value (const std::string &name) +{ + try + { + return (const PeriodUnit *)EnumType::value (name, values); + } + catch (IllegalArgException) + { + return YEARS(); + } +} + +void PeriodUnit::init() +{ + MONTHS(); + YEARS(); +} diff --git a/AusRegEPPTK/se/PeriodUnit.hpp b/AusRegEPPTK/se/PeriodUnit.hpp new file mode 100644 index 0000000..617f396 --- /dev/null +++ b/AusRegEPPTK/se/PeriodUnit.hpp @@ -0,0 +1,24 @@ +#ifndef __PERIOD_UNIT_HPP +#define __PERIOD_UNIT_HPP + +#include "se/EnumType.hpp" + +/** + * Enumeration of units supported by EPP for period elements. + */ +class PeriodUnit : public EnumType +{ +public: + PeriodUnit (const std::string &description); + + static const PeriodUnit* MONTHS(); + static const PeriodUnit* YEARS(); + + static const PeriodUnit* value(const std::string &name); + + static void init(); +private: + static std::vector values; +}; + +#endif // __PERIOD_UNIT_HPP diff --git a/AusRegEPPTK/se/PollAckCommand.hpp b/AusRegEPPTK/se/PollAckCommand.hpp new file mode 100644 index 0000000..4a8ee7c --- /dev/null +++ b/AusRegEPPTK/se/PollAckCommand.hpp @@ -0,0 +1,31 @@ +#ifndef __POLL_ACK_COMMAND_HPP +#define __POLL_ACK_COMMAND_HPP + +#include "se/PollCommand.hpp" +#include "xml/XStr.hpp" + +#include + +/** + * Use this command to acknowledge receipt of a service message previously + * retrieved via a poll request. This dequeues the message and makes the next + * message available for retrieval. From RFC 3730: + * "After a messages has been received by the client, the client MUST respond to + * the message with an explicit acknowledgement to confirm that the message has + * been received. A server MUST dequeue the message and decrement the queue + * counter after receiving acknowledgement from the client, making the next + * message in the queue (if any) available for retrieval." + */ +class PollAckCommand : public PollCommand +{ +public: + PollAckCommand (int msgID) + : PollCommand (PollOperation::ACK()) + { + std::ostringstream intval; + intval << msgID; + cmdElement->setAttribute(XStr("msgID").str(), XStr(intval.str()).str()); + }; +}; + +#endif // __POLL_ACK_COMMAND_HPP diff --git a/AusRegEPPTK/se/PollAckCommandTest.cpp b/AusRegEPPTK/se/PollAckCommandTest.cpp new file mode 100644 index 0000000..1979190 --- /dev/null +++ b/AusRegEPPTK/se/PollAckCommandTest.cpp @@ -0,0 +1,24 @@ +#include "se/PollAckCommand.hpp" +#include "se/CLTRID.hpp" +#include "session/Timer.hpp" +#include "common/Test.hpp" +#include "common/init.hpp" + +using namespace std; + +void doWork() +{ + init("etc/toolkit2.conf"); + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + PollAckCommand cmd(123); + const string xml = cmd.toXML(); + ASSERT_EQ("JTKUTEST.20070101.010101.0", xml); +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/PollCommand.hpp b/AusRegEPPTK/se/PollCommand.hpp new file mode 100644 index 0000000..71c354a --- /dev/null +++ b/AusRegEPPTK/se/PollCommand.hpp @@ -0,0 +1,31 @@ +#ifndef __POLL_COMMAND_HPP +#define __POLL_COMMAND_HPP + +#include "xml/XStr.hpp" +#include "se/Command.hpp" +#include "se/StandardCommandType.hpp" +#include "se/PollOperation.hpp" +#include "common/ErrorPkg.hpp" + +/** + * Representation of the EPP poll command, as defined in RFC3730. Subclasses + * of this must internally specify the poll operation as either acknowledge + * (ack) or request (req), without exposing the implementation of the poll + * operation type to the user. + */ +class PollCommand : public Command +{ +public: + PollCommand(const PollOperation* op) + : Command(StandardCommandType::POLL()) + { + if (op == NULL) + { + throw ::IllegalArgException( + ErrorPkg::getMessage("se.poll.op.missing")); + } + cmdElement->setAttribute(XStr("op").str(), XStr(op->toString()).str()); + } +}; + +#endif // __POLL_COMMAND_HPP diff --git a/AusRegEPPTK/se/PollOperation.cpp b/AusRegEPPTK/se/PollOperation.cpp new file mode 100644 index 0000000..8418c52 --- /dev/null +++ b/AusRegEPPTK/se/PollOperation.cpp @@ -0,0 +1,30 @@ +#include "se/PollOperation.hpp" + +std::vector PollOperation::values; + +const PollOperation* PollOperation::REQ() +{ + static const PollOperation po("req"); + return PollOperation::value("req"); +} + +const PollOperation* PollOperation::ACK() +{ + static const PollOperation po("ack"); + return PollOperation::value("ack"); +} + +PollOperation::PollOperation(const std::string &op) + : EnumType(values, op) +{ } + +const PollOperation* PollOperation::value (const std::string &name) +{ + return (const PollOperation *)EnumType::value (name, values); +} + +void PollOperation::init() +{ + REQ(); + ACK(); +} diff --git a/AusRegEPPTK/se/PollOperation.hpp b/AusRegEPPTK/se/PollOperation.hpp new file mode 100644 index 0000000..180fc98 --- /dev/null +++ b/AusRegEPPTK/se/PollOperation.hpp @@ -0,0 +1,25 @@ +#ifndef __POLL_OPERATION_HPP +#define __POLL_OPERATION_HPP + +#include "se/EnumType.hpp" + +/** + * Enumeration of poll operations supported by EPP. + */ +class PollOperation : public EnumType +{ +public: + PollOperation(const std::string& op); + + static const PollOperation* REQ(); + static const PollOperation* ACK(); + + static const PollOperation* value(const std::string &name); + + static void init(); + +private: + static std::vector values; +}; + +#endif // __POLL_OPERATION_HPP diff --git a/AusRegEPPTK/se/PollRequestCommand.hpp b/AusRegEPPTK/se/PollRequestCommand.hpp new file mode 100644 index 0000000..ebf7867 --- /dev/null +++ b/AusRegEPPTK/se/PollRequestCommand.hpp @@ -0,0 +1,24 @@ +#ifndef __POLL_REQUEST_COMMAND_HPP +#define __POLL_REQUEST_COMMAND_HPP + +#include "se/PollCommand.hpp" + +/** + * Use this command to poll the EPP server for the first message in the + * client's message queue maintained by the server. From RFC 3730: + * "The EPP command is used to discover and retrieve service + * messages queued by a server for individual clients. If the message queue is + * not empty, a successful resposne to a command MUST return the + * first message from the message queue. Each response returned from the + * server includes a server-unique message identifier that MUST be provided to + * acknowledge receipt of the message, and a counter that indicates the number + * of messages in the queue. + * + */ +class PollRequestCommand : public PollCommand +{ +public: + PollRequestCommand () + : PollCommand (PollOperation::REQ()) { } +}; +#endif // __POLL_REQUEST_COMMAND_HPP diff --git a/AusRegEPPTK/se/PollResponse.cpp b/AusRegEPPTK/se/PollResponse.cpp new file mode 100644 index 0000000..55cf835 --- /dev/null +++ b/AusRegEPPTK/se/PollResponse.cpp @@ -0,0 +1,136 @@ +#include "se/PollResponse.hpp" + +#include +#include + +const std::string PollResponse::RES_DATA_EXPR(Response::RESPONSE_EXPR() + "/e:resData"); + +const xalanc::XalanDOMString PollResponse::TRN_DATA() +{ + static xalanc::XalanDOMString domStr("trnData"); + + return domStr; +} + +const xalanc::XalanDOMString PollResponse::INF_DATA() +{ + static xalanc::XalanDOMString domStr("infData"); + + return domStr; +} + +const xalanc::XalanDOMString PollResponse::PAN_DATA() +{ + static xalanc::XalanDOMString domStr("panData"); + + return domStr; +} + +PollResponse::PollResponse() + : resData(NULL) +{ + conTrnResponse = NULL; + domTrnResponse = NULL; + conNtfnResponse = NULL; + domNtfnResponse = NULL; + conInfoResponse = NULL; + domInfoResponse = NULL; +} + +PollResponse::~PollResponse() +{ + if (conTrnResponse != NULL) { + delete conTrnResponse; + } else if (domTrnResponse != NULL) { + delete domTrnResponse; + } else if (conNtfnResponse != NULL) { + delete conNtfnResponse; + } else if (domNtfnResponse != NULL) { + delete domNtfnResponse; + } else if (conInfoResponse != NULL) { + delete conInfoResponse; + } else if (domInfoResponse != NULL) { + delete domInfoResponse; + } +} + +void PollResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + using namespace xalanc; + + debugLogger->LOG_FINEST("enter"); + Response::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + const XalanNode* resDataNode = xmlDoc->getElement(RES_DATA_EXPR); + + if (resDataNode && dynamic_cast(resDataNode) != NULL) + resData = dynamic_cast(resDataNode); + + if (resData == NULL) + { + // Nothing further to extract. + return; + } + + XalanNode* childNode = resData->getFirstChild(); + if (!childNode) { + debugLogger->LOG_FINEST("exit"); + return; + } + + xalanc::XalanDOMString childName(childNode->getLocalName()); + xalanc::XalanDOMString dom_uri(StandardObjectType::DOMAIN()->getURI().c_str()); + xalanc::XalanDOMString con_uri(StandardObjectType::CONTACT()->getURI().c_str()); + + if (xalanc::XalanDOMString::equals(childNode->getNamespaceURI(), dom_uri)) + { + if (xalanc::XalanDOMString::equals(childName, TRN_DATA())) { + domTrnResponse = new DomainTransferResponse(); + domTrnResponse->fromXML(xmlDoc); + } + else if (xalanc::XalanDOMString::equals(childName, PAN_DATA())) + { + domNtfnResponse = new DomainNotificationResponse(); + domNtfnResponse->fromXML(xmlDoc); + } + else if (xalanc::XalanDOMString::equals(childName, INF_DATA())) + { + domInfoResponse = new DomainInfoResponse(); + domInfoResponse->fromXML(xmlDoc); + } + } + else if (xalanc::XalanDOMString::equals(childNode->getNamespaceURI(), con_uri)) + { + if (xalanc::XalanDOMString::equals(childName, TRN_DATA())) { + conTrnResponse = new ContactTransferResponse(); + conTrnResponse->fromXML(xmlDoc); + } + else if (xalanc::XalanDOMString::equals(childName, PAN_DATA())) + { + conNtfnResponse = new ContactNotificationResponse(); + conNtfnResponse->fromXML(xmlDoc); + } + else if (xalanc::XalanDOMString::equals(childName, INF_DATA())) + { + conInfoResponse = new ContactInfoResponse(); + conInfoResponse->fromXML(xmlDoc); + } + } + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } + + debugLogger->LOG_FINEST("exit"); +} + diff --git a/AusRegEPPTK/se/PollResponse.hpp b/AusRegEPPTK/se/PollResponse.hpp new file mode 100644 index 0000000..3509568 --- /dev/null +++ b/AusRegEPPTK/se/PollResponse.hpp @@ -0,0 +1,81 @@ +#ifndef __POLL_RESPONSE_HPP +#define __POLL_RESPONSE_HPP + +#include "se/Response.hpp" +#include "se/ContactTransferResponse.hpp" +#include "se/DomainTransferResponse.hpp" +#include "se/ContactNotificationResponse.hpp" +#include "se/DomainNotificationResponse.hpp" +#include "se/ContactInfoResponse.hpp" +#include "se/DomainInfoResponse.hpp" +#include +#include +#include +#include + +#ifndef SWIG +XALAN_USING_XALAN(XalanElement) +#endif + +/** + * Use this to access poll response information, as provided in an EPP poll + * response compliant with RFC 3730. Such a service element is sent by an EPP + * server in response to a poll service element. If in response to a poll + * request, the getResData, getContactTransferResponse or + * getDomainTransferResponse methods may return object-specific information, + * which is in addition to any message queue data potentially available via the + * getMessage and related methods in the {@link Response} class. + * + * @see PollCommand + * @see PollRequestCommand + * @see PollAckCommand + */ +class PollResponse : public Response +{ +public: + PollResponse(); + ~PollResponse(); + + const ContactTransferResponse* getContactTransferResponse() + { return conTrnResponse; }; + + const DomainTransferResponse* getDomainTransferResponse() + { return domTrnResponse; }; + + const ContactNotificationResponse* getContactNotificationResponse() + { return conNtfnResponse; }; + + const DomainNotificationResponse* getDomainNotificationResponse() + { return domNtfnResponse; }; + + const ContactInfoResponse* getContactInfoResponse() + { return conInfoResponse; }; + + const DomainInfoResponse* getDomainInfoResponse() + { return domInfoResponse; }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +private: + PollResponse(const PollResponse&); + PollResponse& operator=(const PollResponse&); + + static const std::string RES_DATA_EXPR; + + static const xalanc::XalanDOMString TRN_DATA(); + static const xalanc::XalanDOMString INF_DATA(); + static const xalanc::XalanDOMString PAN_DATA(); + + // Non-owning pointer. + const XalanElement* resData; + + // Owned data + DomainTransferResponse* domTrnResponse; + ContactTransferResponse* conTrnResponse; + DomainNotificationResponse* domNtfnResponse; + ContactNotificationResponse* conNtfnResponse; + DomainInfoResponse* domInfoResponse; + ContactInfoResponse* conInfoResponse; +}; + +#endif // __POLL_RESPONSE_HPP diff --git a/AusRegEPPTK/se/PollResponseTest.cpp b/AusRegEPPTK/se/PollResponseTest.cpp new file mode 100644 index 0000000..7ce195e --- /dev/null +++ b/AusRegEPPTK/se/PollResponseTest.cpp @@ -0,0 +1,103 @@ +#include "se/PollResponse.hpp" +#include "se/CLTRID.hpp" +#include "se/EPPDateFormatter.hpp" +#include "xml/XMLParser.hpp" +#include "session/Timer.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" + +#include + +using namespace std; + +void testContactTransferApprovePoll(); +void testDomainTransferApprovePoll(); +PollResponse& getPollResponse(const string xml); + +void doWork() +{ + init("etc/toolkit2.conf"); + + testContactTransferApprovePoll(); + testDomainTransferApprovePoll(); +} + +void testContactTransferApprovePoll() +{ + const string xml = + "Command completed successfully; ack to dequeue2000-06-08T22:00:00.0ZTransfer requested.JTKUTESTpendingClientX2000-06-08T22:00:00.0ZClientY2000-06-13T22:00:00.0ZABC-1234554321-XYZ"; + + PollResponse& response(getPollResponse(xml)); + + const ContactTransferResponse* ctr = response.getContactTransferResponse(); + ASSERT(ctr != NULL); + ASSERT_EQ("JTKUTEST", ctr->getID()); + ASSERT_EQ("pending", ctr->getTransferStatus()); + ASSERT_EQ("ClientX", ctr->getRequestingClID()); + ASSERT_EQ("ClientY", ctr->getActioningClID()); + + const vector& results(response.getResults()); + ASSERT_EQ(1, results.size()); + ASSERT_EQ(1301, results[0].getResultCode()); + ASSERT_EQ( + "Command completed successfully; ack to dequeue", + results[0].getResultMessage()); + + ASSERT_EQ("ABC-12345", response.getCLTRID()); + const XMLGregorianCalendar *qDate1 = response.getMessageEnqueueDate(); + std::string res = EPPDateFormatter::toXSDateTime(*qDate1); + ASSERT_EQ(res, "2000-06-08T22:00:00.0Z"); + + ASSERT_EQ("Transfer requested.", response.getMessage()); + ASSERT_EQ("en", response.getMessageLanguage()); + ASSERT_EQ(5, response.getMsgCount()); + ASSERT_EQ("12345", response.getMsgID()); +} + +void testDomainTransferApprovePoll() +{ + const string xml = + "Command completed successfully; ack to dequeue2000-06-08T22:00:00.0ZTransfer requested.example.compendingClientX2000-06-08T22:00:00.0ZClientY2000-06-13T22:00:00.0Z2002-09-08T22:00:00.0ZABC-1234554321-XYZ"; + + PollResponse& response(getPollResponse(xml)); + + const DomainTransferResponse* dtr = response.getDomainTransferResponse(); + ASSERT(dtr != NULL); + ASSERT_EQ("example.com", dtr->getName()); + ASSERT_EQ("pending", dtr->getTransferStatus()); + ASSERT_EQ("ClientX", dtr->getRequestingClID()); + ASSERT_EQ("ClientY", dtr->getActioningClID()); + + const vector& results(response.getResults()); + ASSERT_EQ(1, results.size()); + ASSERT_EQ(1301, results[0].getResultCode()); + ASSERT_EQ( + "Command completed successfully; ack to dequeue", + results[0].getResultMessage()); + + ASSERT_EQ("ABC-12345", response.getCLTRID()); + const XMLGregorianCalendar *qDate1 = response.getMessageEnqueueDate(); + std::string res = EPPDateFormatter::toXSDateTime(*qDate1); + ASSERT_EQ(res, "2000-06-08T22:00:00.0Z"); + + ASSERT_EQ("Transfer requested.", response.getMessage()); + ASSERT_EQ("en", response.getMessageLanguage()); + ASSERT_EQ(5, response.getMsgCount()); + ASSERT_EQ("12345", response.getMsgID()); +} + +PollResponse& getPollResponse(const string xml) +{ + PollResponse *response = new PollResponse(); + XMLParser parser; + response->fromXML(parser.parse(xml)); + + return *response; +} + +int main(int argc, char* argv[]) +{ + TEST_run(doWork); + return TEST_errorCount(); +} + diff --git a/AusRegEPPTK/se/PostalInfo.cpp b/AusRegEPPTK/se/PostalInfo.cpp new file mode 100644 index 0000000..c3b16a3 --- /dev/null +++ b/AusRegEPPTK/se/PostalInfo.cpp @@ -0,0 +1,69 @@ +#include "se/PostalInfo.hpp" +#include "xml/XMLHelper.hpp" +#include "xml/XMLWriter.hpp" + +using namespace std; + +PostalInfo::PostalInfo(const PostalInfoType* type, + const string &name, + const string &city, + const string &countryCode) + : type(type->toString()), name(name), city(city), cc(countryCode) +{ } + +PostalInfo::PostalInfo (const PostalInfoType *type, + const string &name, + const string &org, + const vector &street, + const string &city, + const string &stateProv, + const string &postcode, + const string &countryCode) + : type(type->toString()), name(name), org(org), street(street), + city(city), sp(stateProv), pc(postcode), cc(countryCode) +{ } + +DOMElement* PostalInfo::appendToElement(XMLWriter *xmlWriter, + DOMElement *parent) const +{ + DOMElement *postalInfo = + xmlWriter->appendChild (parent, + "postalInfo", + "type", + type); + + XMLHelper::setTextContent + (xmlWriter->appendChild(postalInfo, "name"), name); + + if (org != "") + XMLHelper::setTextContent + (xmlWriter->appendChild (postalInfo, "org"), org); + + DOMElement *addr = xmlWriter->appendChild (postalInfo, "addr"); + if (street.size() > 0) + { + vector::const_iterator p; + + for (p = street.begin(); p != street.end(); p++) + XMLHelper::setTextContent + (xmlWriter->appendChild (addr, "street"), *p); + } + // End if (street valid) + + XMLHelper::setTextContent + (xmlWriter->appendChild (addr, "city"), city); + + if (sp != "") + XMLHelper::setTextContent + (xmlWriter->appendChild (addr, "sp"), sp); + + if (pc != "") + XMLHelper::setTextContent + (xmlWriter->appendChild (addr, "pc"), pc); + + XMLHelper::setTextContent + (xmlWriter->appendChild (addr, "cc"), cc); + + return postalInfo; +} +// End PostalInfo::appendToElement() diff --git a/AusRegEPPTK/se/PostalInfo.hpp b/AusRegEPPTK/se/PostalInfo.hpp new file mode 100644 index 0000000..24d0da3 --- /dev/null +++ b/AusRegEPPTK/se/PostalInfo.hpp @@ -0,0 +1,79 @@ +#ifndef __POSTALINFO_HPP +#define __POSTALINFO_HPP + +#include "se/PostalInfoType.hpp" +#include "se/Appendable.hpp" + +#include + +#include +#include + +class XMLWriter; + +/** + * This class models postal information of contact objects. Instances may be + * used to either transform postal information or access attributes of postal + * information obtained by querying a contact object via a contact info EPP + * command, the response to which is implemented in the class + * ContactInfoResponse. + */ +class PostalInfo : public Appendable +{ +public: + virtual ~PostalInfo(){}; + + xercesc::DOMElement* appendToElement(XMLWriter* xmlWriter, + xercesc::DOMElement* parent) const; + + const std::string& getCountryCode() const { return cc; }; + const std::string& getCity() const { return city; }; + const std::string& getName() const { return name; }; + const std::string& getOrganisation() const { return org; }; + const std::string& getPostcode() const { return pc; }; + const std::string& getSp() const { return sp; }; + const std::vector& getStreet() const { return street; }; + const std::string& getType() const { return type; }; + +protected: + /** + * Minimal information required as per RFC3733 for creation of a contact. + */ + PostalInfo (const PostalInfoType* type, + const std::string& name, + const std::string& city, + const std::string& countryCode); + + /** + * All fields defined in RFC3733 for postalInfoType. + */ + PostalInfo (const PostalInfoType* type, + const std::string& name, + const std::string& org, + const std::vector& street, + const std::string& city, + const std::string& stateProv, + const std::string& postcode, + const std::string& countryCode); +private: + std::string type; + std::string name; + std::string org; + std::vector street; + std::string city; + std::string sp; + std::string pc; + std::string cc; + + void Init (const std::string& type, + const std::string& name, + const std::string& org, + const std::vector& street, + const std::string& city, + const std::string& stateProv, + const std::string& postcode, + const std::string& countryCode); +}; + + +#endif // __POSTALINFO_HPP diff --git a/AusRegEPPTK/se/PostalInfoType.cpp b/AusRegEPPTK/se/PostalInfoType.cpp new file mode 100644 index 0000000..63f8433 --- /dev/null +++ b/AusRegEPPTK/se/PostalInfoType.cpp @@ -0,0 +1,31 @@ +#include "se/PostalInfoType.hpp" + +// Static member initialisation. +std::vector PostalInfoType::values; + +const PostalInfoType* PostalInfoType::INTERNATIONAL() +{ + static const PostalInfoType type("int"); + return &type; +} + +const PostalInfoType* PostalInfoType::LOCAL() +{ + static const PostalInfoType type("loc"); + return &type; +} + +PostalInfoType::PostalInfoType(const std::string &type) + : EnumType (values, type) +{ } + +void PostalInfoType::init() +{ + INTERNATIONAL(); + LOCAL(); +} + +const PostalInfoType* PostalInfoType::value (const std::string &name) +{ + return (const PostalInfoType *)EnumType::value (name, values); +} diff --git a/AusRegEPPTK/se/PostalInfoType.hpp b/AusRegEPPTK/se/PostalInfoType.hpp new file mode 100644 index 0000000..bf580b0 --- /dev/null +++ b/AusRegEPPTK/se/PostalInfoType.hpp @@ -0,0 +1,28 @@ +#ifndef __POSTALINFOTYPE_HPP +#define __POSTALINFOTYPE_HPP + +#include "se/EnumType.hpp" + +/** + * Enumeration of PostalInfo types supported by EPP. The only difference + * between the two types is the allowed character encoding; international + * postal info is restricted to US ASCII, whereas local postal info element + * content may be represented in unrestricted UTF8. + */ +class PostalInfoType : public EnumType +{ +public: + PostalInfoType(const std::string &type); + + static const PostalInfoType* value(const std::string &name); + + static const PostalInfoType* INTERNATIONAL(); + static const PostalInfoType* LOCAL(); + + static void init(); + +private: + static std::vector values; +}; + +#endif // __POSTALINFOTYPE_HPP diff --git a/AusRegEPPTK/se/ProtocolExtensionCommand.cpp b/AusRegEPPTK/se/ProtocolExtensionCommand.cpp new file mode 100644 index 0000000..5b7a0a9 --- /dev/null +++ b/AusRegEPPTK/se/ProtocolExtensionCommand.cpp @@ -0,0 +1,55 @@ +#include "common/ErrorPkg.hpp" +#include "se/CLTRID.hpp" +#include "se/IllegalArgException.hpp" +#include "se/ProtocolExtensionCommand.hpp" +#include "xml/XMLHelper.hpp" + +ProtocolExtensionCommand::ProtocolExtensionCommand( + const CommandType* commandType, + const ObjectType* objectType, + const std::string& ident, + const Extension& ext) : SendSE(), + cmdType(commandType), + objType(objectType), + extension(ext) +{ + if (commandType == NULL) + { + throw IllegalArgException( + ErrorPkg::getMessage("se.command.type.missing")); + } + cmdType = commandType; + + command = xmlWriter->appendChild( + xmlWriter->appendChild( + xmlWriter->getRoot(), + "extension"), + "command", + extension.getURI()); + + command->setAttribute(XStr("xsi:schemaLocation").str(), + XStr(extension.getSchemaLocation()).str()); + + cmdElement = xmlWriter->appendChild(command, cmdType->getCommandName()); + + objElement = xmlWriter->appendChild(cmdElement, + commandType->getCommandName(), + objectType->getURI()); + objElement->setAttribute( + XStr("xsi:schemaLocation").str(), + XStr(objType->getSchemaLocation()).str()); + + DOMElement* element = xmlWriter->appendChild( + objElement, objectType->getIdentType()); + XMLHelper::setTextContent(element, ident); +} + +std::string ProtocolExtensionCommand::toXMLImpl() +{ + XMLHelper::setTextContent( + xmlWriter->appendChild(command, "clTRID"), + CLTRID::nextVal()); + + return xmlWriter->toXML(); +} + diff --git a/AusRegEPPTK/se/ProtocolExtensionCommand.hpp b/AusRegEPPTK/se/ProtocolExtensionCommand.hpp new file mode 100644 index 0000000..2a01325 --- /dev/null +++ b/AusRegEPPTK/se/ProtocolExtensionCommand.hpp @@ -0,0 +1,44 @@ +#ifndef __PROTOCOLEXTENSIONCOMMAND_HPP +#define __PROTOCOLEXTENSIONCOMMAND_HPP + +#include "se/SendSE.hpp" +#include "se/CommandType.hpp" +#include "se/ObjectType.hpp" +#include "se/Extension.hpp" +#include "xml/XStr.hpp" + +#include + +/** + * Base class for AusRegistry protocol extension commands. Instances of this + * class are responsible for building the part of the XML DOM tree common to + * all arext-1.0 protocol extension commands. + */ +class ProtocolExtensionCommand : public SendSE +{ +public: + ProtocolExtensionCommand( + const CommandType* commandType, + const ObjectType* objectType, + const std::string& ident, + const Extension& ext); + + // We can not use the xmlWriter API until the base class is + // constructed, so we disable the default command element + // creation in the base class initialised for Command and do + // our own construction here. + +protected: + DOMElement *command; + DOMElement *cmdElement; + DOMElement *objElement; + const CommandType *cmdType; + const ObjectType *objType; + const Extension& extension; + +private: + virtual std::string toXMLImpl(); +}; + +#endif // __PROTOCOLEXTENSIONCOMMAND_HPP + diff --git a/AusRegEPPTK/se/ReceiveSE.cpp b/AusRegEPPTK/se/ReceiveSE.cpp new file mode 100644 index 0000000..1600e89 --- /dev/null +++ b/AusRegEPPTK/se/ReceiveSE.cpp @@ -0,0 +1,24 @@ +#include "se/ReceiveSE.hpp" + +#include "common/StringUtils.hpp" + +Logger* ReceiveSE::maintLogger; +Logger* ReceiveSE::supportLogger; +Logger* ReceiveSE::userLogger; +Logger* ReceiveSE::debugLogger; + +void ReceiveSE::init() +{ + std::string pname = "com.ausregistry.cpptoolkit.se"; + maintLogger = Logger::getLogger(pname + ".maint"); + supportLogger = Logger::getLogger(pname + ".support"); + userLogger = Logger::getLogger(pname + ".user"); + debugLogger = Logger::getLogger(pname + ".debug"); +} + +std::string ReceiveSE::replaceIndex (const std::string & inputExpr, int index) +{ + return StringUtils::replaceAll (inputExpr, + "IDX", + StringUtils::makeString(index)); +} diff --git a/AusRegEPPTK/se/ReceiveSE.hpp b/AusRegEPPTK/se/ReceiveSE.hpp new file mode 100644 index 0000000..2325031 --- /dev/null +++ b/AusRegEPPTK/se/ReceiveSE.hpp @@ -0,0 +1,37 @@ +#ifndef __RECEIVESE_HPP +#define __RECEIVESE_HPP + +#include "xml/XMLDocument.hpp" +#include "common/Logger.hpp" + +#include + +/** + * Handles basic processing of all EPP packets received by the client. Parsing + * of the received XML document is the only responsibility of this class. + */ +class ReceiveSE +{ +public: + const std::string& toXML() const { return xml; }; + virtual ~ReceiveSE(){}; + + /** + * Set attribute values according to the given XML document. + * @throws ParsingException + */ + virtual void fromXML(XMLDocument *xmlDoc) = 0; + + static void init(); +protected: + static Logger* maintLogger; + static Logger* supportLogger; + static Logger* userLogger; + static Logger* debugLogger; + + ReceiveSE() { }; + std::string xml; + static std::string replaceIndex(const std::string &inputExpr, int index); +}; + +#endif // __RECEIVESE_HPP diff --git a/AusRegEPPTK/se/RegistrantObjectType.cpp b/AusRegEPPTK/se/RegistrantObjectType.cpp new file mode 100644 index 0000000..c8e8efe --- /dev/null +++ b/AusRegEPPTK/se/RegistrantObjectType.cpp @@ -0,0 +1,25 @@ +#include "RegistrantObjectType.hpp" + +#include + +const std::string& RegistrantObjectType::getName() const { + static const std::string name = "registrant"; + return name; +} + +const std::string& RegistrantObjectType::getURI() const { + static const std::string uri = "urn:X-ar:params:xml:ns:registrant-1.0"; + return uri; +} + +const std::string& RegistrantObjectType::getSchemaLocation() const { + static const std::string schemaLocation = + "urn:X-ar:params:xml:ns:registrant-1.0 registrant-1.0.xsd"; + return schemaLocation; +} + +const std::string& RegistrantObjectType::getIdentType() const { + static const std::string ident = "name"; + return ident; +} + diff --git a/AusRegEPPTK/se/RegistrantObjectType.hpp b/AusRegEPPTK/se/RegistrantObjectType.hpp new file mode 100644 index 0000000..335d134 --- /dev/null +++ b/AusRegEPPTK/se/RegistrantObjectType.hpp @@ -0,0 +1,17 @@ +#ifndef REGISTRANT_OBJECT_TYPE +#define REGISTRANT_OBJECT_TYPE + +#include "ObjectType.hpp" + +#include + +class RegistrantObjectType : public ObjectType { +public: + virtual const std::string& getName() const; + virtual const std::string& getURI() const; + virtual const std::string& getSchemaLocation() const; + virtual const std::string& getIdentType() const; +}; + +#endif // REGISTRANT_OBJECT_TYPE + diff --git a/AusRegEPPTK/se/RegistrantTransferCommandType.cpp b/AusRegEPPTK/se/RegistrantTransferCommandType.cpp new file mode 100644 index 0000000..a1f82dc --- /dev/null +++ b/AusRegEPPTK/se/RegistrantTransferCommandType.cpp @@ -0,0 +1,4 @@ +#include "se/RegistrantTransferCommandType.hpp" + +const std::string RegistrantTransferCommandType::cmdName("registrantTransfer"); + diff --git a/AusRegEPPTK/se/RegistrantTransferCommandType.hpp b/AusRegEPPTK/se/RegistrantTransferCommandType.hpp new file mode 100644 index 0000000..dd4bf96 --- /dev/null +++ b/AusRegEPPTK/se/RegistrantTransferCommandType.hpp @@ -0,0 +1,19 @@ +#ifndef REGISTRANT_TRANSFER_COMMAND_TYPE +#define REGISTRANT_TRANSFER_COMMAND_TYPE + +#include "se/CommandType.hpp" +#include + +class RegistrantTransferCommandType : public CommandType +{ + public: + RegistrantTransferCommandType() : CommandType(getCommandName()) {}; + std::string getCommandName() const { return cmdName; }; + std::string toString() const { return cmdName; }; + + private: + static const std::string cmdName; +}; + +#endif /* REGISTRANT_TRANSFER_COMMAND_TYPE */ + diff --git a/AusRegEPPTK/se/Response.cpp b/AusRegEPPTK/se/Response.cpp new file mode 100644 index 0000000..ae35c1e --- /dev/null +++ b/AusRegEPPTK/se/Response.cpp @@ -0,0 +1,174 @@ +#include "se/Response.hpp" +#include "se/EPPDateFormatter.hpp" +#include "se/ResponseExtension.hpp" +#include "common/StringUtils.hpp" +#include "common/Constants.hpp" +#include "common/ErrorPkg.hpp" + +const std::string Response::RESULT_COUNT_EXPR() +{ + return "count(" + Response::RESPONSE_EXPR() + "/e:result)"; +} + +const std::string Response::RESULT_EXPR() +{ + return Response::RESPONSE_EXPR() + "/e:result[IDX]"; +} + +const std::string Response::RESULT_CODE_EXPR() +{ + return "/@code"; +} + +const std::string Response::RESULT_MSG_EXPR() +{ + return "/e:msg"; +} + +const std::string Response::RESULT_VALUE_EXPR() +{ + return "/e:value"; +} + +const std::string Response::RESULT_XVALUE_EXPR() +{ + return "/e:extValue/e:value"; +} + +const std::string Response::RESULT_REASON_EXPR() +{ + return "/e:result"; +} + +const std::string Response::MSGQ_COUNT_EXPR() +{ + return RESPONSE_EXPR() + "/e:msgQ/@count"; +} + +const std::string Response::MSGQ_ID_EXPR() +{ + return RESPONSE_EXPR() + "/e:msgQ/@id"; +} + +const std::string Response::MSGQ_QDATE_EXPR() +{ + return RESPONSE_EXPR() + "/e:msgQ/e:qDate/text()"; +} + +const std::string Response::MSGQ_MSG_EXPR() +{ + return RESPONSE_EXPR() + "/e:msgQ/e:msg/text()"; +} + +const std::string Response::MSGQ_MSG_LANG_EXPR() +{ + return RESPONSE_EXPR() + "/e:msgQ/e:msg/@lang"; +} + +const std::string Response::CLTRID_EXPR() +{ + return RESPONSE_EXPR() + "/e:trID/e:clTRID/text()"; +} + +const std::string Response::SVTRID_EXPR() +{ + return RESPONSE_EXPR() + "/e:trID/e:svTRID/text()"; +} + + +const std::string Response::RESPONSE_EXPR() +{ + static std::string expr = "/e:epp/e:response"; + return expr; +} + + +Response::Response() + : msgCount(0), msgLang(Constants::DEFAULT_LANG) +{ } + +void Response::registerExtension(ResponseExtension * const extension) +{ + extensions.push_back(extension); +} + +void Response::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + debugLogger->LOG_FINEST("enter"); + try + { + int resultCount = xmlDoc->getNodeCount(RESULT_COUNT_EXPR()); + resultArray.clear(); + + for (int i = 0; i < resultCount; i++) + { + std::string qry = ReceiveSE::replaceIndex(RESULT_EXPR(), i + 1); + std::string code = xmlDoc->getNodeValue(qry + RESULT_CODE_EXPR()); + std::string msg = xmlDoc->getNodeValue(qry + RESULT_MSG_EXPR()); + const XalanNode *value = xmlDoc->getElement(qry + RESULT_VALUE_EXPR()); + std::string xvalue = xmlDoc->getNodeValue(qry + RESULT_XVALUE_EXPR()); + std::string reason = xmlDoc->getNodeValue(qry + RESULT_REASON_EXPR()); + + resultArray.push_back(Result(atoi(code.c_str()), msg, value, xvalue, reason)); + debugLogger->LOG_FINEST(resultArray[i].toString()); + } + + std::string msgQcount = xmlDoc->getNodeValue(MSGQ_COUNT_EXPR()); + if (msgQcount != "") + msgCount = atoi(msgQcount.c_str()); + + std::string msgQid = xmlDoc->getNodeValue (MSGQ_ID_EXPR()); + + if (msgQid != "") + msgID = msgQid.c_str(); + + std::string msgQqDate = xmlDoc->getNodeValue(MSGQ_QDATE_EXPR()); + if (msgQqDate != "") + qDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(msgQqDate)); + + msg = xmlDoc->getNodeValue(MSGQ_MSG_EXPR()); + msgLang = xmlDoc->getNodeValue (MSGQ_MSG_LANG_EXPR()); + + clTRID = xmlDoc->getNodeValue(CLTRID_EXPR()); + svTRID = xmlDoc->getNodeValue(SVTRID_EXPR()); + + std::list::const_iterator extensionsIterator; + for (extensionsIterator = extensions.begin(); + extensionsIterator != extensions.end(); + extensionsIterator++) + { + (*extensionsIterator)->fromXML(xmlDoc); + } + } + catch (XPathExpressionException &e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } + + debugLogger->LOG_FINEST("exit"); +} +// End Response::fromXML() + + +std::string Response::toString (void) const +{ + std::string retval = "(msgcount = "; + + retval += StringUtils::makeString(getMsgCount()) + ")" + + (getMsgID().size() > 0 ? "(msgID = " +getMsgID() + ")" : "" ) + + (getMessageEnqueueDate() != NULL ? + "(qDate = " + EPPDateFormatter::toXSDateTime(*getMessageEnqueueDate()) + ")" + : "") + + "(clTRID = " + getCLTRID() + ")" + + "(svTRID = " + getSVTRID() + ")"; + + std::vector::const_iterator p; + + for (p = resultArray.begin(); p != resultArray.end(); p++) + retval += "\n" + p->toString(); + + return retval; +} diff --git a/AusRegEPPTK/se/Response.hpp b/AusRegEPPTK/se/Response.hpp new file mode 100644 index 0000000..8a29af7 --- /dev/null +++ b/AusRegEPPTK/se/Response.hpp @@ -0,0 +1,80 @@ +#ifndef __RESPONSE_HPP +#define __RESPONSE_HPP + +#include +#include + +#include "se/ReceiveSE.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/Result.hpp" +#include "xml/ParsingException.hpp" + +class ResponseExtension; + +/** + * Use this to retrieve the values of attributes common to all EPP response + * service elements. Unless there is a specific subclass dedicated to handling + * a type of response, an instance of this class should be used to handle the + * response. The commands which result in a response that should be handled by + * this class are LoginCommand, LogoutCommand, subclasses of DeleteCommand and + * subclasses of UpdateCommand. + * + * @see LoginCommand + * @see LogoutCommand + * @see DeleteCommand + * @see UpdateCommand + */ +class Response : public ReceiveSE +{ +public: + Response(); + + const std::vector& getResults() const { return resultArray; }; + const XMLGregorianCalendar* getMessageEnqueueDate() const { return qDate.get(); }; + + const std::string& getCLTRID() const { return clTRID; }; + const std::string& getSVTRID() const { return svTRID; }; + const std::string& getMessage() const { return msg; }; + const std::string& getMessageLanguage() const { return msgLang; }; + int getMsgCount() const { return msgCount; }; + + /// @returns The msgQ id attribute, or a zero length string if it was not + /// present. + std::string getMsgID() const { return msgID; }; + + void registerExtension(ResponseExtension * const extension); + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + std::string toString() const; + +protected: + static const std::string RESPONSE_EXPR(); + static const std::string RESULT_COUNT_EXPR(); + static const std::string RESULT_EXPR(); + static const std::string RESULT_CODE_EXPR(); + static const std::string RESULT_MSG_EXPR(); + static const std::string RESULT_VALUE_EXPR(); + static const std::string RESULT_XVALUE_EXPR(); + static const std::string RESULT_REASON_EXPR(); + static const std::string MSGQ_COUNT_EXPR(); + static const std::string MSGQ_ID_EXPR(); + static const std::string MSGQ_QDATE_EXPR(); + static const std::string MSGQ_MSG_EXPR(); + static const std::string MSGQ_MSG_LANG_EXPR(); + static const std::string CLTRID_EXPR(); + static const std::string SVTRID_EXPR(); + + std::vector resultArray; + std::list extensions; + +private: + std::string clTRID, svTRID; + int msgCount; + std::string msgID; + std::auto_ptr qDate; + std::string msg; + std::string msgLang; +}; + + +#endif // __RESPONSE_HPP diff --git a/AusRegEPPTK/se/ResponseError.hpp b/AusRegEPPTK/se/ResponseError.hpp new file mode 100644 index 0000000..9c7b67c --- /dev/null +++ b/AusRegEPPTK/se/ResponseError.hpp @@ -0,0 +1,11 @@ +#ifndef __RESPONSEERROR_HPP +#define __RESPONSEERROR_HPP + +#include "se/Error.hpp" + +class ResponseError : public Error +{ +public: + ResponseError (const std::string & msg) : Error(msg) {}; +}; +#endif // __RESPONSEERROR_HPP diff --git a/AusRegEPPTK/se/ResponseExtension.cpp b/AusRegEPPTK/se/ResponseExtension.cpp new file mode 100644 index 0000000..125dd16 --- /dev/null +++ b/AusRegEPPTK/se/ResponseExtension.cpp @@ -0,0 +1,7 @@ +#include "se/Response.hpp" +#include "se/ResponseExtension.hpp" + +const std::string ResponseExtension::EXTENSION_EXPR() +{ + return "/e:epp/e:response/e:extension"; +} diff --git a/AusRegEPPTK/se/ResponseExtension.hpp b/AusRegEPPTK/se/ResponseExtension.hpp new file mode 100644 index 0000000..ef0eb8c --- /dev/null +++ b/AusRegEPPTK/se/ResponseExtension.hpp @@ -0,0 +1,36 @@ +#ifndef RESPONSEEXTENSION_H_ +#define RESPONSEEXTENSION_H_ + +#include + +#include + +class XMLDocument; + +/** + * Extension of the response mapping of the EPP response. Instances of this + * class provide an interface to access all of the information available through + * EPP response extension. This relies on the instance first being initialised + * by a suitable EPP response using the method fromXML. For flexibility, this + * implementation extracts the data from the response using XPath queries, the + * expressions for which are defined statically. + */ +class ResponseExtension : public ReceiveSE +{ + public: + /** + * Indicates whether fromXML() completed successfully and the extension was + * successfully initialised from the EPP response. + * + * @return true if the extension has been initialised, else false. + */ + virtual bool isInitialised() const = 0; + + protected: + /** + * XPath expression to locate the extension element from the EPP response. + */ + static const std::string EXTENSION_EXPR(); +}; + +#endif /* RESPONSEEXTENSION_H_ */ diff --git a/AusRegEPPTK/se/Result.cpp b/AusRegEPPTK/se/Result.cpp new file mode 100644 index 0000000..a3b5b4d --- /dev/null +++ b/AusRegEPPTK/se/Result.cpp @@ -0,0 +1,32 @@ +#include "se/Result.hpp" +#include "common/StringUtils.hpp" + +Result::Result (int code, + const std::string& msg, + const XalanNode* value, + const std::string& valueText, + const std::string& valueReason, + const std::string& msgLang) + : resultCode(code), + resultMessage(msg), + resultMessageLang(msgLang), + resultValue(value), + resultExtvalueValue(valueText), + resultExtvalueReason(valueReason) +{ } + +Result::~Result() +{ } + + +std::string Result::toString() const +{ + std::string retval ("(result = (code = "); + + retval += StringUtils::makeString(resultCode) + + ")(msg = " + + resultMessage + + "))"; + + return retval; +} diff --git a/AusRegEPPTK/se/Result.hpp b/AusRegEPPTK/se/Result.hpp new file mode 100644 index 0000000..3265d1d --- /dev/null +++ b/AusRegEPPTK/se/Result.hpp @@ -0,0 +1,122 @@ +#ifndef __RESULT_HPP +#define __RESULT_HPP + +#include "string" +//#include +#include + +#ifndef SWIG +XALAN_USING_XALAN(XalanNode) +#endif + +/** + * This class models the result element of EPP responses. From RFC 3730: + * "One or more }elements [...] document the success or failure + * of command execution. If the command was processed successfully, only one + * element MUST be returned. If the command was not processed + * successfully, multiple elements MAY be returned to document + * failure conditions. Each element contains the following + * attribute and child elements. + * + * See getX method descriptions for a description of the elements of a Result. + * Note that any DOM Node fields will not be serialized. + * @note A Result instance uses nodes (cf. XalanNode*) from a parsed response object, but does + * not assume ownership. Therefore, these other objects life time must outlast + * the Result object. + */ +class Result +{ +public: + + /// @TODO SWIG/Perl workaround - figure out why SWIG wants an empty constructor. + Result () {} + + /** + * @note A Result instance uses nodes (cf. XalanNode*) from a parsed response object, but does + * not assume ownership. Therefore, these other objects life time must outlast + * the Result object. + */ + Result (int code, + const std::string &msg, + const XalanNode *value, + const std::string &valueText, + const std::string &valueReason, + const std::string &msgLang = ""); + + ~Result(); + + /** + * The code attribute of a result. From RFC 3730: + * A "code" attribute whose value is a four-digit, decimal number that + * describes the success or failure of the command. + */ + int getResultCode() const { return resultCode; }; + + /** + * The msg element of a result. From RFC 3730: + *
+ * A element containing a human-readable description of the + * response code. + *
+ */ + const std::string& getResultMessage() const { return resultMessage; }; + /** + * The lang attribute of the msg element of a result. From RFC 3730: + *
+ * The language of the response is identified via an OPTIONAL "lang" + * attribute. If not specified, the default attribute value MUST be "en" + * (English). + *
+ */ + const std::string& getResultMessageLanguage() const { return resultMessageLang; }; + /** + * The value child elements of the extValue element of a result. From RFC + * 3730: + * "Zero or more OPTIONAL elements that can be used to + * provide additional error diagnostic information, including:
+ * - A element that identifies a client-provided element + * (including XML tag and value) that caused a server error condition." + */ + const std::string& getResultExtValueValue() const { return resultExtvalueValue; }; + /** + * The reason child elements of the extValue element of a result. From RFC + * 3730: "Zero or more OPTIONAL elements that can be used to + * provide additional error diagnostic information, including:
+ * - A element containing a human-readable message that + * describes the reason for the error." + * @todo provide interface to get language of each reason. + */ + const std::string& getResultExtValueReason() const { return resultExtvalueReason; }; + + /** + * The value elements of a result. From RFC 3730: + *
+ * Zero or more OPTIONAL elements that identify a + * client-provided element (including XML tag and value) that caused a + * server error condition. + *
+ */ + const xalanc::XalanNode* getResultValue() { return resultValue; }; + + /** + * Whether the associated command succeeded or not. This can be used to + * reduce the amount of result checking, since if this returns true, then + * no further results should be available for the associated response. + */ + bool succeeded() const { return ((1000 <= resultCode) && (resultCode < 2000)); }; + + std::string toString() const; + +private: + int resultCode; + std::string resultMessage; + std::string resultMessageLang; + + // non-owning pointer. + const XalanNode* resultValue; + + std::string resultExtvalueValue; + std::string resultExtvalueReason; +}; + +#endif // __RESULT_HPP diff --git a/AusRegEPPTK/se/ResultCode.hpp b/AusRegEPPTK/se/ResultCode.hpp new file mode 100644 index 0000000..6004fec --- /dev/null +++ b/AusRegEPPTK/se/ResultCode.hpp @@ -0,0 +1,49 @@ +#ifndef __RESULTCODE_HPP +#define __RESULTCODE_HPP + +/** + * This class defines a set of constants mapped to the EPP result codes. These + * can be used to provide symbolic names for handling of result codes, rather + * than magic numbers. + */ +class ResultCode +{ +public: + static const int SUCCESS = 1000; + static const int SUCCESS_ACT_PEND = 1001; + static const int SUCCESS_NO_MSG = 1300; + static const int SUCCESS_ACK = 1301; + static const int SUCCESS_LOGOUT = 1500; + static const int CMD_UNKNOWN = 2000; + static const int CMD_SYNTAX_ERR = 2001; + static const int CMD_USE_ERR = 2002; + static const int PARAM_MISSING = 2003; + static const int PARAM_VAL_RANGE_ERR = 2004; + static const int PARAM_VAL_SYNTAX_ERR = 2005; + static const int UNIMPL_PROTO_VERS = 2100; + static const int UNIMPL_CMD = 2101; + static const int UNIMPL_OPT = 2102; + static const int UNIMPL_EXT = 2103; + static const int BILLING_FAILURE = 2104; + static const int OBJ_NOT_ELIG_RENEW = 2105; + static const int OBJ_NOT_ELIG_TXFR = 2106; + static const int AUTHENT_ERR = 2200; + static const int AUTHRZN_ERR = 2201; + static const int INVALID_AUTH_INFO = 2202; + static const int OBJ_PEND_TXFR = 2300; + static const int OBJ_NOT_PEND_TXFR = 2301; + static const int YX_OBJ = 2302; + static const int NX_OBJ = 2303; + static const int OBJ_STATUS_PROHIB_OP = 2304; + static const int OBJ_ASSOC_PROHIB_OP = 2305; + static const int PARAM_VAL_POL_ERR = 2306; + static const int UNIMPL_OBJ_SVC = 2307; + static const int DATA_MGMT_POL_VIOLATION = 2308; + static const int CMD_FAILED = 2400; + static const int CMD_FAILED_CLOSING = 2500; + static const int AUTHENT_ERROR_CLOSING = 2501; + static const int SESS_LIM_EXCEEDED_CLOSING = 2502; + +}; + +#endif // __RESULTCODE_HPP diff --git a/AusRegEPPTK/se/SendSE.cpp b/AusRegEPPTK/se/SendSE.cpp new file mode 100644 index 0000000..adeafc4 --- /dev/null +++ b/AusRegEPPTK/se/SendSE.cpp @@ -0,0 +1,53 @@ +#include "se/SendSE.hpp" + +using namespace std; + +Logger* SendSE::userLogger; + +string& SendSE::eppns() +{ + static string expr = "urn:ietf:params:xml:ns:epp-1.0"; + return expr; +} + +string& SendSE::xsi() +{ + static string expr = "http://www.w3.org/2001/XMLSchema-instance"; + return expr; +} + +string& SendSE::schemaLocation() +{ + static string expr = "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"; + return expr; +} + +const string SendSE::XML_VERSION() +{ + static const string ver = "1.0"; + return ver; +} + +const string SendSE::XML_ENCODING() +{ + static const string enc = "UTF-8"; + return enc; +} + +SendSE::SendSE(const string& xmlVersion, + const string& xmlEncoding, + bool xmlStandalone) +{ + xmlWriter = new EPPWriter(xmlVersion, xmlEncoding, xmlStandalone, + eppns(), xsi(), schemaLocation()); +} + +SendSE::~SendSE() +{ + delete xmlWriter; +} + +void SendSE::init () +{ + userLogger = Logger::getLogger("com.ausregistry.cpptoolkit.se.user"); +} diff --git a/AusRegEPPTK/se/SendSE.hpp b/AusRegEPPTK/se/SendSE.hpp new file mode 100644 index 0000000..0cca931 --- /dev/null +++ b/AusRegEPPTK/se/SendSE.hpp @@ -0,0 +1,47 @@ +#ifndef __SENDSE_HPP +#define __SENDSE_HPP + +#include "xml/EPPWriter.hpp" +#include "common/Logger.hpp" + +#include +#include + +/** + * The base class for EPP command service elements that provides + * the basic XML serialisation protocol. + */ +class SendSE +{ +public: + SendSE (const std::string &xmlVersion = XML_VERSION(), + const std::string &xmlEncoding = XML_ENCODING(), + bool xmlStandalone = XML_STANDALONE); + virtual ~SendSE(); + + virtual std::string toXML() + { + if (xml.size() == 0) xml = toXMLImpl(); + return xml; + } + + static void init(); +protected: + static Logger *userLogger; + + std::string xml; + XMLWriter* xmlWriter; + + virtual std::string toXMLImpl() = 0; + + static const std::string XML_VERSION(); + static const std::string XML_ENCODING(); + static const bool XML_STANDALONE = false; + + static std::string& eppns(); + static std::string& xsi(); + static std::string& schemaLocation(); +}; + +#endif // __SENDSE_HPP + diff --git a/AusRegEPPTK/se/StandardCommandType.cpp b/AusRegEPPTK/se/StandardCommandType.cpp new file mode 100644 index 0000000..fa8e2ee --- /dev/null +++ b/AusRegEPPTK/se/StandardCommandType.cpp @@ -0,0 +1,96 @@ +#include "se/StandardCommandType.hpp" + +using namespace std; + +vector& StandardCommandType::values() +{ + static vector v; + return v; +} + +const StandardCommandType* StandardCommandType::LOGIN() +{ + static const StandardCommandType expr("login"); + return &expr; +} + +const StandardCommandType* StandardCommandType::LOGOUT() +{ + static const StandardCommandType expr("logout"); + return &expr; +} + +const StandardCommandType* StandardCommandType::POLL() +{ + static const StandardCommandType expr("poll"); + return &expr; +} + +const StandardCommandType* StandardCommandType::CHECK() +{ + static const StandardCommandType expr("check"); + return &expr; +} + +const StandardCommandType* StandardCommandType::INFO() +{ + static const StandardCommandType expr("info"); + return &expr; +} + +const StandardCommandType* StandardCommandType::CREATE() +{ + static const StandardCommandType expr("create"); + return &expr; +} + +const StandardCommandType* StandardCommandType::DELETE() +{ + static const StandardCommandType expr("delete"); + return &expr; +} + +const StandardCommandType* StandardCommandType::UPDATE() +{ + static const StandardCommandType expr("update"); + return &expr; +} + +const StandardCommandType* StandardCommandType::TRANSFER() +{ + static const StandardCommandType expr("transfer"); + return &expr; +} + +const StandardCommandType* StandardCommandType::RENEW() +{ + static const StandardCommandType expr("renew"); + return &expr; +} + + +StandardCommandType::StandardCommandType(const string &name) + : EnumType (values(), name), + CommandType (getCommandName()) +{ +} + +const StandardCommandType* StandardCommandType::value + (const string &name) +{ + return (const StandardCommandType *)EnumType::value (name, values()); +} + +void StandardCommandType::init() +{ + LOGIN(); + LOGOUT(); + POLL(); + CHECK(); + INFO(); + CREATE(); + DELETE(); + UPDATE(); + TRANSFER(); + RENEW(); +} diff --git a/AusRegEPPTK/se/StandardCommandType.hpp b/AusRegEPPTK/se/StandardCommandType.hpp new file mode 100644 index 0000000..1141e39 --- /dev/null +++ b/AusRegEPPTK/se/StandardCommandType.hpp @@ -0,0 +1,34 @@ +#ifndef __STANDARDCOMMANDTYPE_HPP +#define __STANDARDCOMMANDTYPE_HPP + +#include "se/EnumType.hpp" +#include "se/CommandType.hpp" + +class StandardCommandType : public EnumType, public CommandType +{ +public: + StandardCommandType(const std::string &name); + + virtual std::string getCommandName() const { return getFirst(); } + virtual std::string toString() const { return getFirst(); } + + static const StandardCommandType* value (const std::string &name); + + static const StandardCommandType* LOGIN(); + static const StandardCommandType* LOGOUT(); + static const StandardCommandType* POLL(); + static const StandardCommandType* CHECK(); + static const StandardCommandType* INFO(); + static const StandardCommandType* CREATE(); + static const StandardCommandType* DELETE(); + static const StandardCommandType* UPDATE(); + static const StandardCommandType* TRANSFER(); + static const StandardCommandType* RENEW(); + + static void init(); + +private: + static std::vector& values(); +}; + +#endif // __STANDARDCOMMANDTYPE_HPP diff --git a/AusRegEPPTK/se/StandardObjectType.cpp b/AusRegEPPTK/se/StandardObjectType.cpp new file mode 100644 index 0000000..6712cc5 --- /dev/null +++ b/AusRegEPPTK/se/StandardObjectType.cpp @@ -0,0 +1,69 @@ +#include "se/StandardObjectType.hpp" + +using namespace std; + +vector StandardObjectType::values; +vector StandardObjectType::stdURIs; + +const StandardObjectType* StandardObjectType::DOMAIN() +{ + static StandardObjectType obj( + "domain", + "urn:ietf:params:xml:ns:domain-1.0", + "urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd", + "name"); + return &obj; +} + +const StandardObjectType* StandardObjectType::HOST() +{ + static StandardObjectType obj( + "host", + "urn:ietf:params:xml:ns:host-1.0", + "urn:ietf:params:xml:ns:host-1.0 host-1.0.xsd", + "name"); + return &obj; +} + +const StandardObjectType* StandardObjectType::CONTACT() +{ + static StandardObjectType obj( + "contact", + "urn:ietf:params:xml:ns:contact-1.0", + "urn:ietf:params:xml:ns:contact-1.0 contact-1.0.xsd", + "id"); + return &obj; +} + +StandardObjectType::StandardObjectType(const string& name, + const string& uri, + const string& schemaLocation, + const string& identType) + : EnumType(values, name, uri, schemaLocation, identType) +{ } + +const StandardObjectType* StandardObjectType::value(const string &name) +{ + return (const StandardObjectType *)EnumType::value (name, values); +} + + +const vector& StandardObjectType::getStandardURIs() +{ + if (stdURIs.size() == 0) + { + stdURIs.push_back(DOMAIN()->getURI()); + stdURIs.push_back(HOST()->getURI()); + stdURIs.push_back(CONTACT()->getURI()); + } + + return stdURIs; +} + +void StandardObjectType::init() +{ + getStandardURIs(); + DOMAIN(); + HOST(); + CONTACT(); +} diff --git a/AusRegEPPTK/se/StandardObjectType.hpp b/AusRegEPPTK/se/StandardObjectType.hpp new file mode 100644 index 0000000..9104ee5 --- /dev/null +++ b/AusRegEPPTK/se/StandardObjectType.hpp @@ -0,0 +1,44 @@ +#ifndef __STANDARDOBJECTTYPE_HPP +#define __STANDARDOBJECTTYPE_HPP + +#include "se/EnumType.hpp" +#include "se/ObjectType.hpp" + +#include +#include + +#ifdef DOMAIN +#undef DOMAIN +#endif + + +class StandardObjectType : public ObjectType, public EnumType +{ +public: + StandardObjectType(const std::string& name, + const std::string& uri, + const std::string& schemaLocation, + const std::string& identType); + + const std::string& getName() const { return getFirst(); }; + const std::string& getURI() const { return getSecond(); }; + const std::string& getSchemaLocation() const { return getThird(); }; + const std::string& getIdentType() const { return getFourth(); }; + + static const std::vector& getStandardURIs(); + + static const StandardObjectType* value(const std::string &name); + + static const StandardObjectType* DOMAIN(); + static const StandardObjectType* HOST(); + static const StandardObjectType* CONTACT(); + + static void init(); + + +private: + static std::vector values; + static std::vector stdURIs; +}; + +#endif // __STANDARDOBJECTTYPE_HPP diff --git a/AusRegEPPTK/se/Status.hpp b/AusRegEPPTK/se/Status.hpp new file mode 100644 index 0000000..5d2a624 --- /dev/null +++ b/AusRegEPPTK/se/Status.hpp @@ -0,0 +1,43 @@ +#ifndef __STATUS_HPP +#define __STATUS_HPP + +#include "common/StringUtils.hpp" + +/** + * This class models EPP object statuses. Instances of this class can be used + * to update object statuses and are also returned by subclasses of + * InfoResponse to provide access to the attributes of status values of the + * queried object. + * + * @see UpdateCommand + * @see InfoResponse + */ +class Status +{ +public: + /// @TODO SWIG/Perl workaround - figure out why SWIG wants an empty constructor. + Status () {} + + Status (const std::string &status, + const std::string &rationale = "", + const std::string &lang = "") + : status(status), + rationale(rationale), + lang(lang) {}; + + const std::string& toString() const { return status; }; + const std::string& getRationale() const { return rationale; }; + const std::string& getLanguage() const { return lang; }; + + bool equals (Status *obj) const + { + return (obj->toString().compare(status) == 0) ? true : false; + }; + + int hashCode() const { return (int)StringUtils::hashCode(status); }; + +private: + std::string status, rationale, lang; +}; + +#endif // __STATUS_HPP diff --git a/AusRegEPPTK/se/SyncExtension.cpp b/AusRegEPPTK/se/SyncExtension.cpp new file mode 100644 index 0000000..ff48d6b --- /dev/null +++ b/AusRegEPPTK/se/SyncExtension.cpp @@ -0,0 +1,16 @@ +#include + +#include "se/SyncExtension.hpp" + +std::string& SyncExtension::getURI() const +{ + static std::string uri = "urn:X-ar:params:xml:ns:sync-1.0"; + return uri; +} + +std::string& SyncExtension::getSchemaLocation() const +{ + static std::string loc = "urn:X-ar:params:xml:ns:sync-1.0 sync-1.0.xsd"; + return loc; +} + diff --git a/AusRegEPPTK/se/SyncExtension.hpp b/AusRegEPPTK/se/SyncExtension.hpp new file mode 100644 index 0000000..61efe67 --- /dev/null +++ b/AusRegEPPTK/se/SyncExtension.hpp @@ -0,0 +1,31 @@ +#ifndef __SYNCEXTENSION_HPP +#define __SYNCEXTENSION_HPP + +#include + +#include "se/Extension.hpp" + +/** + * A bundled set of constants representing the Domain Expiry Synchronisation + * EPP extension schema. The namespace URI uniquely identifies the extension. + */ +class SyncExtension : public Extension +{ +public: + + virtual ~SyncExtension(void) { } + + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __SYNCEXTENSION_HPP + diff --git a/AusRegEPPTK/se/TransferCommand.cpp b/AusRegEPPTK/se/TransferCommand.cpp new file mode 100644 index 0000000..7034c61 --- /dev/null +++ b/AusRegEPPTK/se/TransferCommand.cpp @@ -0,0 +1,88 @@ +#include "se/TransferCommand.hpp" +#include "se/StandardCommandType.hpp" +#include "xml/XMLHelper.hpp" +#include "common/ErrorPkg.hpp" + + +TransferCommand::TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string& ident) + : ObjectCommand(StandardCommandType::TRANSFER(), objType, ident) +{ + Init(operation); +} + +TransferCommand::TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string &ident, + const std::string &pw) + : ObjectCommand(StandardCommandType::TRANSFER(), objType, ident) +{ + Init(operation); + appendPW (pw); +} + +TransferCommand::TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string &ident, + const Period &period, + const std::string &pw) + : ObjectCommand(StandardCommandType::TRANSFER(), objType, ident) +{ + Init (operation); + period.appendPeriod (xmlWriter, objElement); + appendPW (pw); +} + +TransferCommand::TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string& ident, + const std::string& roid, + const std::string& pw) + : ObjectCommand(StandardCommandType::TRANSFER(), objType, ident) +{ + Init(operation); + appendPW(pw, roid); +} + +TransferCommand::TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string& ident, + const Period& period, + const std::string& roid, + const std::string& pw) + : ObjectCommand(StandardCommandType::TRANSFER(), objType, ident) +{ + Init(operation); + period.appendPeriod(xmlWriter, objElement); + appendPW(pw, roid); +} + +void TransferCommand::appendPW(const std::string &pw, const std::string &roid) +{ + XMLHelper::setTextContent( + xmlWriter->appendChild( + xmlWriter->appendChild(objElement, "authInfo"), + "pw", + "roid", + roid), + pw); +} + +void TransferCommand::appendPW(const std::string &pw) +{ + XMLHelper::setTextContent( + xmlWriter->appendChild( + xmlWriter->appendChild(objElement, "authInfo"), "pw"), + pw); +} + +void TransferCommand::Init(const TransferOp* operation) +{ + if (operation == NULL) + { + throw IllegalArgException(ErrorPkg::getMessage("se.transfer.operation.missing")); + } + XMLHelper::setAttribute (cmdElement, + "op", operation->toString()); +} diff --git a/AusRegEPPTK/se/TransferCommand.hpp b/AusRegEPPTK/se/TransferCommand.hpp new file mode 100644 index 0000000..53408df --- /dev/null +++ b/AusRegEPPTK/se/TransferCommand.hpp @@ -0,0 +1,136 @@ +#ifndef __TRANSFER_COMMAND_HPP +#define __TRANSFER_COMMAND_HPP + +#include "se/ObjectCommand.hpp" +#include "se/ObjectType.hpp" +#include "se/Period.hpp" +#include "se/TransferOp.hpp" + +/** + * Representation of the EPP transfer command, as defined in RFC3730. + * Subclasses of this must specify the object to which the command is mapped, + * the type of transfer operation and specify the object-specific identifier of + * the object to create a transfer command for. + * + * @see TransferResponse + */ +class TransferCommand : public ObjectCommand +{ +public: + /** + * Create a transfer command of the specified operation type mapped to the + * specified object type for the identified object. + * + * @param objType The type of object to which the transfer command is to be + * mapped. + * + * @param operation The type of transfer operation to perform. + * + * @param ident An object type-specific label identifying the object + * subject to the transfer command. + */ + TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string &ident); + + /** + * Create a transfer command of the specified operation type mapped to the + * specified object type for the identified object. + * + * @param objType The type of object to which the transfer command is to be + * mapped. + * + * @param operation The type of transfer operation to perform. + * + * @param ident An object type-specific label identifying the object + * subject to the transfer command. + * + * @param pw The password of the object subject to the transfer command - + * also referred to as authInfo or authorisation information. + */ + TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string& ident, + const std::string& pw); + + /** + * Create a transfer command of the specified operation type mapped to the + * specified object type for the identified object. + * + * @param objType The type of object to which the transfer command is to be + * mapped. + * + * @param operation The type of transfer operation to perform. + * + * @param ident An object type-specific label identifying the object + * subject to the transfer command. + * + * @param period The validity period of the identified object should be + * extended by this duration upon successful completion of the transfer + * related to this command. + * + * @param pw The password of the object subject to the transfer command - + * also referred to as authInfo or authorisation information. + */ + TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string& ident, + const Period& period, + const std::string& pw); + + /** + * Create a transfer command of the specified operation type mapped to the + * specified object type for the identified object. + * + * @param objType The type of object to which the transfer command is to be + * mapped. + * + * @param operation The type of transfer operation to perform. + * + * @param ident An object type-specific label identifying the object + * subject to the transfer command. + * + * @param roid The Repository Object Identifier of an object related to the + * identified object subject to transfer which is considered a suitable + * proxy for authorising transfer commands. + * + * @param pw The password of the related object identified by roid. + */ + TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string& ident, + const std::string& roid, + const std::string& pw); + + /** + * Create a transfer command of the specified operation type mapped to the + * specified object type for the identified object. + * + * @param objType The type of object to which the transfer command is to be + * mapped. + * + * @param operation The type of transfer operation to perform. + * + * @param ident An object type-specific label identifying the object + * subject to the transfer command. + * + * @param period The validity period of the identified object should be + * extended by this duration upon successful completion of the transfer + * related to this command. + * + * @param pw The password of the object subject to the transfer command - + * also referred to as authInfo or authorisation information. + */ + TransferCommand (const ObjectType* objType, + const TransferOp* operation, + const std::string& ident, + const Period& period, + const std::string& roid, + const std::string& pw); +private: + void appendPW (const std::string &pw, const std::string &roid); + void appendPW (const std::string &pw); + void Init(const TransferOp* operation); +}; + +#endif // __TRANSFER_COMMAND_HPP diff --git a/AusRegEPPTK/se/TransferOp.cpp b/AusRegEPPTK/se/TransferOp.cpp new file mode 100644 index 0000000..b693635 --- /dev/null +++ b/AusRegEPPTK/se/TransferOp.cpp @@ -0,0 +1,53 @@ +#include "se/TransferOp.hpp" + +// Static member initialisation. +std::vector TransferOp::values; + +const TransferOp* TransferOp::QUERY() +{ + static TransferOp op("query"); + return &op; +} + +const TransferOp* TransferOp::REQUEST() +{ + static TransferOp op("request"); + return &op; +} + +const TransferOp* TransferOp::CANCEL() +{ + static TransferOp op("cancel"); + return &op; +} + +const TransferOp* TransferOp::APPROVE() +{ + static TransferOp op("approve"); + return &op; +} + +const TransferOp* TransferOp::REJECT() +{ + static TransferOp op("reject"); + return &op; +} + + +TransferOp::TransferOp (const std::string &op) + : EnumType (values, op) +{ } + +const TransferOp* TransferOp::value (const std::string &name) +{ + return (const TransferOp *)EnumType::value (name, values); +} + +void TransferOp::init() +{ + QUERY(); + REQUEST(); + CANCEL(); + APPROVE(); + REJECT(); +} diff --git a/AusRegEPPTK/se/TransferOp.hpp b/AusRegEPPTK/se/TransferOp.hpp new file mode 100644 index 0000000..7e2c83a --- /dev/null +++ b/AusRegEPPTK/se/TransferOp.hpp @@ -0,0 +1,31 @@ +#ifndef __TRANSFER_OP_HPP +#define __TRANSFER_OP_HPP + +#include "se/EnumType.hpp" + +#include +#include + +/** + * An enumeration of the transfer operation types defined for transfer commands + * in RFC 3730. + */ +class TransferOp : public EnumType +{ +public: + TransferOp (const std::string &operation); + + static const TransferOp* QUERY(); + static const TransferOp* REQUEST(); + static const TransferOp* CANCEL(); + static const TransferOp* APPROVE(); + static const TransferOp* REJECT(); + static const TransferOp* value (const std::string &name); + + static void init(); + +private: + static std::vector values; +}; + +#endif // __TRANSFER_OP_HPP diff --git a/AusRegEPPTK/se/TransferResponse.cpp b/AusRegEPPTK/se/TransferResponse.cpp new file mode 100644 index 0000000..1f3048e --- /dev/null +++ b/AusRegEPPTK/se/TransferResponse.cpp @@ -0,0 +1,77 @@ +#include "se/TransferResponse.hpp" +#include "se/StandardCommandType.hpp" +#include "se/EPPDateFormatter.hpp" + +using namespace std; + +const string TransferResponse::OBJ() +{ + static string expr = "OBJ"; + return expr; +} + +const string TransferResponse::TR_STATUS_EXPR() +{ + static string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:trnData/OBJ:trStatus/text()"; + return expr; +} + +const string TransferResponse::REID_EXPR() +{ + static string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:trnData/OBJ:reID/text()"; + return expr; +} + +const string TransferResponse::REDATE_EXPR() +{ + static string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:trnData/OBJ:reDate/text()"; + return expr; +} + +const string TransferResponse::ACID_EXPR() +{ + static string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:trnData/OBJ:acID/text()"; + return expr; +} + +const string TransferResponse::ACDATE_EXPR() +{ + static string expr = DataResponse::RES_DATA_EXPR() + "/OBJ:trnData/OBJ:acDate/text()"; + return expr; +} + +TransferResponse::TransferResponse (const ObjectType* objectType) + : DataResponse(StandardCommandType::TRANSFER(), objectType) +{ +} + +void TransferResponse::fromXML (XMLDocument *xmlDoc) throw (ParsingException) +{ + DataResponse::fromXML(xmlDoc); + + if (!(resultArray[0].succeeded())) { + return; + } + + try + { + trStatus = xmlDoc->getNodeValue (trStatusExpr()); + + reID = xmlDoc->getNodeValue (reIDExpr()); + string reDateStr = xmlDoc->getNodeValue(reDateExpr()); + if (reDateStr.length() > 0) + reDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(reDateStr)); + + acID = xmlDoc->getNodeValue(acIDExpr()); + string acDateStr = xmlDoc->getNodeValue (acDateExpr()); + if (acDateStr.length() > 0) + acDate = std::auto_ptr(EPPDateFormatter::fromXSDateTime(acDateStr)); + } + catch (XPathExpressionException& e) + { + maintLogger->warning(e.getMessage()); + ParsingException pe; + pe.causedBy(e); + throw pe; + } +} diff --git a/AusRegEPPTK/se/TransferResponse.hpp b/AusRegEPPTK/se/TransferResponse.hpp new file mode 100644 index 0000000..f63bdc9 --- /dev/null +++ b/AusRegEPPTK/se/TransferResponse.hpp @@ -0,0 +1,54 @@ +#ifndef __TRANSFER_RESPONSE_HPP +#define __TRANSFER_RESPONSE_HPP + +#include "se/DataResponse.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/ObjectType.hpp" + +#include "xml/XMLDocument.hpp" + +/** + * Representation of the EPP transfer response, as defined in RFC3730. + * Subclasses of this must specify the object to which the command is mapped. + * Instances of this class provide an interface to access transfer response + * data for the object identified in a @link TransferCommand . + * This relies on the instance first being initialised by a suitable EPP + * transfer response using the method fromXML. For flexibility, this + * implementation extracts the data from the response using XPath queries, the + * expressions for which are defined statically. + * + * @see TransferCommand + */ +class TransferResponse : public DataResponse +{ +public: + TransferResponse (const ObjectType* objectType); + + const std::string& getTransferStatus() const { return trStatus; }; + const std::string& getRequestingClID() const { return reID; }; + const XMLGregorianCalendar* getRequestDate() const { return reDate.get(); }; + const std::string& getActioningClID() const { return acID; }; + const XMLGregorianCalendar* getActionDate() const { return acDate.get(); }; + + virtual void fromXML (XMLDocument *xmlDoc) throw (ParsingException); + +protected: + static const std::string OBJ(); + static const std::string TR_STATUS_EXPR(); + static const std::string REID_EXPR(); + static const std::string REDATE_EXPR(); + static const std::string ACID_EXPR(); + static const std::string ACDATE_EXPR(); + + virtual const std::string& trStatusExpr() const = 0; + virtual const std::string& reIDExpr() const = 0; + virtual const std::string& reDateExpr() const = 0; + virtual const std::string& acIDExpr() const = 0; + virtual const std::string& acDateExpr() const = 0; + +private: + std::string trStatus, reID, acID; + std::auto_ptr reDate, acDate; +}; + +#endif // __TRANSFER_RESPONSE_HPP diff --git a/AusRegEPPTK/se/UpdateCommand.hpp b/AusRegEPPTK/se/UpdateCommand.hpp new file mode 100644 index 0000000..16bf008 --- /dev/null +++ b/AusRegEPPTK/se/UpdateCommand.hpp @@ -0,0 +1,32 @@ +#ifndef __UPDATECOMMAND_HPP +#define __UPDATECOMMAND_HPP + +#include "se/ObjectCommand.hpp" +#include "se/StandardCommandType.hpp" + +/** + * Representation of the EPP update command, as defined in RFC3730. + * Subclasses of this must specify the object to which the command is mapped + * and specify the object-specific identifier of the object to update. + * + * @see Response + */ +class UpdateCommand : public ObjectCommand +{ +public: + /** + * Create an update command mapped to the specified object type to update + * the identified object. + * + * @param objType The type of object to which the update command is to be + * mapped. + * + * @param ident An object type-specific label identifying the object to + * update. + */ + UpdateCommand (const ObjectType* objType, + const std::string& ident) + : ObjectCommand(StandardCommandType::UPDATE(), objType, ident) {}; +}; + +#endif // __UPDATECOMMAND_HPP diff --git a/AusRegEPPTK/se/XMLGregorianCalendar.cpp b/AusRegEPPTK/se/XMLGregorianCalendar.cpp new file mode 100644 index 0000000..5b1fbe2 --- /dev/null +++ b/AusRegEPPTK/se/XMLGregorianCalendar.cpp @@ -0,0 +1,680 @@ +#include "se/XMLGregorianCalendar.hpp" +#include "common/StringUtils.hpp" +#include "common/EPPException.hpp" + +#include +#include +#include // isdigit() +#include // atol() + +using namespace std; + +const char * XMLGregorianCalendar::FIELD_NAME[] = + { "Year", + "Month", + "Day", + "Hour", + "Minute", + "Second", + "Millisecond", + "Timezone" }; + +const int XMLGregorianCalendar::daysInMonth[] = +{ 0, // XML Schema months start at 1. + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +typedef enum +{ + DATETIME, + DATE, + TIME, + GYEARMONTH, + GMONTHDAY, + GYEAR, + GMONTH, + GDAY +} QName; + +string formatInteger (int number, int width = 0) +{ + ostringstream str; + str.fill('0'); + str.width(width); + str << number; + + return str.str(); +} + +string formatBigDecimal (long double number, int digits = 10) +{ + ostringstream str; + str.precision(digits); + str << number; + return str.str(); +} + +class InternalError : public EPPException +{ +public: + InternalError(const string msg) + : EPPException(msg) + { } + EPP_EXCEPTION(InternalError); +}; + +class Parser +{ +public: + Parser (const string &format, + const string &value, + XMLGregorianCalendar *calendar) + : calendar(calendar), format(format), value(value), flen(format.length()), + vlen(value.length()), fidx(0), vidx(0) + { } + + void parse() throw (IllegalArgException, InternalError) + { + while (fidx < flen) + { + char fch = format[fidx++]; + + if (fch != '%') + { + skip(fch); + continue; + } + + switch (format[fidx++]) + { + case 'Y': // year + parseAndSetYear(4); + break; + + case 'M': // month + calendar->setMonth(parseInt(2, 2)); + break; + + case 'D': // days + calendar->setDay(parseInt(2, 2)); + break; + + case 'h': // hours + calendar->setHour(parseInt(2, 2), false); + break; + + case 'm': // minutes + calendar->setMinute(parseInt(2, 2)); + break; + + case 's': // parse seconds. + { + calendar->setSecond(parseInt(2, 2)); + + if (peek() == '.') + calendar->setFractionalSecond(parseBigDecimal()); + } + break; + + case 'z': // time zone. missing 'Z', or [+-]nn:nn + { + char vch = peek(); + if (vch == 'Z') + { + vidx++; + calendar->setTimezone(0); + } + else if (vch == '+' || vch == '-') + { + vidx++; + int h = parseInt(2, 2); + skip(':'); + int m = parseInt(2, 2); + calendar->setTimezone((h * 60 + m) * (vch == '+' ? 1 : -1)); + } + } + break; + + default: + throw InternalError("Unexpected internal format character"); + } + // End switch + } + // End while + + if (vidx != vlen) + throw IllegalArgException(value); + }; + // End parse() + +private: + XMLGregorianCalendar *calendar; + string format, value; + int flen, vlen; + + int fidx, vidx; + + char peek () + { + if (vidx == vlen) + return (char)-1; + + return value[vidx]; + }; + + char read() + { + if (vidx == vlen) + throw IllegalArgException(value); + + return value[vidx++]; + }; + + void skip(char ch) + { + if (read() != ch) + throw IllegalArgException(value); + }; + + int parseInt (int minDigits, int maxDigits) + { + int n = 0; + char ch; + int vstart = vidx; + while (isdigit(ch = peek()) && (vidx - vstart) <= maxDigits) + { + vidx++; + n = n*10 + ch-'0'; + } + if ((vidx - vstart) < minDigits) + throw IllegalArgException(value); + + return n; + }; + + void parseAndSetYear(int minDigits) throw (IllegalArgException) + { + int vstart = vidx; + int n = 0; + bool neg = false; + + if (peek() == '-') + { + vidx++; + neg = true; + } + + for (;;) + { + char ch = peek(); + if (!isdigit(ch)) + break; + vidx++; + n = n*10 + ch-'0'; + } + + if ((vidx - vstart) < minDigits) + throw IllegalArgException(value); + + if (vidx - vstart < 7) + { + if (neg) + n = -n; + + calendar->year = n; + } + else + calendar->setYear ((long long)atol (value.substr(vstart, vidx - vstart).c_str())); + }; + + long double parseBigDecimal() + { + int vstart = vidx; + + if (peek() == '.') + vidx++; + else + throw IllegalArgException(value); + + while (isdigit(peek())) + vidx++; + + return strtold (value.substr(vstart, vidx - vstart).c_str(), NULL); + }; +}; +// End class Parser + + + +XMLGregorianCalendar::XMLGregorianCalendar () + : fractionalSecond(0), year(FIELD_UNDEFINED), + month(FIELD_UNDEFINED), day(FIELD_UNDEFINED), timezone(FIELD_UNDEFINED), + hour(FIELD_UNDEFINED), minute(FIELD_UNDEFINED), second(FIELD_UNDEFINED) +{ } + +XMLGregorianCalendar::XMLGregorianCalendar(const string &lexicalRepresentation) + throw (MalformedDateException) + : fractionalSecond(0), year(FIELD_UNDEFINED), + month(FIELD_UNDEFINED), day(FIELD_UNDEFINED), timezone(FIELD_UNDEFINED), + hour(FIELD_UNDEFINED), minute(FIELD_UNDEFINED), second(FIELD_UNDEFINED) +{ + string format(""), + lexRep = lexicalRepresentation; + + const string::size_type NOT_FOUND = string::npos; + int lexRepLength = lexRep.length(); + + // Parser needs a format string - work out which xml schema date/time + // datatype this lexRep represents. + if (lexRep.find ('T', 0) != NOT_FOUND) + { + // Found date/time separator -> must be xsd:DateTime + format = string("%Y-%M-%DT%h:%m:%s") + "%z"; + } + else if (lexRepLength >= 3 && lexRep[2] == ':') + { + // Found ':' -> must be xsd:Time + format = string("%h:%m:%s") + "%z"; + } + else if (lexRep.find("--", 0) == 0) + { + // Check for gDay/gMonth/gMonthDay + if (lexRepLength >= 3 && lexRep[2] == '-') + { + // gDay + format = string("---%D") + "%z"; + } + else if (lexRepLength == 4 || // --MM + lexRepLength == 5 || // --MMZ + lexRepLength == 10) // --MMSHH:MM + { + // gMonth + format = string("--%M") + "%z"; + } + else + { + // gMonthDay + format = string("--%M-%D") + "%z"; + } + } + else + { + // Check for date/gYear/gYearMonth + int countSeparator = 0; + const size_t timezoneOffset = lexRep.find(':', 0); + if (timezoneOffset != NOT_FOUND) + lexRepLength -= 6; + + // Start at 1 to skip potential -ve sign for year. + for (int i = 1; i < lexRepLength; i++) + if (lexRep[i] == '-') + countSeparator++; + + if (countSeparator == 0) + { + // gYear + format = string("%Y") + "%z"; + } + else if (countSeparator == 1) + { + // gYearMonth + format = string("%Y-%M") + "%z"; + } + else + { + // date + format = string("%Y-%M-%D") + "%z"; + } + } + // End if + + Parser p(format, lexRep, this); + try + { + p.parse(); + } + catch (InternalError& i) + { + MalformedDateException e("Could not parse date: " + lexicalRepresentation); + e.causedBy(i); + throw e; + } + catch (IllegalArgException& i) + { + MalformedDateException e("Could not parse date: " + lexicalRepresentation); + e.causedBy(i); + throw e; + } + if (!isValid()) throw MalformedDateException("common.date.format"); +} + +bool XMLGregorianCalendar::isValid() const +{ + if (year == 0) + return false; + + if (getHour() == 24 && + (getMinute() != 0 || getSecond() != 0)) + { + return false; + } + + if (getMonth() == FEBRUARY) + { + int maxDays = 29; + + if (year != FIELD_UNDEFINED) + maxDays = maximumDayInMonthFor(year, getMonth()); + + if (getDay() > maxDays) + return false; + } + + return true; +} + +void XMLGregorianCalendar::setMonth (int month) +{ + if ((month < JANUARY || DECEMBER < month) && month != FIELD_UNDEFINED) + invalidFieldValue (MONTH, month); + + this->month = month; +} + +void XMLGregorianCalendar::setDay (int day) +{ + if ((day < 1 || 31 < day) && day != FIELD_UNDEFINED) + invalidFieldValue (DAY, day); + + this->day = day; +} + +void XMLGregorianCalendar::setTimezone (int offset) +{ + if ((offset < -14*60 || 14*60 < offset) && offset != FIELD_UNDEFINED) + invalidFieldValue (TIMEZONE, offset); + + this->timezone = offset; +} + +void XMLGregorianCalendar::setTime (int hour, + int minute, + int second, + long double fractional) +{ + setHour (hour, false); + setMinute (minute); + if (second != 60) + setSecond(second); + else if ((hour == 23 && minute == 59) || + (hour == 0 && minute == 0)) + { + setSecond(second); + } + else + invalidFieldValue (SECOND, second); + + setFractionalSecond(fractional); + + testHour(); +} + +void XMLGregorianCalendar::testHour() +{ + if (hour == 24 && (getMinute() != 0 || + getSecond() != 0)) + invalidFieldValue (HOUR, getHour()); +} + + +void XMLGregorianCalendar::setHour (int hour, bool validate) +{ + if ((hour < 0 || hour > 24) && hour != FIELD_UNDEFINED) + invalidFieldValue (HOUR, hour); + + this->hour = hour; + + if (validate) + testHour(); +} + +void XMLGregorianCalendar::setMinute (int minute) +{ + if ((minute < 0 || 59 < minute) && minute != FIELD_UNDEFINED) + invalidFieldValue (MINUTE, minute); + + this->minute = minute; +} + +void XMLGregorianCalendar::setSecond (int second) +{ + if ((second < 0 || 60 < second) && // leap second allows for 60 + second != FIELD_UNDEFINED) + { + invalidFieldValue (SECOND, second); + } + + this->second = second; +} + +void XMLGregorianCalendar::setFractionalSecond(long double fractional) +{ + if (fractional < 0.0 || fractional >= 1.0) + throw IllegalArgException ("Invalid fractional seconds"); + + fractionalSecond = fractional; +} + + +QName getXMLSchemaType(int year, int month, int day, int hour, int minute, int second) + throw (IllegalStateException) +{ + unsigned int mask = + (year != XMLGregorianCalendar::FIELD_UNDEFINED ? 0x20 : 0) | + (month != XMLGregorianCalendar::FIELD_UNDEFINED ? 0x10 : 0) | + (day != XMLGregorianCalendar::FIELD_UNDEFINED ? 0x08 : 0) | + (hour != XMLGregorianCalendar::FIELD_UNDEFINED ? 0x04 : 0) | + (minute != XMLGregorianCalendar::FIELD_UNDEFINED ? 0x02 : 0) | + (second != XMLGregorianCalendar::FIELD_UNDEFINED ? 0x01 : 0); + + switch (mask) + { + case 0x3F: + return DATETIME; + break; + + case 0x38: + return DATE; + break; + + case 0x07: + return TIME; + break; + + case 0x30: + return GYEARMONTH; + break; + + case 0x18: + return GMONTHDAY; + break; + + case 0x20: + return GYEAR; + break; + + case 0x10: + return GMONTH; + break; + + case 0x08: + return GDAY; + break; + + default: + throw IllegalStateException("common.illegal.state"); + } + // End switch +} + +string XMLGregorianCalendar::toXMLFormat() const +{ + string formatString; + + switch (getXMLSchemaType(year, month, day, hour, minute, second)) + { + case DATETIME: + formatString = "%Y-%M-%DT%h:%m:%s%z"; + break; + + case DATE: + formatString = "%Y-%M-%D%z"; + break; + + case TIME: + formatString = "%h:%m:%s%z"; + break; + + case GMONTH: + formatString = "--%M%z"; + break; + + case GDAY: + formatString = "---%D%z"; + break; + + case GYEAR: + formatString = "%Y%z"; + break; + + case GYEARMONTH: + formatString = "%Y-%M%z"; + break; + + case GMONTHDAY: + formatString = "--%M-%D%z"; + break; + + default: + break; + } + // End switch + + return format (formatString); +} + +string XMLGregorianCalendar::format (const string &format) const +{ + string buf; + + int fidx = 0, flen = format.length(); + + while (fidx < flen) + { + char fch = format[fidx++]; + + if (fch != '%') // not a meta char + { + buf.append(&fch, 1); + continue; + } + + switch (format[fidx++]) + { + case 'Y': + buf.append (formatInteger(getYear(), 4)); + break; + + case 'M': + buf.append (formatInteger (getMonth(), 2)); + break; + + case 'D': + buf.append (formatInteger (getDay(), 2)); + break; + + case 'h': + buf.append (formatInteger (getHour(), 2)); + break; + + case 'm': + buf.append (formatInteger (getMinute(), 2)); + break; + + case 's': + buf.append (formatInteger (getSecond(), 2)); + { + string frac = ".0"; // always truncate subsecond. + buf.append (frac); // don't skip leading zero. + } + break; + + case 'z': + { + int offset = getTimezone(); + if (offset == 0) + { + buf.append ("Z"); + } + else + { + if (offset != FIELD_UNDEFINED) + { + if (offset < 0) + { + buf.append ("-"); + offset = -offset; + } + else + buf.append ("+"); + + buf.append (formatInteger (offset/60)); + buf.append (":"); + buf.append (formatInteger (offset % 60)); + } + } + } + break; + + default: + throw InternalError("Unexpected format character in output format"); + } + // End switch + } + + return buf; +} + + +long double XMLGregorianCalendar::getSeconds() const +{ + if (second == FIELD_UNDEFINED) + return 0.0L; + else + return second + fractionalSecond; +} + + +int XMLGregorianCalendar::maximumDayInMonthFor (long long year, int month) +{ + if (month != FEBRUARY) + return daysInMonth[month]; + else + { + if ((year % 400) == 0 || ((year % 100) != 0 && (year % 4) == 0)) + { + return 29; + } + else + return daysInMonth[month]; + } +} + +void XMLGregorianCalendar::invalidFieldValue (int field, int value) + throw (IllegalArgException) +{ + throw IllegalArgException( + string("InvalidFieldValue") + + FIELD_NAME[field] + + StringUtils::makeString(value)); +} diff --git a/AusRegEPPTK/se/XMLGregorianCalendar.hpp b/AusRegEPPTK/se/XMLGregorianCalendar.hpp new file mode 100644 index 0000000..568a334 --- /dev/null +++ b/AusRegEPPTK/se/XMLGregorianCalendar.hpp @@ -0,0 +1,148 @@ +#ifndef __XMLGREGORIANCALENDAR_HPP +#define __XMLGREGORIANCALENDAR_HPP + +#include "common/IllegalStateException.hpp" +#include "common/EPPException.hpp" +#include "se/IllegalArgException.hpp" + +#include + +class InvalidDateCombination : public EPPException +{ +public: + InvalidDateCombination (const std::string &msg) + : EPPException(msg) { } + EPP_EXCEPTION(InvalidDateCombination); +}; + +class MalformedDateException : public EPPException +{ +public: + MalformedDateException(const std::string& msg) + : EPPException(msg) { } + EPP_EXCEPTION(MalformedDateException); +}; + + +class Parser; +class XMLGregorianCalendar +{ +public: + friend class Parser; + + enum { FIELD_UNDEFINED = -1 }; + + enum + { + JANUARY = 1, + FEBRUARY, + MARCH, + APRIL, + MAY, + JUNE, + JULY, + AUGUST, + SEPTEMBER, + OCTOBER, + NOVEMBER, + DECEMBER + }; + + + std::string toXMLFormat() const; + std::string format (const std::string &format) const; + + static XMLGregorianCalendar * createDate (int year, + int month, + int day, + int timezone); + static XMLGregorianCalendar * createTime (int hours, + int minutes, + int seconds, + int timezone); + static XMLGregorianCalendar * createTime (int hours, + int minutes, + int seconds, + long double fractionalSecond, + int timezone); + static XMLGregorianCalendar * createTime (int hours, + int minutes, + int seconds, + int milliseconds, + int timezone); + + bool isValid() const; + + long double getFractionalSecond () const { return fractionalSecond; }; + int getYear() const { return year; }; + int getMonth() const { return month; }; + int getHour() const { return hour; }; + int getMinute() const { return minute; }; + int getSecond() const { return second; }; + int getDay() const { return day; }; + int getTimezone() const { return timezone; }; + long double getSeconds() const; + + void setYear (int year) { this->year = year; } + void setMonth (int month); + void setDay (int day); + void setTimezone (int offset); + void setTime (int hour, + int minute, + int second, + long double fractional = 0); + void setHour (int hour, bool validate = true); + void setMinute (int minute); + void setSecond (int second); + void setFractionalSecond (long double fractional); + + + XMLGregorianCalendar (const std::string &lexicalRepresentation) + throw (MalformedDateException); + XMLGregorianCalendar (); +protected: + XMLGregorianCalendar (long year, + int month, + int day, + int hour, + int minute, + int second, + long double fractionalSecond, + int timezone); + +private: + XMLGregorianCalendar (long year, + int month, + int day, + int hour, + int minute, + int second, + int millisecond, + int timezone); + + long double fractionalSecond; + int year, + month, + day, + timezone, + hour, + minute, + second; + + static const long BILLION = 1000000000; + + enum { YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, TIMEZONE }; + + static const char * FIELD_NAME[]; + static const int daysInMonth[]; + + void testHour (); + + static int maximumDayInMonthFor (long long year, int month); + + void invalidFieldValue (int field, int value) + throw (IllegalArgException); +}; + + +#endif // __XMLGREGORIANCALENDAR_HPP diff --git a/AusRegEPPTK/se/XMLGregorianCalendarTest.cpp b/AusRegEPPTK/se/XMLGregorianCalendarTest.cpp new file mode 100644 index 0000000..8f589a5 --- /dev/null +++ b/AusRegEPPTK/se/XMLGregorianCalendarTest.cpp @@ -0,0 +1,135 @@ +#include "common/Test.hpp" +#include "se/XMLGregorianCalendar.hpp" +#include "se/IllegalArgException.hpp" + +using namespace std; + +/* Ordinarily wouldn't bother testing setters and getters, but it's necessary + * here because the underlying implementation of of fractional seconds changed + * from a pointer to primitive, and is used throughout the class. No good + * reason why it was done like this in the first place, other than to + * unnecessarily provide a poor analogue of behaviour in the Java version. + */ + +void testNoFractionalSecondSet() +{ + XMLGregorianCalendar calendar; + ASSERT_EQ(calendar.getFractionalSecond(), 0); +} + +void testSetZeroFractionalSecond() +{ + XMLGregorianCalendar calendar; + calendar.setFractionalSecond(0.0); + ASSERT_EQ(calendar.getFractionalSecond(), 0); +} + +void testSetNonZeroFractionalSecond() +{ + XMLGregorianCalendar calendar; + calendar.setFractionalSecond(0.123); + ASSERT_EQ(calendar.getFractionalSecond(), 0.123); +} + +void testSetNegativeFractionalSecond() +{ + XMLGregorianCalendar calendar; + + try + { + calendar.setFractionalSecond(-0.0000001); + FAIL("Should have thrown an illegal argument exception"); + } + catch (IllegalArgException& e) + { + ASSERT_EQ(e.getMessage(), "Invalid fractional seconds"); + } +} + +void testSetFractionalSecondToWholeSecond() +{ + XMLGregorianCalendar calendar; + + try + { + calendar.setFractionalSecond(1); + FAIL("Should have thrown an illegal argument exception"); + } + catch (IllegalArgException& e) + { + ASSERT_EQ(e.getMessage(), "Invalid fractional seconds"); + } +} + +/* Like fractional seconds, it seems that eons were implemented to maintain + * parity with the Java class. Given that it leaks memory, and we're not too + * concerned with the usability of the usability of this toolkit a billion + * years from now, eons have now been removed. The following tests ensure that + * the year field works correctly, since it's affected by the change. + */ +void testValidYearSet() +{ + XMLGregorianCalendar calendar; + calendar.setDay(1); + calendar.setMonth(3); + calendar.setYear(2010); + ASSERT_EQ(calendar.isValid(), true); +} + +void testInvalidNoYearSet() +{ + XMLGregorianCalendar calendar("2015-04-08T04:23:29.0Z"); + ASSERT_EQ(calendar.isValid(), true); + calendar.setYear(0); + ASSERT_EQ(calendar.isValid(), false); +} + +void testInvalidNonLeapYear() +{ + XMLGregorianCalendar calendar("2009-02-08T04:23:29.0Z"); + ASSERT_EQ(calendar.isValid(), true); + calendar.setDay(29); + ASSERT_EQ(calendar.isValid(), false); +} + +void testFormatYear() +{ + XMLGregorianCalendar calendar; + calendar.setYear(2015); + ASSERT_EQ(calendar.format("%Y"), "2015"); +} + +/* No good reason why we should be allowing negative years, but there was code + * to explicitly ensure it was output correctly, so it does appear to be + * intended behaviour. + */ + +void testValidNegativeYear() +{ + XMLGregorianCalendar calendar; + calendar.setYear(-2102); + ASSERT_EQ(calendar.isValid(), true); +} + +void testFormatNegativeYear() +{ + XMLGregorianCalendar calendar; + calendar.setYear(-2015); + ASSERT_EQ(calendar.format("%Y"), "-2015"); +} + +int main(int argc, char* argv[]) +{ + TEST_run(testNoFractionalSecondSet); + TEST_run(testSetZeroFractionalSecond); + TEST_run(testSetNonZeroFractionalSecond); + TEST_run(testSetNegativeFractionalSecond); + TEST_run(testSetFractionalSecondToWholeSecond); + TEST_run(testValidYearSet); + TEST_run(testInvalidNoYearSet); + TEST_run(testInvalidNonLeapYear); + TEST_run(testFormatYear); + TEST_run(testValidNegativeYear); + TEST_run(testFormatNegativeYear); + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.cpp b/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.cpp new file mode 100644 index 0000000..faebeb2 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.cpp @@ -0,0 +1,24 @@ +#include "se/Command.hpp" +#include "SecDNSExtension.hpp" +#include "xml/XMLHelper.hpp" +#include "DomainSecDNSCreateCommandExtension.hpp" + +namespace { + SecDNSExtension& secDNSExtension() { + static SecDNSExtension* secDNSExtension = new SecDNSExtension(); + return *secDNSExtension; + } +}; // anonymous namespace + +void DomainSecDNSCreateCommandExtension::addToCommand(const Command &command) const +{ + XMLWriter* xmlWriter = command.getXmlWriter(); + DOMElement* extensionElement = command.getExtensionElement(); + DOMElement* createElement = xmlWriter->appendChild(extensionElement, + "create", secDNSExtension().getURI()); + + if (createData.get() != NULL) + { + createData->createXMLElement(xmlWriter, createElement); + } +} diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.hpp b/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.hpp new file mode 100644 index 0000000..3dae40d --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtension.hpp @@ -0,0 +1,36 @@ +#ifndef _SECDNS_DOMAIN_CREATE_COMMAND_EXTENSION_HPP_ +#define _SECDNS_DOMAIN_CREATE_COMMAND_EXTENSION_HPP_ + +#include "se/CommandExtension.hpp" +#include "SecDNSDSOrKeyType.hpp" + +/** + * This class models the elements as defined in the + * AusRegistry secDNS-1.1 EPP command extension. + */ + +class DomainSecDNSCreateCommandExtension : public CommandExtension +{ + public: + virtual void addToCommand(const Command &command) const; + + /** + * Set the Create Data. + * The memory of createData pointer will be handled DomainSecDNSCreateCommandExtension, + * memory will be auto freed when this extension instance is out of scope + * + * @param createData + * The DSData or KeyData in the command xml + * + */ + void setCreateData(SecDNSDSOrKeyType* createData); + private: + std::auto_ptr createData; +}; + +inline void DomainSecDNSCreateCommandExtension::setCreateData(SecDNSDSOrKeyType* createData) +{ + this->createData.reset(createData); +} + +#endif /* _SECDNS_DOMAIN_CREATE_COMMAND_EXTENSION_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtensionTest.cpp b/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtensionTest.cpp new file mode 100644 index 0000000..d6161c2 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSCreateCommandExtensionTest.cpp @@ -0,0 +1,158 @@ +#include "xml/XMLParser.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" +#include "session/Timer.hpp" +#include "SecDNSDSData.hpp" +#include "SecDNSKeyData.hpp" +#include "SecDNSDSOrKeyType.hpp" +#include "DomainSecDNSCreateCommandExtension.hpp" +#include "se/DomainCreateCommand.hpp" +#include "se/CLTRID.hpp" + +using namespace std; + +void testSecDNSAllFields() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainCreateCommand createCommand("jtkutest.com.au", "jtkUT3st", NULL); + + auto_ptr dsData(new SecDNSDSData(12345, 3, 1, "49FD46E6C4B45C55D4AC")); + auto_ptr keyData(new SecDNSKeyData(256, 3, 1, "AQPJ////4Q==")); + dsData->setKeyData(keyData.release()); + + auto_ptr createData(new SecDNSDSOrKeyType()); + auto_ptr maxSigLife(new SecDNSMaxSigLifeType(604800)); + createData->setMaxSigLife(maxSigLife.release()); + createData->addToDSData(dsData.release()); + + DomainSecDNSCreateCommandExtension extension; + extension.setCreateData(createData.release()); + + createCommand.appendExtension(extension); + + const string xml = createCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aujtkUT3st604800123453149FD46E6C4B45C55D4AC25631AQPJ////4Q==JTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSMultipleDSDataWithoutMaxSigLife() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainCreateCommand createCommand("jtkutest.com.au", "jtkUT3st", NULL); + + auto_ptr dsData(new SecDNSDSData(12345, 3, 1, "38FD46E6C4B45C55D4AC")); + auto_ptr keyData(new SecDNSKeyData(256, 3, 1, "AQPJ////4Q==")); + dsData->setKeyData(keyData.release()); + + auto_ptr createData(new SecDNSDSOrKeyType()); + createData->addToDSData(dsData.release()); + + auto_ptr dsData2(new SecDNSDSData(6789, 2, 2, "49FD46E6C4B45C55D4AC")); + createData->addToDSData(dsData2.release()); + + DomainSecDNSCreateCommandExtension extension; + extension.setCreateData(createData.release()); + + createCommand.appendExtension(extension); + + const string xml = createCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aujtkUT3st123453138FD46E6C4B45C55D4AC25631AQPJ////4Q==67892249FD46E6C4B45C55D4ACJTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSAllFieldsMin() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainCreateCommand createCommand("jtkutest.com.au", "jtkUT3st", NULL); + + auto_ptr dsData(new SecDNSDSData(0, 0, 0, "49FD46E6C4B45C55D4AC")); + auto_ptr keyData(new SecDNSKeyData(0, 0, 0, "AQPJ////4Q==")); + dsData->setKeyData(keyData.release()); + + auto_ptr createData(new SecDNSDSOrKeyType()); + auto_ptr maxSigLife(new SecDNSMaxSigLifeType(1)); + createData->setMaxSigLife(maxSigLife.release()); + createData->addToDSData(dsData.release()); + + DomainSecDNSCreateCommandExtension extension; + extension.setCreateData(createData.release()); + + createCommand.appendExtension(extension); + + const string xml = createCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aujtkUT3st100049FD46E6C4B45C55D4AC000AQPJ////4Q==JTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSAllFieldsMax() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainCreateCommand createCommand("jtkutest.com.au", "jtkUT3st", NULL); + + auto_ptr dsData(new SecDNSDSData(65535, 255, 255, "49FD46E6C4B45C55D4AC")); + auto_ptr keyData(new SecDNSKeyData(65535, 255, 255, "AQPJ////4Q==")); + dsData->setKeyData(keyData.release()); + + auto_ptr createData(new SecDNSDSOrKeyType()); + auto_ptr maxSigLife(new SecDNSMaxSigLifeType(2147483647)); + createData->setMaxSigLife(maxSigLife.release()); + createData->addToDSData(dsData.release()); + + DomainSecDNSCreateCommandExtension extension; + extension.setCreateData(createData.release()); + + createCommand.appendExtension(extension); + + const string xml = createCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aujtkUT3st21474836476553525525549FD46E6C4B45C55D4AC65535255255AQPJ////4Q==JTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSJustKeyData() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + DomainCreateCommand createCommand("jtkutest.com.au", "jtkUT3st", NULL); + + auto_ptr keyData(new SecDNSKeyData(65535, 255, 255, "AQPJ////4Q==")); + + auto_ptr createData(new SecDNSDSOrKeyType()); + auto_ptr maxSigLife(new SecDNSMaxSigLifeType(65535)); + createData->setMaxSigLife(maxSigLife.release()); + createData->addToKeyData(keyData.release()); + + DomainSecDNSCreateCommandExtension extension; + extension.setCreateData(createData.release()); + + createCommand.appendExtension(extension); + + const string xml = createCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.aujtkUT3st6553565535255255AQPJ////4Q==JTKUTEST.20070101.010101.0" + ); +} + +int main(int argc, char* argv[]) +{ + init("etc/toolkit2.conf"); + TEST_run(testSecDNSAllFields); + TEST_run(testSecDNSMultipleDSDataWithoutMaxSigLife); + TEST_run(testSecDNSAllFieldsMin); + TEST_run(testSecDNSAllFieldsMax); + TEST_run(testSecDNSJustKeyData); + + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.cpp b/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.cpp new file mode 100644 index 0000000..4a4f18f --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.cpp @@ -0,0 +1,125 @@ +#include + +#include "SecDNSMaxSigLifeType.hpp" +#include "SecDNSDSData.hpp" +#include "SecDNSKeyData.hpp" +#include "DomainSecDNSInfoResponseExtension.hpp" + +using namespace std; + +/* + * Have to use static function instead of static variable + * since there is not guarantee about the construct/destruct + * order of a static instance of any types + */ +const string DomainSecDNSInfoResponseExtension::DS_DATA_LIST_EXPR() +{ + return EXTENSION_EXPR() + "/secDNS:infData/secDNS:dsData"; +} + +const string DomainSecDNSInfoResponseExtension::KEY_DATA_LIST_EXPR() +{ + return EXTENSION_EXPR() + "/secDNS:infData/secDNS:keyData"; +} + +const string DomainSecDNSInfoResponseExtension::MAXSIGLIFE_EXPR() +{ + return EXTENSION_EXPR() + "/secDNS:infData/secDNS:maxSigLife"; +} + +void DomainSecDNSInfoResponseExtension::fromXML(XMLDocument *xmlDoc) +{ + infData.reset(new SecDNSDSOrKeyType); + + if (xmlDoc->getNodeCount("count(" + MAXSIGLIFE_EXPR() + ")") > 0) + { + int maxSigLifeInt = getInt(xmlDoc->getNodeValue(MAXSIGLIFE_EXPR())); + + auto_ptr maxSigLife(new SecDNSMaxSigLifeType(maxSigLifeInt)); + infData->setMaxSigLife(maxSigLife.release()); + } + + int secDnsCount = getResponseDSData(xmlDoc); + initialised = (secDnsCount > 0) && (infData->getDSDataListSize() == secDnsCount); + + if (!initialised) + { + secDnsCount = getResponseKeyData(xmlDoc); + initialised = (secDnsCount > 0) && (infData->getKeyDataListSize() == secDnsCount); + } +} + +SecDNSDSOrKeyType* DomainSecDNSInfoResponseExtension::getInfData() const +{ + return infData.get(); +} + +int DomainSecDNSInfoResponseExtension::getResponseDSData(const XMLDocument* xmlDoc) +{ + int secDnsCount = xmlDoc->getNodeCount("count(" + DS_DATA_LIST_EXPR() + ")"); + + if (secDnsCount > 0) { + for (int i = 1; i <= secDnsCount; i++) + { + const std::string currentDSDataListXPath = + ReceiveSE::replaceIndex(DS_DATA_LIST_EXPR() + "[IDX]", i); + auto_ptr dsData = getDSData(xmlDoc, currentDSDataListXPath); + infData->addToDSData(dsData.release()); + } + } + + return secDnsCount; +} + +int DomainSecDNSInfoResponseExtension::getResponseKeyData(const XMLDocument* xmlDoc) +{ + int secDnsCount = xmlDoc->getNodeCount("count(" + KEY_DATA_LIST_EXPR() + ")"); + if (secDnsCount > 0) { + for (int i = 1; i <= secDnsCount; i++) + { + const std::string currentKeyDataListXPath = + ReceiveSE::replaceIndex(KEY_DATA_LIST_EXPR() + "[IDX]", i); + auto_ptr keyData = getKeyData(xmlDoc, currentKeyDataListXPath); + infData->addToKeyData(keyData.release()); + } + } + return secDnsCount; +} + +auto_ptr DomainSecDNSInfoResponseExtension::getDSData( + const XMLDocument* xmlDoc, + const std::string& dsDataXPath) +{ + auto_ptr dsData(new SecDNSDSData()); + dsData->setKeyTag(getInt(xmlDoc->getNodeValue(dsDataXPath + "/secDNS:keyTag/text()"))); + dsData->setAlg(getInt(xmlDoc->getNodeValue(dsDataXPath + "/secDNS:alg/text()"))); + dsData->setDigestType(getInt(xmlDoc->getNodeValue(dsDataXPath + "/secDNS:digestType/text()"))); + dsData->setDigest(xmlDoc->getNodeValue(dsDataXPath + "/secDNS:digest/text()")); + + int keyDataCount = xmlDoc->getNodeCount("count(" + dsDataXPath + "/secDNS:keyData)"); + if (keyDataCount > 0) { + dsData->setKeyData(getKeyData(xmlDoc, dsDataXPath + "/secDNS:keyData").release()); + } + return dsData; +} + +auto_ptr DomainSecDNSInfoResponseExtension::getKeyData( + const XMLDocument* xmlDoc, + const std::string& keyDataXPath) +{ + auto_ptr keyData(new SecDNSKeyData()); + + keyData->setFlags(getInt(xmlDoc->getNodeValue(keyDataXPath + "/secDNS:flags/text()"))); + keyData->setProtocol(getInt(xmlDoc->getNodeValue(keyDataXPath + "/secDNS:protocol/text()"))); + keyData->setAlg(getInt(xmlDoc->getNodeValue(keyDataXPath + "/secDNS:alg/text()"))); + keyData->setPubKey(xmlDoc->getNodeValue(keyDataXPath + "/secDNS:pubKey/text()")); + return keyData; +} + +int DomainSecDNSInfoResponseExtension::getInt(const std::string& value) +{ + int intValue; + istringstream iss(value); + iss >> intValue; + return intValue; +} diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.hpp b/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.hpp new file mode 100644 index 0000000..ed36eb3 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtension.hpp @@ -0,0 +1,44 @@ +#ifndef SECDNSDOMAININFORESPONSEEXTENSION_HPP_ +#define SECDNSDOMAININFORESPONSEEXTENSION_HPP_ + +#include "se/ResponseExtension.hpp" +#include "SecDNSDSOrKeyType.hpp" + +/** + * This class models the elements as defined in the + * AusRegistry secDNS-1.1 EPP command extension. + */ + +class DomainSecDNSInfoResponseExtension : public ResponseExtension +{ + public: + DomainSecDNSInfoResponseExtension() : + initialised(false), + infData(NULL) + {} + virtual void fromXML(XMLDocument *xmlDoc); + virtual bool isInitialised() const; + SecDNSDSOrKeyType* getInfData() const; + private: + int getResponseDSData(const XMLDocument* xmlDoc); + int getResponseKeyData(const XMLDocument* xmlDoc); + + std::auto_ptr getDSData(const XMLDocument* xmlDoc, const std::string& dsDataXPath); + std::auto_ptr getKeyData(const XMLDocument* xmlDoc, const std::string& keyDataXPath); + int getInt(const std::string& value); + + bool initialised; + std::auto_ptr infData; + + static const std::string DS_DATA_LIST_EXPR(); + static const std::string KEY_DATA_LIST_EXPR(); + static const std::string MAXSIGLIFE_EXPR(); + +}; + +inline bool DomainSecDNSInfoResponseExtension::isInitialised() const +{ + return initialised; +} + +#endif /* SECDNSDOMAININFORESPONSEEXTENSION_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtensionTest.cpp b/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtensionTest.cpp new file mode 100644 index 0000000..e7b7994 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSInfoResponseExtensionTest.cpp @@ -0,0 +1,249 @@ +#include + +#include "xml/XMLParser.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" +#include "SecDNSDSData.hpp" +#include "SecDNSKeyData.hpp" +#include "SecDNSDSOrKeyType.hpp" +#include "DomainSecDNSInfoResponseExtension.hpp" +#include "se/DomainInfoResponse.hpp" + +using namespace std; + +void assertFirstDSData(const SecDNSDSData* dsData); +void assertKeyData(const SecDNSKeyData* keyData); +void assertSecondDSData(const SecDNSDSData* dsData); + +string getInfoResponseExpectedXml(const string& domainName, bool isMulitpleDs, + bool isKeyData, bool isDsData); +void buildXmlResponseAfterExtension(ostringstream& result); +void buildSecDNSXmlExtension(bool isMulitpleDs, bool isKeyData, bool isDsData, + ostringstream& result); +void buildXmlResponseBeforeExtension(const string& domainName, + ostringstream& result); + +void testSecDNSInfoExtensionAllFields() +{ + string domainName = "test.com.au"; + DomainInfoResponse response; + DomainSecDNSInfoResponseExtension extension; + response.registerExtension(&extension); + + const string xml = getInfoResponseExpectedXml(domainName, false, false, true); + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + ASSERT_EQ(extension.isInitialised(), true); + ASSERT_EQ(response.getName(), domainName); + ASSERT_EQ(extension.getInfData()->getDSDataListSize(), 1); + assertFirstDSData(extension.getInfData()->getDSData(0).get()); +} + +void testSecDNSInfoExtensionOnlyKeyData() +{ + string domainName = "test.com.au"; + DomainInfoResponse response; + DomainSecDNSInfoResponseExtension extension; + response.registerExtension(&extension); + + const string xml = getInfoResponseExpectedXml(domainName, false, true, false); + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + ASSERT_EQ(extension.isInitialised(), true); + ASSERT_EQ(response.getName(), domainName); + ASSERT_EQ(extension.getInfData()->getDSDataListSize(), 0); + ASSERT_EQ(extension.getInfData()->getKeyDataListSize(), 1); + assertKeyData(extension.getInfData()->getKeyData(0).get()); +} + +void testSecDNSInfoExtensionMultipleDsRecords() +{ + string domainName = "test.com.au"; + DomainInfoResponse response; + DomainSecDNSInfoResponseExtension extension; + response.registerExtension(&extension); + + const string xml = getInfoResponseExpectedXml(domainName, true, false, true); + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + ASSERT_EQ(extension.isInitialised(), true); + ASSERT_EQ(response.getName(), domainName); + ASSERT_EQ(extension.getInfData()->getDSDataListSize(), 2); + assertFirstDSData(extension.getInfData()->getDSData(0).get()); + assertSecondDSData(extension.getInfData()->getDSData(1).get()); +} + +void testSecDNSInfoNoExtensionInitialised() +{ + string domainName = "test.com.au"; + DomainInfoResponse response; + DomainSecDNSInfoResponseExtension extension; + response.registerExtension(&extension); + + const string xml = getInfoResponseExpectedXml(domainName, false, false, false); + + auto_ptr parser(new XMLParser); + auto_ptr doc(parser->parse(xml)); + + response.fromXML(doc.get()); + + ASSERT_EQ(extension.isInitialised(), false); + ASSERT_EQ(response.getName(), domainName); + ASSERT_EQ(extension.getInfData()->getDSDataListSize(), 0); + ASSERT_EQ(extension.getInfData()->getKeyDataListSize(), 0); +} + +void assertFirstDSData(const SecDNSDSData* dsData) +{ + if (dsData != NULL) + { + ASSERT_EQ(dsData->getKeyTag(), 12345); + ASSERT_EQ(dsData->getAlg(), 3); + ASSERT_EQ(dsData->getDigestType(), 1); + ASSERT_EQ(dsData->getDigest(), "49FD46E6C4B45C55D4AC"); + + assertKeyData(dsData->getKeyData()); + } +} + +void assertKeyData(const SecDNSKeyData* keyData) +{ + if (keyData != NULL) + { + ASSERT_EQ(keyData->getFlags(), 256); + ASSERT_EQ(keyData->getProtocol(), 3); + ASSERT_EQ(keyData->getAlg(), 1); + ASSERT_EQ(keyData->getPubKey(), "AQPJ////4Q=="); + } +} + +void assertSecondDSData(const SecDNSDSData* dsData) +{ + if (dsData != NULL) + { + ASSERT_EQ(dsData->getKeyTag(), 14321); + ASSERT_EQ(dsData->getAlg(), 2); + ASSERT_EQ(dsData->getDigestType(), 5); + ASSERT_EQ(dsData->getDigest(), "39FD46E6C4B45C55D4AC"); + + ASSERT_NULL(dsData->getKeyData()); + } +} + +string getInfoResponseExpectedXml(const string& domainName, bool isMulitpleDs, + bool isKeyData, bool isDsData) +{ + ostringstream result; + buildXmlResponseBeforeExtension(domainName, result); + if (isKeyData || isDsData) + { + buildSecDNSXmlExtension(isMulitpleDs, isKeyData, isDsData, result); + } + buildXmlResponseAfterExtension(result); + + return result.str(); +} + +void buildXmlResponseAfterExtension(ostringstream& result) +{ + result << "" << "ABC-12345" + << "54321-XYZ" << "" << "" + << ""; +} + +void buildSecDNSXmlExtension(bool isMulitpleDs, bool isKeyData, bool isDsData, + ostringstream& result) +{ + result << "" + << "" + << "" + << "RegistrantName Pty. Ltd." + << "123456789" + << "Other" + << "Registrant Eligi" + << "987654321" + << "2" + << "" << "" + << "" + << "604800"; + + if (isDsData) + { + result << "" << "12345" + << "3" + << "1" + << "49FD46E6C4B45C55D4AC" + << "" << "256" + << "3" + << "1" + << "AQPJ////4Q==" + << "" << ""; + if (isMulitpleDs) + { + result << "" + << "14321" + << "2" + << "5" + << "39FD46E6C4B45C55D4AC" + << ""; + } + } + + if (isKeyData) + { + result << "" << "256" + << "3" + << "1" + << "AQPJ////4Q==" + << ""; + } + + result << "" << ""; +} + +void buildXmlResponseBeforeExtension(const string& domainName, + ostringstream& result) +{ + result << "" + << "" + << "" << "" + << "Command completed successfully" << "" + << "" + << "" + << "" + domainName + "" << "D0000003-AR" + << "" + << "EXAMPLE" + << "EXAMPLE" << "" + << "ns1.example.com.au" + << "ns2.example.com.au" << "" + << "ns1.example.com.au" + << "ns2.exmaple.com.au" << "Registrar" + << "Registrar" + << "2006-02-09T15:44:58.0Z" + << "2008-02-10T00:00:00.0Z" << "" + << "0192pqow" << "" << "" + << ""; +} + +int main(int argc, char* argv[]) +{ + init("etc/toolkit2.conf"); + TEST_run(testSecDNSInfoExtensionAllFields); + TEST_run(testSecDNSInfoExtensionOnlyKeyData); + TEST_run(testSecDNSInfoExtensionMultipleDsRecords); + TEST_run(testSecDNSInfoNoExtensionInitialised); + + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.cpp b/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.cpp new file mode 100644 index 0000000..bf6c2e7 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.cpp @@ -0,0 +1,40 @@ +#include "se/Command.hpp" +#include "SecDNSExtension.hpp" +#include "xml/XMLHelper.hpp" +#include "DomainSecDNSUpdateCommandExtension.hpp" + +namespace { + SecDNSExtension& secDNSExtension() { + static SecDNSExtension* secDNSExtension = new SecDNSExtension(); + return *secDNSExtension; + } +}; // anonymous namespace + +void DomainSecDNSUpdateCommandExtension::addToCommand(const Command &command) const +{ + XMLWriter* xmlWriter = command.getXmlWriter(); + DOMElement* extensionElement = command.getExtensionElement(); + DOMElement* updateElement = xmlWriter->appendChild(extensionElement, + "update", secDNSExtension().getURI()); + + if (urgent) + { + XMLHelper::setAttribute(updateElement, "urgent", "true"); + } + + if (remData.get() != NULL) + { + DOMElement* remElement = xmlWriter->appendChild(updateElement, "rem"); + remData->createXMLElement(xmlWriter, remElement); + } + if (addData.get() != NULL) + { + DOMElement* addElement = xmlWriter->appendChild(updateElement, "add"); + addData->createXMLElement(xmlWriter, addElement); + } + if (chgData.get() != NULL) + { + DOMElement* chgElement = xmlWriter->appendChild(updateElement, "chg"); + chgData->createXMLElement(xmlWriter, chgElement); + } +} diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.hpp b/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.hpp new file mode 100644 index 0000000..bc776f8 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtension.hpp @@ -0,0 +1,84 @@ +#ifndef SECDNSDOMAINUPDATECOMMANDEXTENSION_HPP_ +#define SECDNSDOMAINUPDATECOMMANDEXTENSION_HPP_ + +#include "se/CommandExtension.hpp" +#include "SecDNSRemType.hpp" +#include "SecDNSDSOrKeyType.hpp" +#include "SecDNSChgType.hpp" + +/** + * This class models the elements as defined in the + * AusRegistry secDNS-1.1 EPP command extension. + */ + +class DomainSecDNSUpdateCommandExtension : public CommandExtension +{ + public: + DomainSecDNSUpdateCommandExtension() : + urgent(false), + remData(NULL), + addData(NULL), + chgData(NULL) + {} + + virtual void addToCommand(const Command &command) const; + + void setUrgent(bool urgent); + + /** + * Set the remData. + * The memory of remData pointer will be handled by DomainSecDNSUpdateCommandExtension, + * memory will be auto freed when the extension instance is out of scope + * + * @param remData + * The remData in the command xml + * + */ + void setRemData(SecDNSRemType* remData); + + /** + * Set the addData. + * The memory of addData pointer will be handled by DomainSecDNSUpdateCommandExtension, + * memory will be auto freed when the extension instance is out of scope + * + * @param addData + * The addData in the command xml + * + */ + void setAddData(SecDNSDSOrKeyType* addData); + + /** + * Set the chgData. + * The memory of chgData pointer will be handled by DomainSecDNSUpdateCommandExtension, + * memory will be auto freed when the extension instance is out of scope + * + * @param chgData + * The chgData in the command xml + * + */ + void setChgData(SecDNSChgType* chgData); + private: + bool urgent; + std::auto_ptr remData; + std::auto_ptr addData; + std::auto_ptr chgData; +}; + +inline void DomainSecDNSUpdateCommandExtension::setUrgent(bool urgent) +{ + this->urgent = urgent; +} +inline void DomainSecDNSUpdateCommandExtension::setRemData(SecDNSRemType* remData) +{ + this->remData.reset(remData); +} +inline void DomainSecDNSUpdateCommandExtension::setAddData(SecDNSDSOrKeyType* addData) +{ + this->addData.reset(addData); +} +inline void DomainSecDNSUpdateCommandExtension::setChgData(SecDNSChgType* chgData) +{ + this->chgData.reset(chgData); +} + +#endif /* SECDNSDOMAINUPDATECOMMANDEXTENSION_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtensionTest.cpp b/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtensionTest.cpp new file mode 100644 index 0000000..64c2590 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/DomainSecDNSUpdateCommandExtensionTest.cpp @@ -0,0 +1,203 @@ +#include "xml/XMLParser.hpp" +#include "common/init.hpp" +#include "common/Test.hpp" +#include "session/Timer.hpp" +#include "SecDNSDSData.hpp" +#include "SecDNSKeyData.hpp" +#include "SecDNSDSOrKeyType.hpp" +#include "DomainSecDNSUpdateCommandExtension.hpp" +#include "se/DomainUpdateCommand.hpp" +#include "se/CLTRID.hpp" + +using namespace std; + +void testSecDNSAddFieldsUrgent() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + string passwd = "jtkUT3st"; + string registrantID = "JTKCON"; + DomainUpdateCommand updateCommand("jtkutest.com.au", &passwd, NULL, NULL, ®istrantID); + + auto_ptr dsData(new SecDNSDSData(12345, 3, 1, "49FD46E6C4B45C55D4AC")); + auto_ptr keyData(new SecDNSKeyData(256, 3, 1, "AQPJ////4Q==")); + dsData->setKeyData(keyData.release()); + + auto_ptr addData(new SecDNSDSOrKeyType()); + auto_ptr maxSigLife(new SecDNSMaxSigLifeType(604800)); + addData->setMaxSigLife(maxSigLife.release()); + addData->addToDSData(dsData.release()); + + DomainSecDNSUpdateCommandExtension extension; + extension.setUrgent(true); + extension.setAddData(addData.release()); + + updateCommand.appendExtension(extension); + + const string xml = updateCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.auJTKCONjtkUT3st604800123453149FD46E6C4B45C55D4AC25631AQPJ////4Q==JTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSRemoveFieldsNotUrgent() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + string passwd = "jtkUT3st"; + string registrantID = "JTKCON"; + DomainUpdateCommand updateCommand("jtkutest.com.au", &passwd, NULL, NULL, ®istrantID); + + auto_ptr dsData(new SecDNSDSData(65535, 255, 255, "49FD46E6C4B45C55D4AC")); + auto_ptr keyData(new SecDNSKeyData(65535, 255, 255, "AQPJ////4Q==")); + dsData->setKeyData(keyData.release()); + + auto_ptr remData(new SecDNSRemType()); + remData->addToDSData(dsData.release()); + + DomainSecDNSUpdateCommandExtension extension; + extension.setUrgent(false); + extension.setRemData(remData.release()); + + updateCommand.appendExtension(extension); + + const string xml = updateCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.auJTKCONjtkUT3st6553525525549FD46E6C4B45C55D4AC65535255255AQPJ////4Q==JTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSRemoveAll() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + string passwd = "jtkUT3st"; + string registrantID = "JTKCON"; + DomainUpdateCommand updateCommand("jtkutest.com.au", &passwd, NULL, NULL, ®istrantID); + + + auto_ptr remData(new SecDNSRemType()); + remData->setRemoveAll(true); + + DomainSecDNSUpdateCommandExtension extension; + extension.setUrgent(true); + extension.setRemData(remData.release()); + + updateCommand.appendExtension(extension); + + const string xml = updateCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.auJTKCONjtkUT3sttrueJTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSRemoveAllAndAddDsData() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + string passwd = "jtkUT3st"; + string registrantID = "JTKCON"; + DomainUpdateCommand updateCommand("jtkutest.com.au", &passwd, NULL, NULL, ®istrantID); + + + auto_ptr remData(new SecDNSRemType()); + remData->setRemoveAll(true); + + DomainSecDNSUpdateCommandExtension extension; + extension.setUrgent(true); + extension.setRemData(remData.release()); + + auto_ptr dsData(new SecDNSDSData(65535, 255, 255, "49FD46E6C4B45C55D4AC")); + auto_ptr addData(new SecDNSDSOrKeyType()); + addData->addToDSData(dsData.release()); + extension.setAddData(addData.release()); + + updateCommand.appendExtension(extension); + + const string xml = updateCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.auJTKCONjtkUT3sttrue6553525525549FD46E6C4B45C55D4ACJTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSRemoveAllAndAddKeyData() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + string passwd = "jtkUT3st"; + string registrantID = "JTKCON"; + DomainUpdateCommand updateCommand("jtkutest.com.au", &passwd, NULL, NULL, ®istrantID); + + + auto_ptr remData(new SecDNSRemType()); + remData->setRemoveAll(true); + + DomainSecDNSUpdateCommandExtension extension; + extension.setUrgent(true); + extension.setRemData(remData.release()); + + auto_ptr keyData(new SecDNSKeyData(65535, 255, 255, "AQPJ////4Q==")); + auto_ptr addData(new SecDNSDSOrKeyType()); + addData->addToKeyData(keyData.release()); + extension.setAddData(addData.release()); + + updateCommand.appendExtension(extension); + + const string xml = updateCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.auJTKCONjtkUT3sttrue65535255255AQPJ////4Q==JTKUTEST.20070101.010101.0" + ); +} + +void testSecDNSRemoveAllAndAddKeyDataAndChangeMaxSigLife() +{ + Timer::setTime("20070101.010101"); + CLTRID::setClID("JTKUTEST"); + + string passwd = "jtkUT3st"; + string registrantID = "JTKCON"; + DomainUpdateCommand updateCommand("jtkutest.com.au", &passwd, NULL, NULL, ®istrantID); + + + auto_ptr remData(new SecDNSRemType()); + remData->setRemoveAll(true); + + DomainSecDNSUpdateCommandExtension extension; + extension.setUrgent(true); + extension.setRemData(remData.release()); + + auto_ptr keyData(new SecDNSKeyData(65535, 255, 255, "AQPJ////4Q==")); + auto_ptr addData(new SecDNSDSOrKeyType()); + addData->addToKeyData(keyData.release()); + extension.setAddData(addData.release()); + + auto_ptr chgData(new SecDNSChgType()); + auto_ptr maxSigLifeType(new SecDNSMaxSigLifeType(604800)); + chgData->setMaxSigLife(maxSigLifeType.release()); + extension.setChgData(chgData.release()); + + updateCommand.appendExtension(extension); + + const string xml = updateCommand.toXML(); + ASSERT_EQ(xml, + "jtkutest.com.auJTKCONjtkUT3sttrue65535255255AQPJ////4Q==604800JTKUTEST.20070101.010101.0" + ); +} + +int main(int argc, char* argv[]) +{ + init("etc/toolkit2.conf"); + TEST_run(testSecDNSAddFieldsUrgent); + TEST_run(testSecDNSRemoveFieldsNotUrgent); + TEST_run(testSecDNSRemoveAll); + TEST_run(testSecDNSRemoveAllAndAddDsData); + TEST_run(testSecDNSRemoveAllAndAddKeyData); + TEST_run(testSecDNSRemoveAllAndAddKeyDataAndChangeMaxSigLife); + + return TEST_errorCount(); +} diff --git a/AusRegEPPTK/se/secDNS/SecDNSChgType.cpp b/AusRegEPPTK/se/secDNS/SecDNSChgType.cpp new file mode 100644 index 0000000..c5ab609 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSChgType.cpp @@ -0,0 +1,11 @@ +#include "xml/XMLHelper.hpp" +#include "SecDNSChgType.hpp" + +void SecDNSChgType::createXMLElement(XMLWriter* xmlWriter, DOMElement* chgElement) +{ + if (maxSigLife.get() != NULL) + { + maxSigLife->createXMLElement(xmlWriter, chgElement); + } +} + diff --git a/AusRegEPPTK/se/secDNS/SecDNSChgType.hpp b/AusRegEPPTK/se/secDNS/SecDNSChgType.hpp new file mode 100644 index 0000000..bb43af5 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSChgType.hpp @@ -0,0 +1,32 @@ +#ifndef SECDNSCHGTYPE_HPP_ +#define SECDNSCHGTYPE_HPP_ + +#include +#include + +#include "xercesc/dom/DOMElement.hpp" +#include "xml/XMLWriter.hpp" + +#include "SecDNSMaxSigLifeType.hpp" + +class SecDNSChgType +{ + public: + SecDNSChgType() : + maxSigLife(NULL) + {} + virtual ~SecDNSChgType() {}; + + void setMaxSigLife(SecDNSMaxSigLifeType* maxSigLife); + void createXMLElement(XMLWriter* xmlWriter, DOMElement* chgElement); + + private: + std::auto_ptr maxSigLife; +}; + +inline void SecDNSChgType::setMaxSigLife(SecDNSMaxSigLifeType* maxSigLife) +{ + this->maxSigLife.reset(maxSigLife); +} + +#endif /* SECDNSCHGTYPE_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/SecDNSDSData.cpp b/AusRegEPPTK/se/secDNS/SecDNSDSData.cpp new file mode 100644 index 0000000..cc58ced --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSDSData.cpp @@ -0,0 +1,16 @@ +#include "xml/XMLHelper.hpp" +#include "SecDNSDSData.hpp" + +void SecDNSDSData::appendDSDataElement(XMLWriter* xmlWriter, DOMElement* addElement) +{ + DOMElement* dsDataElement = xmlWriter->appendChild(addElement, "dsData"); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "keyTag"), keyTag); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "alg"), alg); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "digestType"), digestType); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "digest"), digest); + + if (keyData.get() != NULL) + { + keyData.get()->appendKeyDataElement(xmlWriter, dsDataElement); + } +} diff --git a/AusRegEPPTK/se/secDNS/SecDNSDSData.hpp b/AusRegEPPTK/se/secDNS/SecDNSDSData.hpp new file mode 100644 index 0000000..30f7447 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSDSData.hpp @@ -0,0 +1,95 @@ +#ifndef SECDNSDSDATA_HPP_ +#define SECDNSDSDATA_HPP_ + +#include + +#include "xercesc/dom/DOMElement.hpp" +#include "xml/XMLWriter.hpp" + +#include "SecDNSKeyData.hpp" + +class SecDNSDSData +{ + public: + SecDNSDSData() : + keyTag(0), + alg(0), + digestType(0), + digest("") + {} + + SecDNSDSData(int keyTag, int alg, int digestType, const std::string &digest) + { + setKeyTag(keyTag); + setAlg(alg); + setDigestType(digestType); + setDigest(digest); + } + + virtual ~SecDNSDSData() {} + + int getKeyTag() const; + int getAlg() const; + int getDigestType() const; + std::string getDigest() const; + SecDNSKeyData* getKeyData() const; + + void setKeyTag(int key_tag); + void setAlg(int alg); + void setDigestType(int digestType); + void setDigest(const std::string& digest); + + void setKeyData(SecDNSKeyData* keyData); + + void appendDSDataElement(XMLWriter* xmlWriter, DOMElement* addElement); + private: + int keyTag; + int alg; + int digestType; + std::string digest; + std::auto_ptr keyData; +}; + +inline int SecDNSDSData::getKeyTag() const +{ + return keyTag; +} +inline int SecDNSDSData::getAlg() const +{ + return alg; +} +inline int SecDNSDSData::getDigestType() const +{ + return digestType; +} +inline std::string SecDNSDSData::getDigest() const +{ + return digest; +} +inline SecDNSKeyData* SecDNSDSData::getKeyData() const +{ + return keyData.get(); +} + +inline void SecDNSDSData::setKeyTag(int key_tag) +{ + this->keyTag = key_tag; +} +inline void SecDNSDSData::setAlg(int alg) +{ + this->alg = alg; +} +inline void SecDNSDSData::setDigestType(int digestType) +{ + this->digestType = digestType; +} +inline void SecDNSDSData::setDigest(const std::string& digest) +{ + this->digest = digest; +} +inline void SecDNSDSData::setKeyData(SecDNSKeyData* keyData) +{ + this->keyData.reset(keyData); +} + +#endif /* SECDNSDSDATA_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.cpp b/AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.cpp new file mode 100644 index 0000000..cda2ef6 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.cpp @@ -0,0 +1,75 @@ +#include "xml/XMLHelper.hpp" +#include "SecDNSDSOrKeyType.hpp" + +void SecDNSDSOrKeyType::setMaxSigLife(SecDNSMaxSigLifeType* maxSigLife) +{ + this->maxSigLife.reset(maxSigLife); +} + +void SecDNSDSOrKeyType::addToDSData(SecDNSDSData* dsData) +{ + std::tr1::shared_ptr dsDataPtr(dsData); + dsDataList.push_back(dsDataPtr); +} + +void SecDNSDSOrKeyType::addToKeyData(SecDNSKeyData* keyData) +{ + std::tr1::shared_ptr keyDataPtr(keyData); + keyDataList.push_back(keyDataPtr); +} + +int SecDNSDSOrKeyType::getDSDataListSize() +{ + return dsDataList.size(); +} + +std::tr1::shared_ptr SecDNSDSOrKeyType::getDSData(int index) const +{ + return dsDataList.at(index); +} + +std::tr1::shared_ptr SecDNSDSOrKeyType::getDSData(int index) +{ + return dsDataList.at(index); +} + +int SecDNSDSOrKeyType::getKeyDataListSize() +{ + return keyDataList.size(); +} + +std::tr1::shared_ptr SecDNSDSOrKeyType::getKeyData(int index) const +{ + return keyDataList.at(index); +} + +std::tr1::shared_ptr SecDNSDSOrKeyType::getKeyData(int index) +{ + return keyDataList.at(index); +} + +void SecDNSDSOrKeyType::createXMLElement(XMLWriter* xmlWriter, DOMElement* addElement) +{ + + if (maxSigLife.get() != NULL) + { + maxSigLife->createXMLElement(xmlWriter, addElement); + } + + std::vector >::const_iterator ds_list_iterator; + for (ds_list_iterator = dsDataList.begin(); + ds_list_iterator != dsDataList.end(); + ds_list_iterator++) + { + ds_list_iterator->get()->appendDSDataElement(xmlWriter, addElement); + } + + std::vector >::const_iterator key_list_iterator; + for (key_list_iterator = keyDataList.begin(); + key_list_iterator != keyDataList.end(); + key_list_iterator++) + { + key_list_iterator->get()->appendKeyDataElement(xmlWriter, addElement); + } +} + diff --git a/AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.hpp b/AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.hpp new file mode 100644 index 0000000..6add017 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSDSOrKeyType.hpp @@ -0,0 +1,44 @@ +#ifndef SECDNSDSORKEYTYPE_HPP_ +#define SECDNSDSORKEYTYPE_HPP_ + +#include +#include + +#include "xercesc/dom/DOMElement.hpp" +#include "xml/XMLWriter.hpp" + +#include "SecDNSMaxSigLifeType.hpp" +#include "SecDNSKeyData.hpp" +#include "SecDNSDSData.hpp" + +class SecDNSDSOrKeyType +{ + public: + SecDNSDSOrKeyType() : + maxSigLife(NULL), + dsDataList(), + keyDataList() + {} + virtual ~SecDNSDSOrKeyType() {}; + + void setMaxSigLife(SecDNSMaxSigLifeType* maxSigLife); + void addToDSData(SecDNSDSData* dsData); + void addToKeyData(SecDNSKeyData* keyData); + + int getDSDataListSize(); + std::tr1::shared_ptr getDSData(int index) const; + std::tr1::shared_ptr getDSData(int index); + + int getKeyDataListSize(); + std::tr1::shared_ptr getKeyData(int index) const; + std::tr1::shared_ptr getKeyData(int index); + + void createXMLElement(XMLWriter* xmlWriter, DOMElement* addElement); + + private: + std::auto_ptr maxSigLife; + std::vector > dsDataList; + std::vector > keyDataList; +}; + +#endif /* SECDNSDSORKEYTYPE_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/SecDNSExtension.cpp b/AusRegEPPTK/se/secDNS/SecDNSExtension.cpp new file mode 100644 index 0000000..46ecf60 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSExtension.cpp @@ -0,0 +1,13 @@ +#include "SecDNSExtension.hpp" + +std::string& SecDNSExtension::getURI() const +{ + static std::string uri = "urn:ietf:params:xml:ns:secDNS-1.1"; + return uri; +} + +std::string& SecDNSExtension::getSchemaLocation() const +{ + static std::string loc = "urn:ietf:params:xml:ns:secDNS-1.1 secDNS-1.1.xsd"; + return loc; +} diff --git a/AusRegEPPTK/se/secDNS/SecDNSExtension.hpp b/AusRegEPPTK/se/secDNS/SecDNSExtension.hpp new file mode 100644 index 0000000..12de07c --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSExtension.hpp @@ -0,0 +1,27 @@ +#ifndef __SECDNSEXTENSION_HPP +#define __SECDNSEXTENSION_HPP + +#include + +#include "se/Extension.hpp" + +class SecDNSExtension : public Extension +{ +public: + + virtual ~SecDNSExtension(void) { } + + /** + * Get the globally unique namespace URI which identifies this extension. + */ + virtual std::string& getURI() const; + + /** + * Get the location hint for the XML schema used to validate EPP service + * element instances using this extension. + */ + virtual std::string& getSchemaLocation() const; +}; + +#endif // __SECDNSEXTENSION_HPP + diff --git a/AusRegEPPTK/se/secDNS/SecDNSKeyData.cpp b/AusRegEPPTK/se/secDNS/SecDNSKeyData.cpp new file mode 100644 index 0000000..c9f0447 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSKeyData.cpp @@ -0,0 +1,11 @@ +#include "xml/XMLHelper.hpp" +#include "SecDNSKeyData.hpp" + +void SecDNSKeyData::appendKeyDataElement(XMLWriter* xmlWriter, DOMElement* addElement) +{ + DOMElement* dsDataElement = xmlWriter->appendChild(addElement, "keyData"); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "flags"), flags); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "protocol"), protocol); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "alg"), alg); + XMLHelper::setTextContent(xmlWriter->appendChild(dsDataElement, "pubKey"), pubKey); +} diff --git a/AusRegEPPTK/se/secDNS/SecDNSKeyData.hpp b/AusRegEPPTK/se/secDNS/SecDNSKeyData.hpp new file mode 100644 index 0000000..02d45c2 --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSKeyData.hpp @@ -0,0 +1,80 @@ +#ifndef SECDNSKEYDATA_HPP_ +#define SECDNSKEYDATA_HPP_ + +#include + +#include "xercesc/dom/DOMElement.hpp" +#include "xml/XMLWriter.hpp" + + +class SecDNSKeyData +{ + public: + SecDNSKeyData() : + flags(0), + protocol(0), + alg(0), + pubKey("") + {} + + SecDNSKeyData(int flags, int protocal, int alg, const std::string &pubKey) + { + setFlags(flags); + setProtocol(protocal); + setAlg(alg); + setPubKey(pubKey); + } + + virtual ~SecDNSKeyData() {} + + int getFlags() const; + int getProtocol() const; + int getAlg() const; + std::string getPubKey() const; + + void setFlags(int flags); + void setProtocol(int protocol); + void setAlg(int alg); + void setPubKey(const std::string& pubKey); + + void appendKeyDataElement(XMLWriter* xmlWriter, DOMElement* addElement); + private: + int flags; + int protocol; + int alg; + std::string pubKey; +}; + +inline int SecDNSKeyData::getFlags() const +{ + return flags; +} +inline int SecDNSKeyData::getProtocol() const +{ + return protocol; +} +inline int SecDNSKeyData::getAlg() const +{ + return alg; +} +inline std::string SecDNSKeyData::getPubKey() const +{ + return pubKey; +} +inline void SecDNSKeyData::setFlags(int flags) +{ + this->flags = flags; +} +inline void SecDNSKeyData::setProtocol(int protocol) +{ + this->protocol = protocol; +} +inline void SecDNSKeyData::setAlg(int alg) +{ + this->alg = alg; +} +inline void SecDNSKeyData::setPubKey(const std::string& pubKey) +{ + this->pubKey = pubKey; +} +#endif /* SECDNSKEYDATA_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/SecDNSMaxSigLifeType.hpp b/AusRegEPPTK/se/secDNS/SecDNSMaxSigLifeType.hpp new file mode 100644 index 0000000..4ba4f1b --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSMaxSigLifeType.hpp @@ -0,0 +1,30 @@ +#ifndef SECDNSMAXSIGLIFETYPE_HPP_ +#define SECDNSMAXSIGLIFETYPE_HPP_ + +#include +#include + +#include "xercesc/dom/DOMElement.hpp" +#include "xml/XMLWriter.hpp" +#include "xml/XMLHelper.hpp" + +class SecDNSMaxSigLifeType +{ + public: + SecDNSMaxSigLifeType(int maxSigLife) : + maxSigLife(maxSigLife) + {} + virtual ~SecDNSMaxSigLifeType() {}; + + void createXMLElement(XMLWriter* xmlWriter, DOMElement* element); + + private: + int maxSigLife; +}; + +inline void SecDNSMaxSigLifeType::createXMLElement(XMLWriter* xmlWriter, DOMElement* element) +{ + XMLHelper::setTextContent(xmlWriter->appendChild(element, "maxSigLife"), maxSigLife); +} + +#endif /* SECDNSMAXSIGLIFETYPE_HPP_ */ diff --git a/AusRegEPPTK/se/secDNS/SecDNSRemType.cpp b/AusRegEPPTK/se/secDNS/SecDNSRemType.cpp new file mode 100644 index 0000000..75e48dc --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSRemType.cpp @@ -0,0 +1,27 @@ +#include "xml/XMLHelper.hpp" +#include "SecDNSRemType.hpp" + +void SecDNSRemType::createXMLElement(XMLWriter* xmlWriter, DOMElement* remElement) +{ + if (removeAll) + { + XMLHelper::setTextContent(xmlWriter->appendChild(remElement, "all"), "true"); + } + + std::list >::const_iterator ds_list_iterator; + for (ds_list_iterator = dsDataList.begin(); + ds_list_iterator != dsDataList.end(); + ds_list_iterator++) + { + ds_list_iterator->get()->appendDSDataElement(xmlWriter, remElement); + } + + std::list >::const_iterator key_list_iterator; + for (key_list_iterator = keyDataList.begin(); + key_list_iterator != keyDataList.end(); + key_list_iterator++) + { + key_list_iterator->get()->appendKeyDataElement(xmlWriter, remElement); + } +} + diff --git a/AusRegEPPTK/se/secDNS/SecDNSRemType.hpp b/AusRegEPPTK/se/secDNS/SecDNSRemType.hpp new file mode 100644 index 0000000..f27c46a --- /dev/null +++ b/AusRegEPPTK/se/secDNS/SecDNSRemType.hpp @@ -0,0 +1,51 @@ +#ifndef SECDNSREMTYPE_HPP_ +#define SECDNSREMTYPE_HPP_ + +#include +#include + +#include "xercesc/dom/DOMElement.hpp" +#include "xml/XMLWriter.hpp" + +#include "SecDNSKeyData.hpp" +#include "SecDNSDSData.hpp" + +class SecDNSRemType +{ + public: + SecDNSRemType() : + removeAll(false), + dsDataList(), + keyDataList() + {} + virtual ~SecDNSRemType() {}; + + void setRemoveAll(bool removeAll); + void addToDSData(SecDNSDSData* dsData); + void addToKeyData(SecDNSKeyData* keyData); + + void createXMLElement(XMLWriter* xmlWriter, DOMElement* remElement); + + private: + bool removeAll; + std::list > dsDataList; + std::list > keyDataList; +}; + +inline void SecDNSRemType::setRemoveAll(bool removeAll) +{ + this->removeAll = removeAll; +} +inline void SecDNSRemType::addToDSData(SecDNSDSData* dsData) +{ + std::tr1::shared_ptr dsDataPtr(dsData); + dsDataList.push_back(dsDataPtr); +} +inline void SecDNSRemType::addToKeyData(SecDNSKeyData* keyData) +{ + std::tr1::shared_ptr keyDataPtr(keyData); + keyDataList.push_back(keyDataPtr); +} + + +#endif /* SECDNSREMTYPE_HPP_ */ diff --git a/AusRegEPPTK/session/CertificateUserMismatchException.cpp b/AusRegEPPTK/session/CertificateUserMismatchException.cpp new file mode 100644 index 0000000..6e6dbf0 --- /dev/null +++ b/AusRegEPPTK/session/CertificateUserMismatchException.cpp @@ -0,0 +1,33 @@ +#include "session/CertificateUserMismatchException.hpp" +#include "common/ErrorPkg.hpp" + +std::vector CertificateUserMismatchException::USER_CN_ARR; + + +CertificateUserMismatchException::CertificateUserMismatchException + (const std::string &clID, const std::string &cn) +{ + std::vector ctor; + ctor.push_back (clID); + ctor.push_back (cn); + + const std::vector &p = getCertificateUser(); + std::string msg = ErrorPkg::getMessage ("epp.login.fail.auth.match", + p, + ctor); + + // LoginException (msg); +} + +const std::vector & CertificateUserMismatchException::getCertificateUser() +{ + if (USER_CN_ARR.size() == 0) + { + USER_CN_ARR.push_back ("<>"); + USER_CN_ARR.push_back ("<>"); + } + + return USER_CN_ARR; +} + + diff --git a/AusRegEPPTK/session/CertificateUserMismatchException.hpp b/AusRegEPPTK/session/CertificateUserMismatchException.hpp new file mode 100644 index 0000000..073eabf --- /dev/null +++ b/AusRegEPPTK/session/CertificateUserMismatchException.hpp @@ -0,0 +1,25 @@ +#ifndef __CERTIFICATE_USER_MISMATCH_EXCEPTION_HPP +#define __CERTIFICATE_USER_MISMATCH_EXCEPTION_HPP + +#include "session/LoginException.hpp" + +#include +#include + +class CertificateUserMismatchException : public LoginException +{ +public: + CertificateUserMismatchException + (const std::string &msg = "Username does not match certificate common name") + : LoginException(msg) {}; + + CertificateUserMismatchException + (const std::string &clID, const std::string &pw); + +private: + static std::vector USER_CN_ARR; +protected: + static const std::vector & getCertificateUser(); +}; + +#endif // __CERTIFICATE_USER_MISMATCH_EXCEPTION_HPP diff --git a/AusRegEPPTK/session/CommandCounter.cpp b/AusRegEPPTK/session/CommandCounter.cpp new file mode 100644 index 0000000..702fb90 --- /dev/null +++ b/AusRegEPPTK/session/CommandCounter.cpp @@ -0,0 +1,106 @@ +#include "se/CommandType.hpp" + +#include "session/CommandCounter.hpp" +#include "session/Timer.hpp" + +CommandCounter::CommandCounter (int resetInterval) + : recentTotal(0), resetInterval(resetInterval), total(0) +{ } + +CommandCounter::~CommandCounter() +{ + CommandTimeMapType::iterator p; + + for (p = recentMap.begin(); p != recentMap.end(); p++) + delete p->second; +} + +void CommandCounter::increment(const CommandType* type) +{ + StringUtils::HashType hash = type->hash(); + + // increment total for command type. + CommandCountMapType::iterator q; + if ((q = totalMap.find(hash)) != totalMap.end()) + { + q->second += 1; + } + else + { + totalMap.insert(std::make_pair(hash, 1)); + } + + // add command time to recent list for that command + TimeList *timeList; + CommandTimeMapType::iterator p = recentMap.find(hash); + if ((p = recentMap.find(hash)) != recentMap.end()) + { + timeList = p->second; + clean(timeList); + } + else + { + timeList = new TimeList; + recentMap.insert(std::make_pair(hash, timeList)); + } + timeList->push_back(Timer::now()); + recentTotal++; + total++; +} + +int CommandCounter::getCount(const CommandType* type) const +{ + StringUtils::HashType hash = type->hash(); + + CommandCountMapType::const_iterator p; + if((p = totalMap.find(hash)) == totalMap.end()) + return 0; + else + return p->second; +} + +int CommandCounter::getRecentCount(const CommandType* type) +{ + StringUtils::HashType hash = type->hash(); + + CommandTimeMapType::iterator p = recentMap.find(hash); + if (p == recentMap.end()) + { + return 0; + } + else + { + return clean(p->second); + } +} + +int CommandCounter::getRecentExactTotal() +{ + CommandTimeMapType::iterator i; + for(i = recentMap.begin(); i != recentMap.end(); ++i) + { + clean(i->second); + } + return recentTotal; +} + +int CommandCounter::clean(TimeList *timeList) +{ + TimeList::iterator listIter; + + // 'now' is milliseconds. + long long now = Timer::now(); + while ((listIter = timeList->begin()) != timeList->end()) + { + if (now - *listIter > static_cast(resetInterval)) + { + timeList->pop_front(); + recentTotal--; + } + else + { + break; + } + } + return timeList->size(); +} diff --git a/AusRegEPPTK/session/CommandCounter.hpp b/AusRegEPPTK/session/CommandCounter.hpp new file mode 100644 index 0000000..b39144a --- /dev/null +++ b/AusRegEPPTK/session/CommandCounter.hpp @@ -0,0 +1,65 @@ +#ifndef __COMMANDCOUNTER_H +#define __COMMANDCOUNTER_H + +#include +#include +#include + +class CommandType; + +class CommandCounter +{ +public: + + /// @param resetInterval Milliseconds. + CommandCounter(int resetInterval = DEFAULT_RESET_INTERVAL); + ~CommandCounter(); + + /** Count a command of type 'type'. */ + void increment(const CommandType* type); + + /** Get the approximate number of commands of the given type recorded by + * this counter. */ + int getRecentCount(const CommandType* type); + + /** Get the total number of commands of the given type recorded by this + * counter. */ + int getCount(const CommandType* type) const; + + /** Cet the the total number of commands of all types recorded by this + * counter. */ + int getTotal() const { return total; } + + /** Get an approximation of the total number of commands processed recently. */ + int getRecentTotal() const { return recentTotal; } + + /** Get the number of commands of the given type processed recently (within + * the reset interval from now). */ + int getRecentExactTotal(); + +private: + CommandCounter(const CommandCounter& rhs); + CommandCounter& operator=(const CommandCounter& rhs); + + // milliseconds. + typedef long long Time; // milli seconds. + + // oldest times towards the head of the list + typedef std::list