release version 1.10.0
This commit is contained in:
@ -0,0 +1,5 @@
|
||||
<!-- -->
|
||||
<configfile finalname="etc/ru.entaxy.audit.interpreter.jmx.cfg" override="true">
|
||||
mvn:ru.entaxy.platform.logging/entaxy-audit/1.10.0/cfg/ru.entaxy.audit.interpreter.jmx
|
||||
</configfile>
|
||||
<!-- -->
|
@ -0,0 +1,27 @@
|
||||
###
|
||||
# ~~~~~~licensing~~~~~~
|
||||
# entaxy-audit
|
||||
# ==========
|
||||
# Copyright (C) 2020 - 2024 EmDev LLC
|
||||
# ==========
|
||||
# You may not use this file except in accordance with the License Terms of the Copyright
|
||||
# Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
# rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
# it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
# Software for commercial purposes to provide services to third parties.
|
||||
#
|
||||
# The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
# Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
# Software provided by him will be suitable or not suitable for the specific purposes
|
||||
# of the User, that the Software will meet all commercial and personal subjective
|
||||
# expectations of the User, that the Software will work properly, without technical
|
||||
# errors, quickly and uninterruptedly.
|
||||
#
|
||||
# Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
# to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
# damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
# or damage to data, property, etc.
|
||||
# ~~~~~~/licensing~~~~~~
|
||||
###
|
||||
topics.ignore=GETATTRIBUTE,GETMBEANINFO
|
||||
topics.process=INVOKE
|
@ -0,0 +1,31 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.data;
|
||||
|
||||
public enum Actions {
|
||||
LOGIN,
|
||||
LOGOUT
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.data;
|
||||
|
||||
import ru.entaxy.audit.utils.AuditHelper;
|
||||
|
||||
public class AuditEvent {
|
||||
private final String target;
|
||||
private final String category;
|
||||
private final String suser;
|
||||
private final String duser;
|
||||
private final String message;
|
||||
private final Outcome outcome;
|
||||
|
||||
private final Severity severity;
|
||||
private final String src;
|
||||
|
||||
public AuditEvent(String target, String category, String suser,
|
||||
String duser, String message, Outcome outcome,
|
||||
Severity severity, String src) {
|
||||
this.target = target;
|
||||
this.category = category;
|
||||
this.suser = suser;
|
||||
this.duser = duser;
|
||||
this.message = message;
|
||||
this.outcome = outcome;
|
||||
this.severity = severity;
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public String getSuser() {
|
||||
return suser;
|
||||
}
|
||||
|
||||
public String getDuser() {
|
||||
return duser;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Outcome getOutcome() {
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public Severity getSeverity() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
public String getSrc() {
|
||||
return src;
|
||||
}
|
||||
|
||||
public static class AuditLoggingEventBuilder {
|
||||
private String target = AuditHelper.DEFAULT_TARGET;
|
||||
private String category;
|
||||
private String suser;
|
||||
private String duser;
|
||||
private String message;
|
||||
|
||||
private String src;
|
||||
private Outcome outcome = Outcome.SUCCESS;
|
||||
private Severity severity = AuditHelper.DEFAULT_SEVERITY;
|
||||
|
||||
|
||||
public static AuditLoggingEventBuilder getInstance() {
|
||||
return new AuditLoggingEventBuilder();
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder target(String target) {
|
||||
this.target = target;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder category(String category) {
|
||||
this.category = category;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder suser(String suser) {
|
||||
this.suser = suser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder duser(String duser) {
|
||||
this.duser = duser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder message(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder outcome(Outcome outcome) {
|
||||
this.outcome = outcome;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder severity(Severity severity) {
|
||||
this.severity = severity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditLoggingEventBuilder src(String src) {
|
||||
this.src = src;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuditEvent build() {
|
||||
return new AuditEvent(target, category, suser, duser,
|
||||
message, outcome, severity, src);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.data;
|
||||
|
||||
public enum Outcome {
|
||||
SUCCESS("Success"), FAILURE("Failed");
|
||||
private final String label;
|
||||
|
||||
Outcome(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.data;
|
||||
|
||||
public enum Severity {
|
||||
INFO(3), WARNING(8), IMPORTANT(6);
|
||||
|
||||
private final int value;
|
||||
|
||||
Severity(int i) {
|
||||
this.value = i;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.data.Outcome;
|
||||
|
||||
|
||||
public interface AuditService {
|
||||
void onAudit(AuditEvent record);
|
||||
|
||||
void onLogin(String username, HttpServletRequest request, Outcome outcome);
|
||||
|
||||
void onLogout(String username, HttpServletRequest request);
|
||||
|
||||
void onOSGIEvent(Event event);
|
||||
|
||||
void onFileChange(Event event);
|
||||
|
||||
boolean interpret(Event event);
|
||||
|
||||
void setRequestAndSubject(Subject subject, HttpServletRequest request);
|
||||
|
||||
void setRequestAndUser(String user, HttpServletRequest request);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service;
|
||||
|
||||
import ru.entaxy.audit.service.impl.AuditServiceImpl;
|
||||
|
||||
public class AuditServiceFactory {
|
||||
private static final AuditServiceImpl INSTANCE = new AuditServiceImpl();
|
||||
|
||||
|
||||
public static AuditService getAuditService() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service;
|
||||
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
|
||||
public interface EventConverter {
|
||||
|
||||
default Class<? extends InterpretedEvent>[] getAllowedClasses() {
|
||||
if (getClass().isAnnotationPresent(EventConverterInfo.class)) {
|
||||
return getClass().getAnnotation(EventConverterInfo.class).classes();
|
||||
}
|
||||
return new Class[] {};
|
||||
};
|
||||
|
||||
<T extends InterpretedEvent> AuditEvent convert(T event);
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RUNTIME)
|
||||
@Target(TYPE)
|
||||
public @interface EventConverterInfo {
|
||||
|
||||
Class<? extends InterpretedEvent>[] classes();
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
public interface EventInterpreter {
|
||||
|
||||
InterpretedEvent interpret(Event origin);
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
import org.osgi.service.event.EventHandler;
|
||||
import ru.entaxy.audit.service.filter.EventRouter;
|
||||
|
||||
public class EventSubscriber implements EventHandler {
|
||||
private final EventRouter eventRouter;
|
||||
|
||||
public EventSubscriber(EventRouter eventRouter) {
|
||||
this.eventRouter = eventRouter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
eventRouter.consumeEvent(event);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
public class InterpretedEvent {
|
||||
|
||||
public enum EventResolution {
|
||||
IGNORE,
|
||||
PROCESS,
|
||||
NONE
|
||||
}
|
||||
|
||||
public Event originalEvent;
|
||||
|
||||
public EventResolution resolution = EventResolution.NONE;
|
||||
|
||||
protected Map<String, Object> eventEssense = new HashMap<>();
|
||||
|
||||
public InterpretedEvent(Event origin) {
|
||||
this.originalEvent = origin;
|
||||
eventEssense.put("event.topic", origin.getTopic());
|
||||
}
|
||||
|
||||
public Map<String, Object> getEventEssense() {
|
||||
return eventEssense;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.filter;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.audit.service.AuditService;
|
||||
|
||||
public class EventRouter {
|
||||
private final Queue<Event> events = new LinkedBlockingQueue<>(10_000);
|
||||
private final AtomicLong counter = new AtomicLong(0);
|
||||
private final AtomicLong consumed = new AtomicLong(0);
|
||||
private final AtomicLong rejected = new AtomicLong(0);
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(3,
|
||||
(r) -> new Thread(r, "audit-logger-helper-thread #" + counter.getAndIncrement()));
|
||||
private final AuditService auditService;
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EventRouter.class);
|
||||
|
||||
public EventRouter(AuditService service) {
|
||||
this.auditService = service;
|
||||
}
|
||||
|
||||
private boolean processEvent(Event event) {
|
||||
if (event == null) {
|
||||
return false;
|
||||
}
|
||||
if (event.getTopic().contains("EXECUTED") && event.getProperty("command") != null) {
|
||||
auditService.onOSGIEvent(event);
|
||||
return true;
|
||||
} else {
|
||||
// if it's a log event
|
||||
if (event.getTopic().startsWith("org/osgi/service/log")) {
|
||||
String bundleSymbolicName = (String) event.getProperty("bundle.symbolicname");
|
||||
// if it's configuration update event
|
||||
if (bundleSymbolicName != null && "org.apache.felix.fileinstall".equals(bundleSymbolicName)) {
|
||||
Object message = event.getProperty("message");
|
||||
if (message instanceof String) {
|
||||
String messageText = (String) message;
|
||||
if (messageText.contains("Updating")) {
|
||||
auditService.onFileChange(event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return auditService.interpret(event);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String stats() {
|
||||
return String.format("Consumed: %d, rejected: %d", consumed.get(), rejected.get());
|
||||
}
|
||||
|
||||
public void consumeEvent(Event event) {
|
||||
boolean added = events.offer(event);
|
||||
if (added) {
|
||||
executor.submit(() -> {
|
||||
Event evt = events.poll();
|
||||
if (processEvent(evt)) {
|
||||
consumed.incrementAndGet();
|
||||
} else {
|
||||
rejected.incrementAndGet();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
LOGGER.warn("Cannot consume event {}, queue is probably full", event);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
executor.shutdown();
|
||||
events.clear();
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.hawtio;
|
||||
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.data.Outcome;
|
||||
import ru.entaxy.audit.data.Severity;
|
||||
import ru.entaxy.audit.service.EventConverter;
|
||||
import ru.entaxy.audit.service.EventConverterInfo;
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
|
||||
@Component(service = EventConverter.class, immediate = true)
|
||||
@EventConverterInfo(classes = {HawtioInterpretedEvent.class})
|
||||
public class HawtioEventConverter implements EventConverter {
|
||||
|
||||
@Override
|
||||
public <T extends InterpretedEvent> AuditEvent convert(T event) {
|
||||
if (!(event instanceof HawtioInterpretedEvent))
|
||||
return null;
|
||||
|
||||
HawtioInterpretedEvent hawtioEvent = (HawtioInterpretedEvent) event;
|
||||
|
||||
AuditEvent result = AuditEvent.AuditLoggingEventBuilder.getInstance()
|
||||
.target("auth")
|
||||
.outcome(hawtioEvent.isSuccessful ? Outcome.SUCCESS : Outcome.FAILURE)
|
||||
.message(String.format("%s", hawtioEvent.getMessage()))
|
||||
.severity(Severity.IMPORTANT)
|
||||
.category(hawtioEvent.getAction())
|
||||
.suser(hawtioEvent.getUser())
|
||||
.src(hawtioEvent.getSrc())
|
||||
.build();
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.hawtio;
|
||||
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.ConfigurationPolicy;
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
import ru.entaxy.audit.service.EventInterpreter;
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
|
||||
@Component(service = EventInterpreter.class, immediate = true, configurationPolicy = ConfigurationPolicy.OPTIONAL)
|
||||
public class HawtioEventInterpreter implements EventInterpreter {
|
||||
|
||||
private static final String HAWTIO_AUDIT_TOPIC = "entaxy/hawtio/audit";
|
||||
|
||||
@Override
|
||||
public InterpretedEvent interpret(Event origin) {
|
||||
|
||||
if (!HAWTIO_AUDIT_TOPIC.equals(origin.getTopic()))
|
||||
return null;
|
||||
|
||||
return new HawtioInterpretedEvent(origin);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.hawtio;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
|
||||
public class HawtioInterpretedEvent extends InterpretedEvent {
|
||||
|
||||
String action;
|
||||
|
||||
String message;
|
||||
|
||||
String user;
|
||||
|
||||
String src;
|
||||
|
||||
boolean isSuccessful;
|
||||
|
||||
public HawtioInterpretedEvent(Event origin) {
|
||||
super(origin);
|
||||
action = origin.getProperty("category").toString();
|
||||
message = origin.getProperty("message").toString();
|
||||
user = origin.getProperty("user").toString();
|
||||
src = origin.getProperty("src").toString();
|
||||
isSuccessful = (Boolean) origin.getProperty("result");
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getSrc() {
|
||||
return src;
|
||||
}
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return isSuccessful;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.impl;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.data.Outcome;
|
||||
import ru.entaxy.audit.service.AuditService;
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
import ru.entaxy.audit.utils.AuditHelper;
|
||||
|
||||
public class AuditServiceImpl implements AuditService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuditServiceImpl.class);
|
||||
|
||||
private final WebLoginModule webLoginModule = new WebLoginModule();
|
||||
private final OSGIEventModule osgiEventModule = new OSGIEventModule();
|
||||
|
||||
@Override
|
||||
public void onAudit(AuditEvent record) {
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogin(String username, HttpServletRequest request, Outcome outcome) {
|
||||
webLoginModule.onLogin(username, request, outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogout(String username, HttpServletRequest request) {
|
||||
webLoginModule.onLogout(username, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOSGIEvent(Event event) {
|
||||
osgiEventModule.onEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileChange(Event event) {
|
||||
osgiEventModule.onFileChange(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean interpret(Event event) {
|
||||
if (InterpreterService.INSTANCE == null)
|
||||
return false;
|
||||
InterpretedEvent result = InterpreterService.INSTANCE.interpret(event);
|
||||
|
||||
if (result == null) {
|
||||
if (LOG.isTraceEnabled())
|
||||
LOG.trace("Event from topic [{}] not interpreted", event.getTopic());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result.resolution.equals(InterpretedEvent.EventResolution.IGNORE)) {
|
||||
if (LOG.isTraceEnabled())
|
||||
LOG.trace("Event from topic [{}] IGNORED; interpreted as [{}] -> [{}]", event.getTopic(),
|
||||
result.getClass().getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (ConverterService.INSTANCE == null)
|
||||
return false;
|
||||
|
||||
AuditEvent convertedEvent = ConverterService.INSTANCE.convert(result);
|
||||
|
||||
if (convertedEvent == null) {
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("NOT CONVERTED: Event from topic [{}] interpreted as [{}]", event.getTopic(),
|
||||
result.getClass().getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
Subject subject = (Subject) event.getProperty("subject");
|
||||
boolean processed = false;
|
||||
|
||||
String suser = "local";
|
||||
String address = "localhost";
|
||||
|
||||
if (subject != null) {
|
||||
suser = AuditHelper.findRemoteUser(subject);
|
||||
address = AuditHelper.findAddress(subject);
|
||||
}
|
||||
|
||||
AuditEvent auditEvent = AuditEvent.AuditLoggingEventBuilder.getInstance()
|
||||
.category(convertedEvent.getCategory())
|
||||
.duser(convertedEvent.getDuser())
|
||||
.message(convertedEvent.getMessage())
|
||||
.outcome(convertedEvent.getOutcome())
|
||||
.severity(convertedEvent.getSeverity())
|
||||
.src(convertedEvent.getSrc() != null ? convertedEvent.getSrc() : address)
|
||||
.suser(convertedEvent.getSuser() != null ? convertedEvent.getSuser() : suser)
|
||||
.target(convertedEvent.getTarget())
|
||||
.build();
|
||||
|
||||
|
||||
AuditHelper.log(auditEvent);
|
||||
processed = true;
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestAndSubject(Subject subject, HttpServletRequest request) {
|
||||
webLoginModule.setMDC(subject, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestAndUser(String user, HttpServletRequest request) {
|
||||
webLoginModule.setMDC(user, request);
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Deactivate;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.service.EventConverter;
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
|
||||
@Component(service = ConverterService.class, immediate = true)
|
||||
public class ConverterService {
|
||||
|
||||
static public ConverterService INSTANCE = null;
|
||||
|
||||
protected Map<Class<? extends InterpretedEvent>, Set<EventConverter>> converters = new HashMap<>();
|
||||
|
||||
protected Object convertersLock = new Object();
|
||||
|
||||
@Activate
|
||||
public void activate() {
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
public void deactivate() {
|
||||
INSTANCE = null;
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY,
|
||||
policy = ReferencePolicy.DYNAMIC, unbind = "removeConverter")
|
||||
public void addInterpreter(EventConverter converter) {
|
||||
synchronized (convertersLock) {
|
||||
for (Class<? extends InterpretedEvent> clazz : converter.getAllowedClasses()) {
|
||||
this.converters.putIfAbsent(clazz, new HashSet<>());
|
||||
this.converters.get(clazz).add(converter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeConverter(EventConverter converter) {
|
||||
synchronized (convertersLock) {
|
||||
for (Class<? extends InterpretedEvent> clazz : converter.getAllowedClasses()) {
|
||||
if (converters.containsKey(clazz))
|
||||
converters.get(clazz).remove(converter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public <T extends InterpretedEvent> AuditEvent convert(T event) {
|
||||
AuditEvent result = null;
|
||||
if (converters.containsKey(event.getClass())) {
|
||||
for (EventConverter converter : converters.get(event.getClass())) {
|
||||
try {
|
||||
result = converter.convert(event);
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
if (result != null)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Deactivate;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
import ru.entaxy.audit.service.EventInterpreter;
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
|
||||
@Component(service = InterpreterService.class, immediate = true)
|
||||
public class InterpreterService {
|
||||
|
||||
static public InterpreterService INSTANCE = null;
|
||||
|
||||
protected List<EventInterpreter> interpreters = new ArrayList<>();
|
||||
|
||||
protected Object interpretersLock = new Object();
|
||||
|
||||
@Activate
|
||||
public void activate() {
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
public void deactivate() {
|
||||
INSTANCE = null;
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY,
|
||||
policy = ReferencePolicy.DYNAMIC, unbind = "removeInterpreter")
|
||||
public void addInterpreter(EventInterpreter interpreter) {
|
||||
synchronized (interpretersLock) {
|
||||
if (!interpreters.contains(interpreter))
|
||||
interpreters.add(interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeInterpreter(EventInterpreter interpreter) {
|
||||
synchronized (interpretersLock) {
|
||||
interpreters.remove(interpreter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public InterpretedEvent interpret(Event event) {
|
||||
InterpretedEvent result = null;
|
||||
for (EventInterpreter interpreter : interpreters) {
|
||||
try {
|
||||
result = interpreter.interpret(event);
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
if (result != null)
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.impl;
|
||||
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.data.Severity;
|
||||
import ru.entaxy.audit.utils.AuditHelper;
|
||||
import ru.entaxy.audit.utils.CommandWeight;
|
||||
|
||||
public class OSGIEventModule {
|
||||
|
||||
private Map<String, LongAdder> processedCommands = new ConcurrentHashMap<>();
|
||||
private Map<String, LongAdder> skippedCommands = new ConcurrentHashMap<>();
|
||||
|
||||
private final Set<String> targets = new HashSet<String>() {{
|
||||
add("jaas");
|
||||
}};
|
||||
|
||||
private final static Pattern COMMAND_PATTERN = Pattern.compile("^(.+):([A-Za-z-]+)\\s?+(.+)?$");
|
||||
private final static Pattern FILE_PATTERN = Pattern.compile("^Updating ([a-zA-Z]+)\\s+(from)?\\s?(.+)$");
|
||||
|
||||
public void onEvent(Event event) {
|
||||
String command = (String) event.getProperty("command");
|
||||
if (command == null) {
|
||||
return;
|
||||
}
|
||||
Subject subject = (Subject) event.getProperty("subject");
|
||||
boolean processed = false;
|
||||
Matcher m = checkCommand(command);
|
||||
if (m != null && subject != null) {
|
||||
String suser = AuditHelper.findRemoteUser(subject);
|
||||
String address = AuditHelper.findAddress(subject);
|
||||
String target = m.group(1);
|
||||
String commandName = m.group(2);
|
||||
String arguments = m.group(3);
|
||||
if (targets.contains(target)) {
|
||||
AuditEvent auditEvent = AuditEvent.AuditLoggingEventBuilder.getInstance()
|
||||
.target(target)
|
||||
.suser(suser)
|
||||
.src(address)
|
||||
.category(commandName)
|
||||
.severity(CommandWeight.getByTarget(target))
|
||||
.message(arguments == null ? "" : arguments).build();
|
||||
AuditHelper.log(auditEvent);
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
Map<String, LongAdder> target = processed ? processedCommands : skippedCommands;
|
||||
target.computeIfAbsent(command, (s) -> new LongAdder()).increment();
|
||||
}
|
||||
|
||||
private Matcher checkCommand(String command) {
|
||||
Matcher m = COMMAND_PATTERN.matcher(command);
|
||||
if (m.find()) {
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onFileChange(Event event) {
|
||||
String message = (String) event.getProperty("message");
|
||||
Matcher m = FILE_PATTERN.matcher(message);
|
||||
if (m.find()) {
|
||||
String filename = m.group(3);
|
||||
String changeSubject = m.group(1);
|
||||
String target = "Update " + changeSubject;
|
||||
if (changeSubject.equals("bundle") || changeSubject.equals("configuration")) {
|
||||
AuditEvent auditEvent = AuditEvent.AuditLoggingEventBuilder.getInstance()
|
||||
.target(target)
|
||||
.suser("local")
|
||||
.src("localhost")
|
||||
.category(filename)
|
||||
.severity(Severity.WARNING)
|
||||
.message(message).build();
|
||||
AuditHelper.log(auditEvent);
|
||||
processedCommands.computeIfAbsent(target, (s) -> new LongAdder()).increment();
|
||||
}
|
||||
skippedCommands.computeIfAbsent(target, (s) -> new LongAdder()).increment();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.impl;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.utils.AuditHelper;
|
||||
import ru.entaxy.audit.utils.Constants;
|
||||
import ru.entaxy.audit.data.Outcome;
|
||||
import ru.entaxy.audit.data.Severity;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WebLoginModule {
|
||||
public void onLogin(String username, HttpServletRequest request, Outcome outcome) {
|
||||
String remoteAddress = requestRemoteAddress(request);
|
||||
AuditEvent event = AuditEvent.AuditLoggingEventBuilder.getInstance()
|
||||
.suser(username)
|
||||
.outcome(outcome)
|
||||
.severity(outcome == Outcome.SUCCESS ? Severity.INFO : Severity.WARNING)
|
||||
.src(remoteAddress)
|
||||
.category(outcome == Outcome.SUCCESS ? "Login success" : "Login failed")
|
||||
.target("auth")
|
||||
.build();
|
||||
AuditHelper.log(event);
|
||||
}
|
||||
|
||||
public void onLogout(String username, HttpServletRequest request) {
|
||||
String remoteAddress = requestRemoteAddress(request);
|
||||
AuditEvent event = AuditEvent.AuditLoggingEventBuilder.getInstance()
|
||||
.suser(username)
|
||||
.outcome(Outcome.SUCCESS)
|
||||
.severity(Severity.INFO)
|
||||
.src(remoteAddress)
|
||||
.category("Logout")
|
||||
.target("auth")
|
||||
.build();
|
||||
AuditHelper.log(event);
|
||||
}
|
||||
|
||||
private static String requestRemoteAddress(HttpServletRequest request) {
|
||||
return Optional.ofNullable(request.getHeader(Constants.X_FORWARDER_FOR))
|
||||
.orElse(request.getRemoteHost());
|
||||
}
|
||||
|
||||
public void setMDC(Subject subject, HttpServletRequest request) {
|
||||
String remoteUser = AuditHelper.findRemoteUser(subject);
|
||||
saveMDC(remoteUser, request);
|
||||
}
|
||||
|
||||
public void setMDC(String username, HttpServletRequest request) {
|
||||
saveMDC(username, request);
|
||||
}
|
||||
|
||||
private void saveMDC(String username, HttpServletRequest request) {
|
||||
Map<String, String> contextMap = MDC.getCopyOfContextMap();
|
||||
if (contextMap == null) {
|
||||
contextMap = new HashMap<>();
|
||||
}
|
||||
contextMap.put(Constants.HTTP_REQUEST_USER, username);
|
||||
contextMap.put(Constants.HTTP_REQUEST_REMOTE_IP, requestRemoteAddress(request));
|
||||
contextMap.put(Constants.HTTP_REQUEST_SERVER_IP, request.getServerName());
|
||||
MDC.setContextMap(contextMap);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.jmx;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.ConfigurationPolicy;
|
||||
import org.osgi.service.component.annotations.Modified;
|
||||
import org.osgi.service.event.Event;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.audit.service.EventInterpreter;
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
import ru.entaxy.audit.service.InterpretedEvent.EventResolution;
|
||||
|
||||
@Component(service = EventInterpreter.class, immediate = true, configurationPid = "ru.entaxy.audit.interpreter.jmx",
|
||||
configurationPolicy = ConfigurationPolicy.OPTIONAL)
|
||||
public class JMXEventInterpreter implements EventInterpreter {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JMXEventInterpreter.class);
|
||||
|
||||
public static final String JMX_AUDIT_TOPIC_PREFIX = "javax/management/MBeanServer";
|
||||
|
||||
public static final String JMX_AUDIT_INVOKE_SUBTOPIC = "INVOKE";
|
||||
|
||||
protected static final String PROP_IGNORE_TOPICS = "topics.ignore";
|
||||
|
||||
protected static final String PROP_PROCESS_TOPICS = "topics.process";
|
||||
|
||||
protected List<String> topicsToIgnore = new ArrayList<>();
|
||||
|
||||
protected List<String> topicsToProcess = new ArrayList<>();
|
||||
|
||||
@Activate
|
||||
public void activate(Map<String, Object> properties) {
|
||||
parseProperties(properties);
|
||||
}
|
||||
|
||||
@Modified
|
||||
public void modified(Map<String, Object> properties) {
|
||||
parseProperties(properties);
|
||||
}
|
||||
|
||||
protected void parseProperties(Map<String, Object> properties) {
|
||||
if (properties == null)
|
||||
return;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("\n CONFIGURATION :: \n " + properties.toString());
|
||||
if (properties.containsKey(PROP_IGNORE_TOPICS)) {
|
||||
String ignoreTopics = (String) properties.get(PROP_IGNORE_TOPICS);
|
||||
if (ignoreTopics == null)
|
||||
topicsToIgnore = new ArrayList<>();
|
||||
else {
|
||||
topicsToIgnore = Arrays.asList(ignoreTopics.split(","));
|
||||
}
|
||||
} else {
|
||||
topicsToIgnore = new ArrayList<>();
|
||||
}
|
||||
if (properties.containsKey(PROP_PROCESS_TOPICS)) {
|
||||
String processTopics = (String) properties.get(PROP_PROCESS_TOPICS);
|
||||
if (processTopics == null)
|
||||
topicsToProcess = new ArrayList<>();
|
||||
else {
|
||||
topicsToProcess = Arrays.asList(processTopics.split(","));
|
||||
}
|
||||
} else {
|
||||
topicsToProcess = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterpretedEvent interpret(Event origin) {
|
||||
if (!origin.getTopic().startsWith(JMX_AUDIT_TOPIC_PREFIX))
|
||||
return null;
|
||||
|
||||
JMXInterpretedEvent result;
|
||||
|
||||
String subtopic = origin.getTopic().substring(JMX_AUDIT_TOPIC_PREFIX.length() + 1);
|
||||
|
||||
if (subtopic.startsWith(JMX_AUDIT_INVOKE_SUBTOPIC))
|
||||
result = new JMXInvokeEvent(origin);
|
||||
else
|
||||
result = new JMXInterpretedEvent(origin);
|
||||
|
||||
result.subtopic = subtopic;
|
||||
|
||||
result.resolution = EventResolution.IGNORE;
|
||||
|
||||
if (!topicsToProcess.isEmpty()) {
|
||||
for (String process : topicsToProcess)
|
||||
if (result.subtopic.startsWith(process)) {
|
||||
result.resolution = EventResolution.PROCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
result.resolution = EventResolution.PROCESS;
|
||||
}
|
||||
|
||||
for (String ignore : topicsToIgnore)
|
||||
if (result.subtopic.startsWith(ignore)) {
|
||||
result.resolution = EventResolution.IGNORE;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.jmx;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
|
||||
public class JMXInterpretedEvent extends InterpretedEvent {
|
||||
|
||||
protected String subtopic = null;
|
||||
|
||||
public JMXInterpretedEvent(Event origin) {
|
||||
super(origin);
|
||||
this.eventEssense.put("event.source", "jmx");
|
||||
}
|
||||
|
||||
public JMXInterpretedEvent subtopic(String value) {
|
||||
setSubtopic(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSubtopic() {
|
||||
return subtopic;
|
||||
}
|
||||
|
||||
public void setSubtopic(String subtopic) {
|
||||
this.subtopic = subtopic;
|
||||
this.eventEssense.put("event.subtopic", this.subtopic);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.jmx;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.osgi.service.event.Event;
|
||||
|
||||
public class JMXInvokeEvent extends JMXInterpretedEvent {
|
||||
|
||||
public static final String PROP_PARAMS = "params";
|
||||
|
||||
protected ObjectName objectName;
|
||||
|
||||
protected String methodName;
|
||||
|
||||
protected Object[] methodParams;
|
||||
|
||||
protected Map<String, Object> objectNameData = new HashMap<>();
|
||||
|
||||
public JMXInvokeEvent(Event origin) {
|
||||
super(origin);
|
||||
if (this.originalEvent.containsProperty(PROP_PARAMS)) {
|
||||
|
||||
Object[] data = (Object[]) this.originalEvent.getProperty(PROP_PARAMS);
|
||||
|
||||
setObjectName((ObjectName) data[0]);
|
||||
setMethodName((String) data[1]);
|
||||
setMethodParams((Object[]) data[2]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseObjectName() {
|
||||
this.objectNameData.clear();
|
||||
this.objectNameData.put("jmx.domain", this.objectName.getDomain());
|
||||
Hashtable<String, String> properties = this.objectName.getKeyPropertyList();
|
||||
for (Map.Entry<String, String> entry : properties.entrySet()) {
|
||||
this.objectNameData.put("jmx.property." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return objectName;
|
||||
}
|
||||
|
||||
public void setObjectName(ObjectName objectName) {
|
||||
this.objectName = objectName;
|
||||
parseObjectName();
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
this.eventEssense.put("jmx.methodName", methodName);
|
||||
}
|
||||
|
||||
public Object[] getMethodParams() {
|
||||
return methodParams;
|
||||
}
|
||||
|
||||
public void setMethodParams(Object[] methodParams) {
|
||||
this.methodParams = methodParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getEventEssense() {
|
||||
Map<String, Object> result = new HashMap<>(super.getEventEssense());
|
||||
result.putAll(this.objectNameData);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.service.osgi;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.event.EventConstants;
|
||||
import org.osgi.service.event.EventHandler;
|
||||
|
||||
import ru.entaxy.audit.service.AuditService;
|
||||
import ru.entaxy.audit.service.AuditServiceFactory;
|
||||
import ru.entaxy.audit.service.EventSubscriber;
|
||||
import ru.entaxy.audit.service.filter.EventRouter;
|
||||
import ru.entaxy.audit.service.impl.AuditServiceImpl;
|
||||
|
||||
public class Activator implements BundleActivator {
|
||||
|
||||
private static final String LOGS_TOPIC = "org/osgi/service/*";
|
||||
private static final String COMMANDS_TOPIC = "org/apache/karaf/shell/console/*";
|
||||
private static final String JMX_AUDIT_TOPIC = "javax/management/MBeanServer/*";
|
||||
private static final String HAWTIO_AUDIT_TOPIC = "entaxy/hawtio/audit";
|
||||
|
||||
private ServiceRegistration<?> listenerRegistration = null;
|
||||
private ServiceRegistration<?> serviceRegistration = null;
|
||||
private ServiceRegistration<?> commandRegistration = null;
|
||||
private ServiceRegistration<?> jmxRegistration = null;
|
||||
private ServiceRegistration<?> hawtioRegistration = null;
|
||||
|
||||
private ServiceRegistration<?> eventRouterRegistration = null;
|
||||
|
||||
private EventRouter eventRouter;
|
||||
|
||||
@Override
|
||||
public void start(BundleContext bundleContext) throws Exception {
|
||||
// System.err.println("I'm activating!");
|
||||
AuditService auditService = AuditServiceFactory.getAuditService();
|
||||
serviceRegistration =
|
||||
bundleContext.registerService(AuditService.class.getName(), new AuditServiceImpl(), new Hashtable<>());
|
||||
eventRouter = new EventRouter(auditService);
|
||||
eventRouterRegistration = bundleContext.registerService(EventRouter.class, eventRouter, new Hashtable<>());
|
||||
|
||||
EventHandler logSubscriber = new EventSubscriber(eventRouter);
|
||||
EventHandler commandsSubscriber = new EventSubscriber(eventRouter);
|
||||
EventHandler jmxSubscriber = new EventSubscriber(eventRouter);
|
||||
EventHandler hawtioSubscriber = new EventSubscriber(eventRouter);
|
||||
|
||||
Dictionary<String, Object> events = new Hashtable<>();
|
||||
events.put(EventConstants.EVENT_TOPIC, LOGS_TOPIC);
|
||||
listenerRegistration = bundleContext.registerService(EventHandler.class.getName(), logSubscriber, events);
|
||||
|
||||
Dictionary<String, Object> commandEvents = new Hashtable<>();
|
||||
commandEvents.put(EventConstants.EVENT_TOPIC, COMMANDS_TOPIC);
|
||||
commandRegistration =
|
||||
bundleContext.registerService(EventHandler.class.getName(), commandsSubscriber, commandEvents);
|
||||
|
||||
Dictionary<String, Object> jmxEvents = new Hashtable<>();
|
||||
jmxEvents.put(EventConstants.EVENT_TOPIC, JMX_AUDIT_TOPIC);
|
||||
jmxRegistration =
|
||||
bundleContext.registerService(EventHandler.class.getName(), jmxSubscriber, jmxEvents);
|
||||
|
||||
Dictionary<String, Object> hawtioEvents = new Hashtable<>();
|
||||
hawtioEvents.put(EventConstants.EVENT_TOPIC, HAWTIO_AUDIT_TOPIC);
|
||||
hawtioRegistration =
|
||||
bundleContext.registerService(EventHandler.class.getName(), hawtioSubscriber, hawtioEvents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
if (listenerRegistration != null) {
|
||||
listenerRegistration.unregister();
|
||||
}
|
||||
if (commandRegistration != null) {
|
||||
commandRegistration.unregister();
|
||||
}
|
||||
if (jmxRegistration != null) {
|
||||
jmxRegistration.unregister();
|
||||
}
|
||||
if (serviceRegistration != null) {
|
||||
serviceRegistration.unregister();
|
||||
}
|
||||
if (eventRouterRegistration != null) {
|
||||
eventRouterRegistration.unregister();
|
||||
}
|
||||
if (eventRouter != null) {
|
||||
eventRouter.stop();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.utils;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.data.Severity;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.Principal;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class AuditHelper {
|
||||
public static final String TARGET_ACTION = "action";
|
||||
|
||||
public static final Severity DEFAULT_SEVERITY = Severity.IMPORTANT;
|
||||
public static final String DEFAULT_TARGET = TARGET_ACTION;
|
||||
private static final Logger AUDIT = LoggerFactory.getLogger(Constants.LOG_FACILITY_NAME);
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuditHelper.class);
|
||||
|
||||
public static void log(AuditEvent event) {
|
||||
JsonObject logRecord = new JsonObject();
|
||||
logRecord.addProperty("isEmdevEvents", true);
|
||||
logRecord.addProperty("typ", event.getTarget());
|
||||
logRecord.addProperty("action", event.getCategory());
|
||||
logRecord.addProperty("performedBy", event.getSuser());
|
||||
|
||||
JsonObject info = new JsonObject();
|
||||
if (event.getSrc() != null) {
|
||||
info.addProperty("src", event.getSrc());
|
||||
}
|
||||
if (event.getDuser() != null) {
|
||||
info.addProperty("duser", event.getDuser());
|
||||
}
|
||||
info.addProperty("suser", event.getSuser());
|
||||
info.addProperty("severity", event.getSeverity().getValue());
|
||||
info.addProperty("msg", event.getMessage());
|
||||
info.addProperty("outcome", event.getOutcome().getLabel());
|
||||
logRecord.add("info", info);
|
||||
|
||||
AUDIT.info(logRecord.toString());
|
||||
}
|
||||
|
||||
public static String findRemoteUser(Subject subject) {
|
||||
return findAndProcessPrincipal(subject, "UserPrincipal", Principal::getName);
|
||||
}
|
||||
|
||||
private static String findAndProcessPrincipal(Subject subject, String principalName, Function<Principal, String> mapping) {
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
if (principals != null) {
|
||||
Optional<String> userName = principals.stream()
|
||||
.filter(p -> p.getClass().getSimpleName().startsWith(principalName)).findFirst()
|
||||
.map(mapping);
|
||||
return userName.orElse(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String findAddress(Subject subject) {
|
||||
return findAndProcessPrincipal(subject, "ClientPrincipal", AuditHelper::getAddress);
|
||||
}
|
||||
|
||||
private static String getAddress(Principal p) {
|
||||
//We're assumiming to process Karaf's ClientPrincipal. We need method getAddress();
|
||||
try {
|
||||
Method m = p.getClass().getMethod("getAddress");
|
||||
Object result = m.invoke(p);
|
||||
return (String) result;
|
||||
} catch (Throwable t) {
|
||||
logger.error("Cannot get address from principal {}:", p, t);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.utils;
|
||||
|
||||
import ru.entaxy.audit.data.Severity;
|
||||
|
||||
public enum CommandWeight {
|
||||
JAAS("jaas", Severity.IMPORTANT);
|
||||
|
||||
private final String target;
|
||||
private final Severity severity;
|
||||
|
||||
CommandWeight(String target, Severity severity) {
|
||||
this.target = target;
|
||||
this.severity = severity;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public Severity getSeverity() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
public static Severity getByTarget(String target) {
|
||||
for (CommandWeight value : values()) {
|
||||
if (value.getTarget().equals(target)) {
|
||||
return value.severity;
|
||||
}
|
||||
}
|
||||
return Severity.INFO;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-audit
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.audit.utils;
|
||||
|
||||
public class Constants {
|
||||
public static final String X_FORWARDER_FOR = "X-Forwarder-For";
|
||||
public static final String LOG_FACILITY_NAME = "AUDIT_LOGFILE";
|
||||
|
||||
public static final String HTTP_REQUEST_USER = "Audit-HTTP-Request-User";
|
||||
public static final String HTTP_REQUEST_REMOTE_IP = "Audit-HTTP-Request-Remote-IP";
|
||||
public static final String HTTP_REQUEST_SERVER_IP = "Audit-HTTP-Request-Server-IP";
|
||||
|
||||
private Constants() {}
|
||||
|
||||
}
|
Reference in New Issue
Block a user