Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejava
titleFremsøgningslogik for Dokumentdelingsservice - herunder auditloging
collapsetrue
public class DDSRegistryQueryImpl {
	static Logger logger = Logger.getLogger(DDSRegistryQueryImpl.class);

	@Autowired
	private AuditLogning auditLogning;

	...

	public AdhocQueryResponse documentRegistryRegistryStoredQuery(AdhocQueryRequest adhocQueryRequestBody, DDSContext context) throws Exception {
		try {
			final AdhocQueryRequestWrapper adhocQueryRequestWrapper = new AdhocQueryRequestWrapper(adhocQueryRequestBody, context);
			String patientId = adhocQueryRequestWrapper.getPatientId();			
			...			
			AuditBuilder auditBuilder = Audit.createAuditBuilder();
			auditLogning.auditLogIti18Response(auditBuilder, patientId, context.getActingUserCivilRegistrationNumber(), context.getResponsibleUserCivilRegistrationNumber(), adhocQueryRequestBody.getAdhocQuery(), response);
			return response;
		} catch (NegativeConsentException e) {
			return AdhocQueryResponseWrapper.createNegativeConsentResponse();
		}
	}

...

Code Block
languagejava
titleAuditLogning klasse til anvendelse af AuditAPI
collapsetrue
public class AuditLogning {

	public static final String KEY_PATIENT_CPR = "patient-cpr";
	public static final String KEY_USER_CPR = "bruger-cpr";
	public static final String KEY_USER_ON_BEHALF_OF_CPR = "on-behalf-of-cpr";
	public static final String KEY_DOCUMENT_ENTRY = "document_entry";


	private static final String ITI_18_CONTEXT = "documentRegistryAdhocQuery";
	private static final String ITI_43_CONTEXT = "documentRepositoryRetrieveDocumentSet";

	private static final String DOCUMENTENTRY_HOMECOMMUNITY_ID = "homecommunityid";
	private static final String DOCUMENTENTRY_REPOSITORY_ID = "repositoryid";
	private static final String DOCUMENTENTRY_DOCUMENT_ID = "documentid";
	private static final String DOCUMENTENTRY_TYPECODE = "typecode";
	private static final String KEY_QUERY_TYPECODE = "queryTypecode";

	private String componentName;

	public AuditLogning() {
		this("DDS");
	}
	
	public AuditLogning(String componentName) {
		this.componentName = componentName;
	}

	public void auditLogIti18Response(AuditBuilder auditBuilder, String patientCpr, String requestingUserCpr, String requestingUserOnBehalfOfCpr, AdhocQueryType adhocQueryType, AdhocQueryResponse adhocQueryResponse) {

		auditBuilder.addAuditInformation(componentName, ITI_18_CONTEXT, TypeOfInformation.RegularPersonalInformation, KEY_PATIENT_CPR, patientCpr);
		if (requestingUserCpr != null) {
			auditBuilder.addAuditInformation(componentName, ITI_18_CONTEXT, TypeOfInformation.RegularPersonalInformation, KEY_USER_CPR, requestingUserCpr);
		}
		if (requestingUserOnBehalfOfCpr != null) {
			auditBuilder.addAuditInformation(componentName, ITI_18_CONTEXT, TypeOfInformation.RegularPersonalInformation, KEY_USER_ON_BEHALF_OF_CPR, requestingUserOnBehalfOfCpr);
		}

		if (adhocQueryType != null && adhocQueryType.getSlot() != null) {
			ValueListType vlt = XDSValueFinder.getSearchParameterTypeCode(adhocQueryType.getSlot());
			if (vlt != null && vlt.getValue() != null) {
				auditBuilder.addAuditInformation(componentName, ITI_18_CONTEXT, TypeOfInformation.NonPersonalInformation, KEY_QUERY_TYPECODE, vlt.getValue());
			}
		}
		
		if (adhocQueryResponse.getRegistryObjectList() != null && adhocQueryResponse.getRegistryObjectList().getIdentifiable() != null) {
			Iterator<JAXBElement<? extends oasis.names.tc.ebxml_regrep.xsd.rim._3.IdentifiableType>> identifiables = adhocQueryResponse.getRegistryObjectList().getIdentifiable().iterator();
			int count = 0;
			while (identifiables.hasNext()) {
				JAXBElement<? extends oasis.names.tc.ebxml_regrep.xsd.rim._3.IdentifiableType> identifiable = identifiables.next();
				ExtrinsicObjectType documentEntry = XDSValueFinder.getAsDocumentEntry(identifiable);
				DocumentEntryExternalId documentEntryExternalId = XDSValueFinder.getDocumentEntryExternalId(documentEntry);
				String typeCode = XDSValueFinder.getTypeCodeValueInClassificiationList(documentEntry.getClassification());
				addDocumentEntryAsAuditLogValue(auditBuilder, ITI_18_CONTEXT, count++, documentEntryExternalId, typeCode);
			}
		}
	}

	public void addDocumentEntryAsAuditLogValue(AuditBuilder auditBuilder, String context, int count, String homeCommunityId, String repositoryId, String documentId, String typeCode) {
		
		if (homeCommunityId != null) {
			auditBuilder.addAuditInformation(componentName, context, TypeOfInformation.SensitivePersonalInformation, formatKey(KEY_DOCUMENT_ENTRY, count, DOCUMENTENTRY_HOMECOMMUNITY_ID), homeCommunityId);
		}
		auditBuilder.addAuditInformation(componentName, context, TypeOfInformation.SensitivePersonalInformation, formatKey(KEY_DOCUMENT_ENTRY, count, DOCUMENTENTRY_REPOSITORY_ID), repositoryId);
		auditBuilder.addAuditInformation(componentName, context, TypeOfInformation.SensitivePersonalInformation, formatKey(KEY_DOCUMENT_ENTRY, count, DOCUMENTENTRY_DOCUMENT_ID), documentId);

		if (typeCode != null) {
			auditBuilder.addAuditInformation(componentName, context, TypeOfInformation.SensitivePersonalInformation, formatKey(KEY_DOCUMENT_ENTRY, count, DOCUMENTENTRY_TYPECODE), typeCode);
		}
	}
	
	public String formatKey(String prefix, int count, String postfix) {
		return prefix+"."+count+"."+postfix;
	}

Som det kan ses i det ovenstående, så kaldes addAuditInformation flere gange i forbindelse med en søgning. Anvendelse af konstanter sørger for, at parametrene componentName og context sfds sendes ensartet videre til NSP Audit API.

Ved hver tilføjelse af auditinformation tages der aktivt stilling til oplysningernes følsomhed.

I Dokumentdelingsservicen auditlogges hele svaret dvs. alle de elementer, der fremsøges. I eksemplet ovenfor konstrueres en nøgle udfra bla en tæller (count) for at auditloggen kan indeholde en liste.

Effekt af NSP Audit API i NSP komponenter

...