Monthly Archives: June, 2018

Drupal 8 entity access permission problems

Sometimes even when you think you’ve given all the correct permissions to a user role Drupal still denies access to a node. This happened to me this week at work unfortunately and I spent some time digging through Drupal 8’s codebase to track down where and why it does this. So in case someone else has this problem as well, these calls in order are the interesting code parts to check out.

AccessManager::check
AccessManager::performCheck
EntityAccessCheck::access
Node::access
ContentEntityBase::access
EntityAccessControlHandler::access

In my case from the bottom of this stack turned out to be one of the modules that denied access. EntityAccessControlHandler::access method calls ModuleHandler::invokeAll to query the modules if they will allow access. Let’s see that Drupal method in version 8.3.x:

public function invokeAll($hook, array $args = []) {
$return = [];
$implementations = $this->getImplementations($hook);
foreach ($implementations as $module) {
$function = $module . ‘_’ . $hook;
$result = call_user_func_array($function, $args);
if (isset($result) && is_array($result)) {
$return = NestedArray::mergeDeep($return, $result);
}
elseif (isset($result)) {
$return[] = $result;
}
}

return $return;
}

As we can see it calls a hook, and passes the arguments that go into the method. The hooks are the following typically:

entity_access
node_access

The arguments are the following:

[ $entity, $operation, $account ]

Operations in case of access can be the following:

create
read
update
delete

Using these information we can filter the calls and list which module(s) deny access and then check out what their problem is

Advertisements

Tomcat 7 servlet context parameters

In desktop applications we typically configure our application by reading a config file, and using the values found.

In a Java web application however there’s a better way, because there’s already a config file we can use, and this is the web.xml file, where we can place the so called context init parameters, that are loaded during the web application’s startup. In this article I’m going to show how this works.

There are 3 things we must do to make this all work

  • Create a so called ContextListener subclass that will listen to events such as context initialization (servlet startup).
  • Tell Tomcat we have such a listener class and that it should tell it about such events, by referencing our class in the web.xml file
  • Place the parameters and values in the web.xml file

This is how a ContextListener class looks like:

package something.something.darkside;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;

public class ContextListener implements ServletContextListener
{
@Override
public void contextInitialized( ServletContextEvent event )
{
final ServletContext context = event.getServletContext();
final String dbdriver = context.getInitParameter( “dbdriver” );
final String dburl = context.getInitParameter( “dburl” );
}

@Override
public void contextDestroyed( ServletContextEvent event )
{
}
}

As we can see the class has 2 methods that need to be implemented, the contextInitialized and contextDestroyed events. We can read the context parameters in the contextInitialized class and then do whatever we want with them.

Let’s now see the relevant parts of such a web.xml file:

<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app xmlns=”http://java.sun.com/xml/ns/javaee&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&#8221;
version=”3.0″>
<context-param>
<param-name>dbdriver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<context-param>
<param-name>dburl</param-name>
<param-value>jdbc:mysql://localhost/database</param-value>
</context-param>
<listener>
<listener-class>something.something.darkside.ContextListener</listener-class>
</listener>

As we can see we have 2 parameters here dbdriver, and dburl, which are database connection configuration parameters in this case. Also we have the context event listener class references. If we restart Tomcat now when starting up the servlet it will tell the context listener about the startup and it can read the parameters.

That’s it. It’s this simple!

Authenticating users against Active Directory with PHP

A co-worker of mine asked how this can be done, since I’ve already had some experience querying AD with Java and PHP. It’s been some time ago so I had to think about a little but then I realized it’s easy. Just use LDAP bind!

Consider the following PHP code snippet:

$ldaphost = ‘ldap://dc.mycompany.local’;
$ldapport = 389;

$user = ‘DOMAIN\user’;
$password = ‘password’;

$ldapconn = @ldap_connect( $ldaphost, $ldapport );
if( $ldapconn )
{

ldap_set_option( $ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3 );
ldap_set_option( $ldapconn, LDAP_OPT_REFERRALS, 0 );

$ok = @ldap_bind( $ldapconn, $user, $password );
if( $ok )
{
ldap_unbind( $ldapconn );
}
else
{
echo ‘Failed to bind to LDAP server:’ . “\n”;
echo ldap_error( $ldapconn ) . “\n”;
}
}
else
{
echo ‘Failed to connect to LDAP server’ . “\n”;
}

It is important to prefix the user’s name with the domain otherwise it won’t accept it and obviously in real life you’d want to use LDAPS and not send the password over the wire in clear text, but the basic idea is the same.

Remote debugging Tomcat7 servlets with Netbeans

At work we still use Tomcat 7 in production and I needed to set up debugging for various development systems. This article shows how to enable Tomcat 7 remote debugging

Enabling Tomcat 7 remote debugging via JDWP

Linux

I use Ubuntu 16.04 LTE so I’ll use that in the example, but other distros will not be that much different, except for the path and (re)starting the service of course.

  • Edit or create the file /usr/share/tomcat7/bin/setenv.sh and put in the following content:

    export JAVA_OPTS=”-Xdebug \
    -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n”

    Note: Obviously if the file already exists and it already has some content, then just add the parameters instead of adding the entire line.

  • Restart Tomcat

    sudo service tomcat7 restart

Windows

  • Go to the Tomcat binary directory, which is by default

    c:\Program Files\Apache Software Foundation\Tomcat 7.0\bin

  • Start the program Tomcat7w.exe
  • Switch to the java tab and add the following lines to the Java options textbox:

    -Xdebug
    -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n

    Note: It is important that each of the parameters should be added on separate lines, and that lines should have no whitespaces in the end!

  • Restarts Tomcat 7

    net stop tomcat7
    net start tomcat7

Attaching Netbeans debugger to Tomcat 7

Now that we have Tomcat running with the remote debugging on we can attach Netbeans to debug.

  • Click debug – attach debugger, a dialog box will appear
  • Select Java Debugger (JPDA) as the Debugger
  • Select SocketAttach as Connector
  • Fill in host / IP address to the host field
  • Fill in port to the Port field, in this example the port is 8787, but obviously it can be any non-taken port
  • Click OK
  • If everything went OK the debugging tab should show up showing the running threads

…and that’s it! Happy bug hunting!