[ 
https://issues.apache.org/jira/browse/WICKET-6508?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16293799#comment-16293799
 ] 

Martin Makundi edited comment on WICKET-6508 at 12/16/17 1:21 PM:
------------------------------------------------------------------

*"Thinking out aloud":*

Goal is to be able to centrally enable access (get, set) monitoring for all 
lambda/propery models
of a Wicket application (possibly centrally activated in 
WebApplication.init()). Currently you cannot add such a monitor in wicket in a 
pluggable way.

Each time the monitor would then be invoked, it would be passed information 
about monitoring context, target object, accessed property, and accessed 
values. The monitoring implementation would then decide what to do with this 
information (for example, it could check if session user has authorization to 
access the information and for example throw exception and deny access in case 
of a breach; it could log the which session user accessed what properties of 
which target objects and in which context).

The problem consists of two parts: 1) how to monitor access of targetObjects, 
2) how to integrate such monitoring into wicket in an elengant and transparent, 
pluggable, centrally configurable manner.
 
1) For the monitoring part, some solutions consist of wrapping the targetObject 
using some sort of proxy object which invokes the monitor (see proposals using 
something like Javassist
or CGLIB:
https://stackoverflow.com/questions/3291637/alternatives-to-java-lang-reflect-proxy-for-creating-proxies-of-abstract-classes).

2) The next challenge is how to do this as elegantly and transparently as 
possible from wicket. Wicket comes into picture when you use it, which should 
be as easy as:

{code:}
new Label("name", project::getDescription)
{code}
or
{code:}
new Label("name", new PropertyModel<String>(project, ”description”))
{code}

This way coder cannot ”forget” using the access monitor whenever it has been 
configured for the application, but instead the monitor is enforced and the 
monitor can choose what to do with each invocation.

AccessMonitoringInterface could be something like:

{code:}
public interface AccessMonitoringInterface<MonitoringContextReference, 
TargetObject, ValueType> {
  /**
   * @param monitoringContextReference
   * @param targetObject
   * @param property
   * @param oldValue
   * @param newValue
   */
  public default void onBeforeSetObject(final MonitoringContextReference 
monitoringContextReference, final TargetObject targetObject,
      final String property, final ValueType oldValue, final ValueType 
newValue) {
    // Override when needed
  }

  /**
   * @param monitoringContextReference
   * @param targetObject
   * @param property
   * @param value
   */
  public default void onBeforeGetObject(final MonitoringContextReference 
monitoringContextReference, final TargetObject targetObject,
      final String property, final ValueType value) {
    // Override when needed
  }
}
{code}

MonitoringContextReference could be some page sepecific information (think 
log4j logging using Logger.getLogger(class) contexts), so it does not need to 
be passed as a parameter but instead could be requested from RequestCycle or 
smth through a method like ((Page) 
PageRequestHandlerTracker.getLastHandler(RequestCycle.get()).getPage()).getAccessMonitoringContext(Object
 targetObject) while its default implementation would be something simple like 
return Page.this.getClass(). Each page implementation could override it as 
necessary to give more detailed info (such as a particular selected tab or 
something for a single-page application).


was (Author: mmakundi):
*"Thinking out aloud":*

Goal is to be able to centrally enable access (get, set) monitoring for all 
lambda/propery models
of a Wicket application (possibly centrally activated in 
WebApplication.init()). Currently you cannot add such a monitor in wicket in a 
pluggable way.

Each time the monitor would then be invoked, it would be passed information 
about monitoring context, target object, accessed property, and accessed 
values. The monitoring implementation would then decide what to do with this 
information (for example, it could check if session user has authorization to 
access the information and for example throw exception and deny access in case 
of a breach; it could log the which session user accessed what properties of 
which target objects and in which context).

The problem consists of two parts: 1) how to monitor access of targetObjects, 
2) how to integrate such monitoring into wicket in an elengant and transparent, 
pluggable, centrally configurable manner.
 
1) For the monitoring part, some solutions consist of wrapping the targetObject 
using some sort of proxy object which invokes the monitor (see proposals using 
something like Javassist
or CGLIB:
https://stackoverflow.com/questions/3291637/alternatives-to-java-lang-reflect-proxy-for-creating-proxies-of-abstract-classes).

2) The next challenge is how to do this as elegantly and transparently as 
possible from wicket. Wicket comes into picture when you use it, which should 
be as easy as:

{code:}
new Label("name", project::getDescription)
{code}
or
{code:}
new Label("name", new PropertyModel<String>(project, ”description”))
{code}

This way coder cannot ”forget” using the access monitor whenever it has been 
configured for the application, but instead the monitor is enforced and the 
monitor can choose what to do with each invocation.

AccessMonitoringInterface could be something like:

{code:}
public interface AccessMonitoringInterface<MonitoringContextReference, 
TargetObject, ValueType> {
  /**
   * @param monitoringContextReference
   * @param targetObject
   * @param property
   * @param oldValue
   * @param newValue
   */
  public default void onBeforeSetObject(final MonitoringContextReference 
monitoringContextReference, final TargetObject targetObject,
      final String property, final ValueType oldValue, final ValueType 
newValue) {
    // Override when needed
  }

  /**
   * @param monitoringContextReference
   * @param targetObject
   * @param property
   * @param value
   */
  public default void onBeforeGetObject(final MonitoringContextReference 
monitoringContextReference, final TargetObject targetObject,
      final String property, final ValueType value) {
    // Override when needed
  }
}
{code}

MonitoringContextReference could be some page sepecific information (think
log4j logging using Logger.getLogger(class) contexts), so it does not need to 
be passed as a parameter but instead could be requested from RequestCycle or 
smth through a method like ((Page) 
PageRequestHandlerTracker.getLastHandler(RequestCycle.get()).getPage()).getAccessMonitoringContext(Object
 targetObject) while its default implementation would be something simple like 
return Page.this.getClass(). Each page implementation could override it as 
necessary to give more
detailed info (such as a particular selected tab or something for a single-page 
application).
 

> Automatically monitoring access to data objects (lambdamodels propertymodels) 
> in wicket gui
> -------------------------------------------------------------------------------------------
>
>                 Key: WICKET-6508
>                 URL: https://issues.apache.org/jira/browse/WICKET-6508
>             Project: Wicket
>          Issue Type: New Feature
>          Components: wicket
>    Affects Versions: 8.0.0-M8
>            Reporter: Martin Makundi
>   Original Estimate: 8h
>  Remaining Estimate: 8h
>
> The [GDPR|https://www.eugdpr.org/] was approved by the EU Parliament on 14 
> April 2016, and it brings strict requirements to logging things like data 
> access.
> We are investigating ways to automatically log access to data objects in 
> wicket gui.
> Oldschool solutions would be, for example to override/customize PropertyModel 
> and log target object and method invoked, and possibly result value, together 
> with necessary information from session (timestamp, user id, authorization 
> level, etc.).
> However, with wicket 8 and java 8 lambda possibilities, I am wondering if 
> there would be  some ingenious suggestion how to do this very nicely by 
> implementing own AuditTrailSerializableFunction or similar?
> Might need to wrap the data objects in some sort of proxy but that would be 
> ok:
> * https://gist.github.com/jhorstmann/de367a42a08d8deb8df9
> * 
> https://stackoverflow.com/questions/13356326/how-can-i-log-every-method-called-in-a-class-automatically-with-log4j
> * 
> https://stackoverflow.com/questions/3291637/alternatives-to-java-lang-reflect-proxy-for-creating-proxies-of-abstract-classes
> Would be nice if wicket would provide reusable blueprints for this, like it 
> does for general authorization functionalities.
> It could have methods like isAuthorized before invoking get or set and log if 
> not authorized and throw exception. 
> When model access is authroized, it would have methods like logAccess() which 
> will log (as necessary) how and what is accessed. Logging implementation will 
> take care of optimizing frequent logs etc.
> Possibly it could be applied to both propertymodel and lamba model as a 
> "model listener" or something.
> Proposals welcome, we will be submitting something soon.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to