SlideShare a Scribd company logo
1 of 78
Download to read offline
Node Access in Drupal 7
                            (and Drupal 8)


                              Ken Rickard
                             NYCamp 2012


Sunday, July 22, 2012
• Who the heck are you?
                        • What is Node Access?
                        • What changed in Drupal 7?
                        • How do I....?
                        • What’s up for Drupal 8?


Sunday, July 22, 2012
• Ken Rickard
          • Drupal since 2004
          • Domain Access
          • rickard@Palantir.net
          • @agentrickard



Sunday, July 22, 2012
Sunday, July 22, 2012
Drupal 7 Module Development




Sunday, July 22, 2012
AaronWinborn.com




Sunday, July 22, 2012
What is Node Access?




Sunday, July 22, 2012
Sunday, July 22, 2012
• Powerful
             • Unintelligible
             • Unpredictable
             • Multi-dimensional




Sunday, July 22, 2012
What is Node Access?
          Drupal’s system for controlling the
          access to nodes (content) for:
                        • View
                        • Edit
                        • Delete
                        • and now...Create

Sunday, July 22, 2012
Drupal 7 Goodness

          • Create permissions!
          • Alter hooks!
          • ‘Bypass node access’
          • Access control modules
          • Node Access API modules

Sunday, July 22, 2012
Sunday, July 22, 2012
chx   moshe   Crell   Dave    some
                                              Cohen    guy




Sunday, July 22, 2012
Sunday, July 22, 2012
Node Access is multipurpose


        • Filter listing queries.
        • Assert access rights on CRUD.
        • API for managing access rights.



Sunday, July 22, 2012
Sunday, July 22, 2012
• Drupal 6: hook_db_rewrite_sql()


          • Drupal 7: ‘node access’ query flag.




Sunday, July 22, 2012
Filter queries in Drupal 6


                 $result = db_query(db_rewrite_sql(
                   “SELECT nid FROM {node} WHERE
                     status = 1 AND
                     promote = 1
                     ORDER BY
                     sticky DESC,
                     created DESC”
                 ));



Sunday, July 22, 2012
Filter queries in Drupal 7


                        $result = db_select('node', 'n')
                          ->fields('n', array('nid'))
                          ->condition('promote', 1)
                          ->condition('status', 1)
                          ->orderBy('sticky', 'DESC')
                          ->orderBy('created', 'DESC')
                          ->addTag('node_access')
                          ->execute();



Sunday, July 22, 2012
Failure to tag your
                        query is a security
                             violation.

Sunday, July 22, 2012
Sunday, July 22, 2012
Why?


Sunday, July 22, 2012
Sunday, July 22, 2012
Sunday, July 22, 2012
Blue   Red    Green   Grey




                               Our Clients


Sunday, July 22, 2012
Blue    Red     Green   Grey




                               Organic Groups


Sunday, July 22, 2012
With proper access control



                                            Recent
                               Blue
                                            Posts




Sunday, July 22, 2012
Without proper access control




                                 Blue




Sunday, July 22, 2012
Sunday, July 22, 2012
• Node Access is not user_access().
        • Node Access is an API for content
        CRUD permissions.
        • It extends Drupal’s core permissions
        system.
        • It is contextual.


Sunday, July 22, 2012
Boolean assertions



       if (user_access(‘administer nodes’)) {
               return t(“I’ll be back.”);
       }




Sunday, July 22, 2012
Conditional access check


         hook_node_grants($account, $op)


         hook_node_access($node, $op, $account)




Sunday, July 22, 2012
Sunday, July 22, 2012
• Those two functions look similar.
          • But they aren’t.




Sunday, July 22, 2012
node_access() Walk-through
      function node_access($op, $node, $account = NULL) {
        $rights = &drupal_static(__FUNCTION__, array());

        if (!$node || !in_array($op, array('view', 'update', 'delete', 'create'),
      TRUE)) {
          // If there was no node to check against, or the $op was not one of the
          // supported ones, we return access denied.
          return FALSE;
        }
        // If no user object is supplied, the access check is for the current user.
        if (empty($account)) {
          $account = $GLOBALS['user'];
        }




Sunday, July 22, 2012
// $node may be either an object or a node type. Since node types cannot be
          // an integer, use either nid or type as the static cache id.

          $cid = is_object($node) ? $node->nid : $node;

          // If we've already checked access for this node, user and op, return from
          // cache.
          if (isset($rights[$account->uid][$cid][$op])) {
            return $rights[$account->uid][$cid][$op];
          }

          if (user_access('bypass node access', $account)) {
            $rights[$account->uid][$cid][$op] = TRUE;
            return TRUE;
          }
          if (!user_access('access content', $account)) {
            $rights[$account->uid][$cid][$op] = FALSE;
            return FALSE;
          }




Sunday, July 22, 2012
// We grant access to the node if both of the following conditions are met:
       // - No modules say to deny access.
       // - At least one module says to grant access.
       // If no module specified either allow or deny, we fall back to the
       // node_access table.
       $access = module_invoke_all('node_access', $node, $op, $account);
       if (in_array(NODE_ACCESS_DENY, $access, TRUE)) {
         $rights[$account->uid][$cid][$op] = FALSE;
         return FALSE;
       }
       elseif (in_array(NODE_ACCESS_ALLOW, $access, TRUE)) {
         $rights[$account->uid][$cid][$op] = TRUE;
         return TRUE;
       }

     // Check if authors can view their own unpublished nodes.
     if ($op == 'view' && !$node->status && user_access('view own unpublished
   content', $account) && $account->uid == $node->uid && $account->uid != 0) {
       $rights[$account->uid][$cid][$op] = TRUE;
       return TRUE;
     }




Sunday, July 22, 2012
foreach (node_access_grants($op, $account) as $realm => $gids) {
                     foreach ($gids as $gid) {
                       $grants->condition(db_and()
                          ->condition('gid', $gid)
                          ->condition('realm', $realm)
                       );
                     }
                   }
                   if (count($grants) > 0) {
                     $query->condition($grants);
                   }
                   $result = (bool) $query
                     ->execute()
                     ->fetchField();
                   $rights[$account->uid][$cid][$op] = $result;
                   return $result;
               }




Sunday, July 22, 2012
elseif (is_object($node) && $op == 'view' && $node->status) {
              // If no modules implement hook_node_grants(), the default behavior is to
              // allow all users to view published nodes, so reflect that here.
              $rights[$account->uid][$cid][$op] = TRUE;
              return TRUE;
            }
        }

        return FALSE;
    }




Sunday, July 22, 2012
Sunday, July 22, 2012
hook_node_access($node, $op, $account)

     • Replaces hook_access().
     • Can be run by any module!
     • Can return TRUE, FALSE or NULL.
     • Used for access to individual nodes.



Sunday, July 22, 2012
Access control modules

     • Act on Create, View, Update & Delete.
     • No tables*.
     • No queries*.
     • Just business logic.
     • DENY, ALLOW, IGNORE


Sunday, July 22, 2012
The operation condition matters!


                                  ‘create’
                                  ‘delete’
                                  ‘update’
                                    ‘view’



Sunday, July 22, 2012
Sunday, July 22, 2012
/**
     * Implement hook_node_access().
     *
     * Only allow posts by users more than two days old.
     */
   function delay_node_access($node, $op, $account) {
       if ($op != 'create') {
         return NODE_ACCESS_IGNORE;
       }
       if (empty($account->created) ||
         $account->created > (REQUEST_TIME - (48*3600)))
       {
         return NODE_ACCESS_DENY;
       }
       return NODE_ACCESS_IGNORE;
   }


Sunday, July 22, 2012
Hooray!


Sunday, July 22, 2012
• No more hook_menu_alter().
          • Explicit DENY grants.
          • Explicit ALLOW grants.
          • Apply to all node types!
          • Apply to node creation!



Sunday, July 22, 2012
Boo!


Sunday, July 22, 2012
• Individual nodes / actions only.
          • Running lookup queries per node
          can be expensive.
          • Can override other modules.
          • Cannot generate accurate lists.



Sunday, July 22, 2012
Sunday, July 22, 2012
NODE ACCESS API

    • Uses {node_access} for list queries.
    • Creates JOINs to return lists of nodes.
    • Does not act on ‘create’ operation.
    • Requires numeric keys.


Sunday, July 22, 2012
The {node_access} table.




Sunday, July 22, 2012
hook_node_access_records()


                                     Data Entry

                                    node_save()

                            node_access_acquire_grants()


                                   {node_access}




Sunday, July 22, 2012
function example_node_access_records($node) {
          $grants[] = array(
             'realm' => 'example_author',
             'gid' => $node->uid,
             'grant_view' => 1,
             'grant_update' => 1,
             'grant_delete' => 1,
             'priority' => 0,
          );
          return $grants;
        }



Sunday, July 22, 2012
hook_node_grants()


                            Inbound Request

                                 $user

                          node_access_grants()


                          Page / Request Render




Sunday, July 22, 2012
function example_node_grants($account, $op) {
     if (user_access('access private content', $account)) {
       $grants['example'] = array(1);
     }
     $grants['example_owner'] = array($account->uid);
     return $grants;
   }




Sunday, July 22, 2012
• Map the user’s grants to the stored
      grants.
      • JOIN {node_access} to the query.
      • Return the node or not.
      • OR based access logic.



Sunday, July 22, 2012
• Two-part system!
      • One query does not cover all cases!

                        ‘create’
                        ‘delete’
                        ‘update’
                         ‘view’


Sunday, July 22, 2012
Sunday, July 22, 2012
Rebuilding the {node_access} table




Sunday, July 22, 2012
• Make sure you hook_node_load()
       your data.
       • node_load() must match node_save()
       • Other modules may depend on you!



Sunday, July 22, 2012
Devel Node Access

      • Debugging tools for developers.
      • And site administrators!




Sunday, July 22, 2012
hook_node_access_explain()
    /**
      * Implements hook_node_access_explain for devel.module
      */
    function domain_node_access_explain($row) {
         $_domain = domain_get_domain();
         $active = $_domain['subdomain'];
         $domain = domain_lookup($row->gid);
         $return = t('Domain Access') . ' -- ';
         switch ($row->realm) {
               case 'domain_all':
                    if (domain_grant_all() == TRUE) {
                      $return .= t('True: Allows content from all domains to be
    shown.');
                    }
                    else {
                      $return .= t('False: Only allows content from the active
    domain (%domain) or from all affiliates.', array('%domain' =>
    $active));
                    }
Sunday, July 22, 2012
Sunday, July 22, 2012
Add debugging to your module, too




Sunday, July 22, 2012
Sunday, July 22, 2012
hook_node_access_records_alter()

      • Change storage rules before they are
      written to the database!
      • Remember to alter node storage as
      needed, too!*
      • * Runs after node_save() :-(


Sunday, July 22, 2012
function hook_node_access_records_alter(&$grants, $node) {
    // Our module allows editors to mark specific articles
    // with the 'is_preview' field.

        if ($node->is_preview) {
          // Our module grants are set in $grants['example'].
          $temp = $grants['example'];
          // Now remove all module grants but our own.
          $grants = array('example' => $temp);
        }

  }




Sunday, July 22, 2012
hook_node_grants_alter()

         • Alter the user’s grants at request
         time.
         • Quick and easy!




Sunday, July 22, 2012
function hook_node_grants_alter(&$grants, $account, $op) {

     // Get our list of banned roles.
     $restricted = variable_get('example_restricted_roles', array());

     if ($op != 'view' && !empty($restricted)) {
       foreach ($restricted as $role_id) {
         if (isset($user->roles[$role_id])) {
           $grants = array();
         }
       }
     }

}




Sunday, July 22, 2012
hook_query_alter()
   /**
     * Implements hook_query_TAG_alter().
     *
     * If enabled, force admins to use Domain Access rules.
     */
   function domain_query_node_access_alter($query) {
       $admin_force = variable_get('domain_force_admin', FALSE);
       // In any of the following cases, do not enforce any rules.
       if (empty($admin_force) || !user_access('bypass node access')
         || domain_grant_all()) {
         return;
       }
       domain_alter_node_query($query);
   }




Sunday, July 22, 2012
Sunday, July 22, 2012
It’s not a tumor.




Sunday, July 22, 2012
Drupal 8 Changes

          • Language-sensitive
          • Abstract to all entities
          • Remove hook_node_access()?
          • Better list queries in core?
          • Support AND and OR logic?

Sunday, July 22, 2012
function node_access($op, $node, $account = NULL, $langcode = NULL) {
         $rights = &drupal_static(__FUNCTION__, array());
         ...
         // If we've already checked access for this node, user and op, return from
         // cache.
         if (isset($rights[$account->uid][$cid][$langcode][$op])) {
           return $rights[$account->uid][$cid][$langcode][$op];
         }

           if (user_access('bypass node access', $account)) {
             $rights[$account->uid][$cid][$langcode][$op] = TRUE;
             return TRUE;
           }
           if (!user_access('access content', $account)) {
             $rights[$account->uid][$cid][$langcode][$op] = FALSE;
             return FALSE;
           }




Sunday, July 22, 2012
Key issues

   • Make a general access API
      • http://drupal.org/node/777578
   • Make node_access() language aware
      • http://drupal.org/node/1658814
   • Query madness
      • http://drupal.org/node/1349080
Sunday, July 22, 2012
Let’s get to work




Sunday, July 22, 2012
• THANK YOU!
          • Ken Rickard
          • rickard@Palantir.net
          • @agentrickard




Sunday, July 22, 2012

More Related Content

What's hot

Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumnameEmanuele Quinto
 
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESDrupalCamp Kyiv
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalFredric Mitchell
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in LaravelHAO-WEN ZHANG
 
Final tagless and cats mtl
Final tagless and cats mtl Final tagless and cats mtl
Final tagless and cats mtl Alexander Zaidel
 
Drupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageDrupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageRonald Ashri
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency InjectionAnton Kril
 
Modularized Persistence - B Zsoldos
Modularized Persistence - B ZsoldosModularized Persistence - B Zsoldos
Modularized Persistence - B Zsoldosmfrancis
 
"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил АнохинFwdays
 
Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"Fwdays
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentationplindner
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Desarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesDesarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesLuis Curo Salvatierra
 
Object::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your CodeObject::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your CodeWorkhorse Computing
 

What's hot (20)

Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumname
 
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
 
iBATIS
iBATISiBATIS
iBATIS
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in Drupal
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
 
Final tagless and cats mtl
Final tagless and cats mtl Final tagless and cats mtl
Final tagless and cats mtl
 
Drupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageDrupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of Usage
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency Injection
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Modularized Persistence - B Zsoldos
Modularized Persistence - B ZsoldosModularized Persistence - B Zsoldos
Modularized Persistence - B Zsoldos
 
"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин
 
Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentation
 
SQLAlchemy Seminar
SQLAlchemy SeminarSQLAlchemy Seminar
SQLAlchemy Seminar
 
Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Desarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesDesarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móviles
 
Object::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your CodeObject::Franger: Wear a Raincoat in your Code
Object::Franger: Wear a Raincoat in your Code
 

Similar to Node Access in Drupal 7 (and Drupal 8)

Drupal node access system & AUL 7.x.-2.x
Drupal node access system & AUL 7.x.-2.xDrupal node access system & AUL 7.x.-2.x
Drupal node access system & AUL 7.x.-2.xOleksandr Milkovskyi
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven DevelopmentAugusto Pascutti
 
Introduction to j query
Introduction to j queryIntroduction to j query
Introduction to j querythewarlog
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptDarren Mothersele
 
Como escalar aplicações PHP
Como escalar aplicações PHPComo escalar aplicações PHP
Como escalar aplicações PHPAugusto Pascutti
 
Redis on Rails (RedDotRubyConf 2012)
Redis on Rails (RedDotRubyConf 2012)Redis on Rails (RedDotRubyConf 2012)
Redis on Rails (RedDotRubyConf 2012)Obie Fernandez
 
Drupal 7: What's In It For You?
Drupal 7: What's In It For You?Drupal 7: What's In It For You?
Drupal 7: What's In It For You?karschsp
 
Symfony2 and MongoDB
Symfony2 and MongoDBSymfony2 and MongoDB
Symfony2 and MongoDBPablo Godel
 
jQuery (MeshU)
jQuery (MeshU)jQuery (MeshU)
jQuery (MeshU)jeresig
 
Angular.js - JS Camp UKraine 2013
Angular.js - JS Camp UKraine 2013Angular.js - JS Camp UKraine 2013
Angular.js - JS Camp UKraine 2013Max Klymyshyn
 
The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009Chris Chabot
 
jQuery (BostonPHP)
jQuery (BostonPHP)jQuery (BostonPHP)
jQuery (BostonPHP)jeresig
 
Domain Driven Design Javaday Roma2007
Domain Driven Design Javaday Roma2007Domain Driven Design Javaday Roma2007
Domain Driven Design Javaday Roma2007Antonio Terreno
 
PHP Loves MongoDB - Dublin MUG (by Hannes)
PHP Loves MongoDB - Dublin MUG (by Hannes)PHP Loves MongoDB - Dublin MUG (by Hannes)
PHP Loves MongoDB - Dublin MUG (by Hannes)Mark Hillick
 
Headless drupal + react js Oleksandr Linyvyi
Headless drupal + react js   Oleksandr LinyvyiHeadless drupal + react js   Oleksandr Linyvyi
Headless drupal + react js Oleksandr LinyvyiDrupalCamp Kyiv
 
Caching techniques in python, europython2010
Caching techniques in python, europython2010Caching techniques in python, europython2010
Caching techniques in python, europython2010Michael Domanski
 
Mock Objects from Concept to Code
Mock Objects from Concept to CodeMock Objects from Concept to Code
Mock Objects from Concept to CodeRob Myers
 
Architecting large Node.js applications
Architecting large Node.js applicationsArchitecting large Node.js applications
Architecting large Node.js applicationsSergi Mansilla
 
20120722 word press
20120722 word press20120722 word press
20120722 word pressSeungmin Sun
 

Similar to Node Access in Drupal 7 (and Drupal 8) (20)

Drupal node access system & AUL 7.x.-2.x
Drupal node access system & AUL 7.x.-2.xDrupal node access system & AUL 7.x.-2.x
Drupal node access system & AUL 7.x.-2.x
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven Development
 
Introduction to j query
Introduction to j queryIntroduction to j query
Introduction to j query
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
 
Como escalar aplicações PHP
Como escalar aplicações PHPComo escalar aplicações PHP
Como escalar aplicações PHP
 
Redis on Rails (RedDotRubyConf 2012)
Redis on Rails (RedDotRubyConf 2012)Redis on Rails (RedDotRubyConf 2012)
Redis on Rails (RedDotRubyConf 2012)
 
Drupal 7: What's In It For You?
Drupal 7: What's In It For You?Drupal 7: What's In It For You?
Drupal 7: What's In It For You?
 
Symfony2 and MongoDB
Symfony2 and MongoDBSymfony2 and MongoDB
Symfony2 and MongoDB
 
Aegir
AegirAegir
Aegir
 
jQuery (MeshU)
jQuery (MeshU)jQuery (MeshU)
jQuery (MeshU)
 
Angular.js - JS Camp UKraine 2013
Angular.js - JS Camp UKraine 2013Angular.js - JS Camp UKraine 2013
Angular.js - JS Camp UKraine 2013
 
The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009
 
jQuery (BostonPHP)
jQuery (BostonPHP)jQuery (BostonPHP)
jQuery (BostonPHP)
 
Domain Driven Design Javaday Roma2007
Domain Driven Design Javaday Roma2007Domain Driven Design Javaday Roma2007
Domain Driven Design Javaday Roma2007
 
PHP Loves MongoDB - Dublin MUG (by Hannes)
PHP Loves MongoDB - Dublin MUG (by Hannes)PHP Loves MongoDB - Dublin MUG (by Hannes)
PHP Loves MongoDB - Dublin MUG (by Hannes)
 
Headless drupal + react js Oleksandr Linyvyi
Headless drupal + react js   Oleksandr LinyvyiHeadless drupal + react js   Oleksandr Linyvyi
Headless drupal + react js Oleksandr Linyvyi
 
Caching techniques in python, europython2010
Caching techniques in python, europython2010Caching techniques in python, europython2010
Caching techniques in python, europython2010
 
Mock Objects from Concept to Code
Mock Objects from Concept to CodeMock Objects from Concept to Code
Mock Objects from Concept to Code
 
Architecting large Node.js applications
Architecting large Node.js applicationsArchitecting large Node.js applications
Architecting large Node.js applications
 
20120722 word press
20120722 word press20120722 word press
20120722 word press
 

More from nyccamp

Drupal As A Jigsaw
Drupal As A JigsawDrupal As A Jigsaw
Drupal As A Jigsawnyccamp
 
A/B Testing and Optimizely Module
A/B Testing and Optimizely ModuleA/B Testing and Optimizely Module
A/B Testing and Optimizely Modulenyccamp
 
Behat - human-readable automated testing
Behat - human-readable automated testingBehat - human-readable automated testing
Behat - human-readable automated testingnyccamp
 
ALL YOUR BASE (THEMES) ARE BELONG TO US
ALL YOUR BASE (THEMES) ARE BELONG TO USALL YOUR BASE (THEMES) ARE BELONG TO US
ALL YOUR BASE (THEMES) ARE BELONG TO USnyccamp
 
Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...
Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...
Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...nyccamp
 
Promotions Vouchers and Offers in Drupal Commerce
Promotions Vouchers and Offers in Drupal CommercePromotions Vouchers and Offers in Drupal Commerce
Promotions Vouchers and Offers in Drupal Commercenyccamp
 
Workbench: Managing Content Management
Workbench: Managing Content ManagementWorkbench: Managing Content Management
Workbench: Managing Content Managementnyccamp
 
Deployment Strategies: Managing Code, Content, and Configurations
Deployment Strategies: Managing Code, Content, and ConfigurationsDeployment Strategies: Managing Code, Content, and Configurations
Deployment Strategies: Managing Code, Content, and Configurationsnyccamp
 
Drupal Aware Design: Good Techniques for Better Themes
Drupal Aware Design: Good Techniques for Better ThemesDrupal Aware Design: Good Techniques for Better Themes
Drupal Aware Design: Good Techniques for Better Themesnyccamp
 
Drupal and Higher Education
Drupal and Higher EducationDrupal and Higher Education
Drupal and Higher Educationnyccamp
 
A New Theme Layer for Drupal 8
A New Theme Layer for Drupal 8A New Theme Layer for Drupal 8
A New Theme Layer for Drupal 8nyccamp
 
Mobile and Responsive Design with Sass
Mobile and Responsive Design with SassMobile and Responsive Design with Sass
Mobile and Responsive Design with Sassnyccamp
 
Drupal and Apache Solr Search Go Together Like Pizza and Beer for Your Site
Drupal and Apache Solr Search Go Together Like Pizza and Beer for Your SiteDrupal and Apache Solr Search Go Together Like Pizza and Beer for Your Site
Drupal and Apache Solr Search Go Together Like Pizza and Beer for Your Sitenyccamp
 
Building Social Networks
Building Social NetworksBuilding Social Networks
Building Social Networksnyccamp
 
The State of Drupal 8
The State of Drupal 8The State of Drupal 8
The State of Drupal 8nyccamp
 
Building Social Networks
Building Social NetworksBuilding Social Networks
Building Social Networksnyccamp
 
Move Into Drupal Using The Migrate Module
Move Into Drupal Using The Migrate ModuleMove Into Drupal Using The Migrate Module
Move Into Drupal Using The Migrate Modulenyccamp
 
Hack Into Drupal Sites (or, How to Secure Your Drupal Site)
Hack Into Drupal Sites (or, How to Secure Your Drupal Site)Hack Into Drupal Sites (or, How to Secure Your Drupal Site)
Hack Into Drupal Sites (or, How to Secure Your Drupal Site)nyccamp
 
Drulenium - Testing Made Easy
Drulenium - Testing Made EasyDrulenium - Testing Made Easy
Drulenium - Testing Made Easynyccamp
 

More from nyccamp (19)

Drupal As A Jigsaw
Drupal As A JigsawDrupal As A Jigsaw
Drupal As A Jigsaw
 
A/B Testing and Optimizely Module
A/B Testing and Optimizely ModuleA/B Testing and Optimizely Module
A/B Testing and Optimizely Module
 
Behat - human-readable automated testing
Behat - human-readable automated testingBehat - human-readable automated testing
Behat - human-readable automated testing
 
ALL YOUR BASE (THEMES) ARE BELONG TO US
ALL YOUR BASE (THEMES) ARE BELONG TO USALL YOUR BASE (THEMES) ARE BELONG TO US
ALL YOUR BASE (THEMES) ARE BELONG TO US
 
Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...
Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...
Drupal Commerce - The Product vs Display Conundrum and How to Explain it to a...
 
Promotions Vouchers and Offers in Drupal Commerce
Promotions Vouchers and Offers in Drupal CommercePromotions Vouchers and Offers in Drupal Commerce
Promotions Vouchers and Offers in Drupal Commerce
 
Workbench: Managing Content Management
Workbench: Managing Content ManagementWorkbench: Managing Content Management
Workbench: Managing Content Management
 
Deployment Strategies: Managing Code, Content, and Configurations
Deployment Strategies: Managing Code, Content, and ConfigurationsDeployment Strategies: Managing Code, Content, and Configurations
Deployment Strategies: Managing Code, Content, and Configurations
 
Drupal Aware Design: Good Techniques for Better Themes
Drupal Aware Design: Good Techniques for Better ThemesDrupal Aware Design: Good Techniques for Better Themes
Drupal Aware Design: Good Techniques for Better Themes
 
Drupal and Higher Education
Drupal and Higher EducationDrupal and Higher Education
Drupal and Higher Education
 
A New Theme Layer for Drupal 8
A New Theme Layer for Drupal 8A New Theme Layer for Drupal 8
A New Theme Layer for Drupal 8
 
Mobile and Responsive Design with Sass
Mobile and Responsive Design with SassMobile and Responsive Design with Sass
Mobile and Responsive Design with Sass
 
Drupal and Apache Solr Search Go Together Like Pizza and Beer for Your Site
Drupal and Apache Solr Search Go Together Like Pizza and Beer for Your SiteDrupal and Apache Solr Search Go Together Like Pizza and Beer for Your Site
Drupal and Apache Solr Search Go Together Like Pizza and Beer for Your Site
 
Building Social Networks
Building Social NetworksBuilding Social Networks
Building Social Networks
 
The State of Drupal 8
The State of Drupal 8The State of Drupal 8
The State of Drupal 8
 
Building Social Networks
Building Social NetworksBuilding Social Networks
Building Social Networks
 
Move Into Drupal Using The Migrate Module
Move Into Drupal Using The Migrate ModuleMove Into Drupal Using The Migrate Module
Move Into Drupal Using The Migrate Module
 
Hack Into Drupal Sites (or, How to Secure Your Drupal Site)
Hack Into Drupal Sites (or, How to Secure Your Drupal Site)Hack Into Drupal Sites (or, How to Secure Your Drupal Site)
Hack Into Drupal Sites (or, How to Secure Your Drupal Site)
 
Drulenium - Testing Made Easy
Drulenium - Testing Made EasyDrulenium - Testing Made Easy
Drulenium - Testing Made Easy
 

Recently uploaded

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 

Recently uploaded (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 

Node Access in Drupal 7 (and Drupal 8)

  • 1. Node Access in Drupal 7 (and Drupal 8) Ken Rickard NYCamp 2012 Sunday, July 22, 2012
  • 2. • Who the heck are you? • What is Node Access? • What changed in Drupal 7? • How do I....? • What’s up for Drupal 8? Sunday, July 22, 2012
  • 3. • Ken Rickard • Drupal since 2004 • Domain Access • rickard@Palantir.net • @agentrickard Sunday, July 22, 2012
  • 5. Drupal 7 Module Development Sunday, July 22, 2012
  • 7. What is Node Access? Sunday, July 22, 2012
  • 9. • Powerful • Unintelligible • Unpredictable • Multi-dimensional Sunday, July 22, 2012
  • 10. What is Node Access? Drupal’s system for controlling the access to nodes (content) for: • View • Edit • Delete • and now...Create Sunday, July 22, 2012
  • 11. Drupal 7 Goodness • Create permissions! • Alter hooks! • ‘Bypass node access’ • Access control modules • Node Access API modules Sunday, July 22, 2012
  • 13. chx moshe Crell Dave some Cohen guy Sunday, July 22, 2012
  • 15. Node Access is multipurpose • Filter listing queries. • Assert access rights on CRUD. • API for managing access rights. Sunday, July 22, 2012
  • 17. • Drupal 6: hook_db_rewrite_sql() • Drupal 7: ‘node access’ query flag. Sunday, July 22, 2012
  • 18. Filter queries in Drupal 6 $result = db_query(db_rewrite_sql( “SELECT nid FROM {node} WHERE status = 1 AND promote = 1 ORDER BY sticky DESC, created DESC” )); Sunday, July 22, 2012
  • 19. Filter queries in Drupal 7 $result = db_select('node', 'n') ->fields('n', array('nid')) ->condition('promote', 1) ->condition('status', 1) ->orderBy('sticky', 'DESC') ->orderBy('created', 'DESC') ->addTag('node_access') ->execute(); Sunday, July 22, 2012
  • 20. Failure to tag your query is a security violation. Sunday, July 22, 2012
  • 25. Blue Red Green Grey Our Clients Sunday, July 22, 2012
  • 26. Blue Red Green Grey Organic Groups Sunday, July 22, 2012
  • 27. With proper access control Recent Blue Posts Sunday, July 22, 2012
  • 28. Without proper access control Blue Sunday, July 22, 2012
  • 30. • Node Access is not user_access(). • Node Access is an API for content CRUD permissions. • It extends Drupal’s core permissions system. • It is contextual. Sunday, July 22, 2012
  • 31. Boolean assertions if (user_access(‘administer nodes’)) { return t(“I’ll be back.”); } Sunday, July 22, 2012
  • 32. Conditional access check hook_node_grants($account, $op) hook_node_access($node, $op, $account) Sunday, July 22, 2012
  • 34. • Those two functions look similar. • But they aren’t. Sunday, July 22, 2012
  • 35. node_access() Walk-through function node_access($op, $node, $account = NULL) { $rights = &drupal_static(__FUNCTION__, array()); if (!$node || !in_array($op, array('view', 'update', 'delete', 'create'), TRUE)) { // If there was no node to check against, or the $op was not one of the // supported ones, we return access denied. return FALSE; } // If no user object is supplied, the access check is for the current user. if (empty($account)) { $account = $GLOBALS['user']; } Sunday, July 22, 2012
  • 36. // $node may be either an object or a node type. Since node types cannot be // an integer, use either nid or type as the static cache id. $cid = is_object($node) ? $node->nid : $node; // If we've already checked access for this node, user and op, return from // cache. if (isset($rights[$account->uid][$cid][$op])) { return $rights[$account->uid][$cid][$op]; } if (user_access('bypass node access', $account)) { $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } if (!user_access('access content', $account)) { $rights[$account->uid][$cid][$op] = FALSE; return FALSE; } Sunday, July 22, 2012
  • 37. // We grant access to the node if both of the following conditions are met: // - No modules say to deny access. // - At least one module says to grant access. // If no module specified either allow or deny, we fall back to the // node_access table. $access = module_invoke_all('node_access', $node, $op, $account); if (in_array(NODE_ACCESS_DENY, $access, TRUE)) { $rights[$account->uid][$cid][$op] = FALSE; return FALSE; } elseif (in_array(NODE_ACCESS_ALLOW, $access, TRUE)) { $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } // Check if authors can view their own unpublished nodes. if ($op == 'view' && !$node->status && user_access('view own unpublished content', $account) && $account->uid == $node->uid && $account->uid != 0) { $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } Sunday, July 22, 2012
  • 38. foreach (node_access_grants($op, $account) as $realm => $gids) { foreach ($gids as $gid) { $grants->condition(db_and() ->condition('gid', $gid) ->condition('realm', $realm) ); } } if (count($grants) > 0) { $query->condition($grants); } $result = (bool) $query ->execute() ->fetchField(); $rights[$account->uid][$cid][$op] = $result; return $result; } Sunday, July 22, 2012
  • 39. elseif (is_object($node) && $op == 'view' && $node->status) { // If no modules implement hook_node_grants(), the default behavior is to // allow all users to view published nodes, so reflect that here. $rights[$account->uid][$cid][$op] = TRUE; return TRUE; } } return FALSE; } Sunday, July 22, 2012
  • 41. hook_node_access($node, $op, $account) • Replaces hook_access(). • Can be run by any module! • Can return TRUE, FALSE or NULL. • Used for access to individual nodes. Sunday, July 22, 2012
  • 42. Access control modules • Act on Create, View, Update & Delete. • No tables*. • No queries*. • Just business logic. • DENY, ALLOW, IGNORE Sunday, July 22, 2012
  • 43. The operation condition matters! ‘create’ ‘delete’ ‘update’ ‘view’ Sunday, July 22, 2012
  • 45. /** * Implement hook_node_access(). * * Only allow posts by users more than two days old. */ function delay_node_access($node, $op, $account) { if ($op != 'create') { return NODE_ACCESS_IGNORE; } if (empty($account->created) || $account->created > (REQUEST_TIME - (48*3600))) { return NODE_ACCESS_DENY; } return NODE_ACCESS_IGNORE; } Sunday, July 22, 2012
  • 47. • No more hook_menu_alter(). • Explicit DENY grants. • Explicit ALLOW grants. • Apply to all node types! • Apply to node creation! Sunday, July 22, 2012
  • 49. • Individual nodes / actions only. • Running lookup queries per node can be expensive. • Can override other modules. • Cannot generate accurate lists. Sunday, July 22, 2012
  • 51. NODE ACCESS API • Uses {node_access} for list queries. • Creates JOINs to return lists of nodes. • Does not act on ‘create’ operation. • Requires numeric keys. Sunday, July 22, 2012
  • 53. hook_node_access_records() Data Entry node_save() node_access_acquire_grants() {node_access} Sunday, July 22, 2012
  • 54. function example_node_access_records($node) { $grants[] = array( 'realm' => 'example_author', 'gid' => $node->uid, 'grant_view' => 1, 'grant_update' => 1, 'grant_delete' => 1, 'priority' => 0, ); return $grants; } Sunday, July 22, 2012
  • 55. hook_node_grants() Inbound Request $user node_access_grants() Page / Request Render Sunday, July 22, 2012
  • 56. function example_node_grants($account, $op) { if (user_access('access private content', $account)) { $grants['example'] = array(1); } $grants['example_owner'] = array($account->uid); return $grants; } Sunday, July 22, 2012
  • 57. • Map the user’s grants to the stored grants. • JOIN {node_access} to the query. • Return the node or not. • OR based access logic. Sunday, July 22, 2012
  • 58. • Two-part system! • One query does not cover all cases! ‘create’ ‘delete’ ‘update’ ‘view’ Sunday, July 22, 2012
  • 60. Rebuilding the {node_access} table Sunday, July 22, 2012
  • 61. • Make sure you hook_node_load() your data. • node_load() must match node_save() • Other modules may depend on you! Sunday, July 22, 2012
  • 62. Devel Node Access • Debugging tools for developers. • And site administrators! Sunday, July 22, 2012
  • 63. hook_node_access_explain() /** * Implements hook_node_access_explain for devel.module */ function domain_node_access_explain($row) { $_domain = domain_get_domain(); $active = $_domain['subdomain']; $domain = domain_lookup($row->gid); $return = t('Domain Access') . ' -- '; switch ($row->realm) { case 'domain_all': if (domain_grant_all() == TRUE) { $return .= t('True: Allows content from all domains to be shown.'); } else { $return .= t('False: Only allows content from the active domain (%domain) or from all affiliates.', array('%domain' => $active)); } Sunday, July 22, 2012
  • 65. Add debugging to your module, too Sunday, July 22, 2012
  • 67. hook_node_access_records_alter() • Change storage rules before they are written to the database! • Remember to alter node storage as needed, too!* • * Runs after node_save() :-( Sunday, July 22, 2012
  • 68. function hook_node_access_records_alter(&$grants, $node) { // Our module allows editors to mark specific articles // with the 'is_preview' field. if ($node->is_preview) { // Our module grants are set in $grants['example']. $temp = $grants['example']; // Now remove all module grants but our own. $grants = array('example' => $temp); } } Sunday, July 22, 2012
  • 69. hook_node_grants_alter() • Alter the user’s grants at request time. • Quick and easy! Sunday, July 22, 2012
  • 70. function hook_node_grants_alter(&$grants, $account, $op) { // Get our list of banned roles. $restricted = variable_get('example_restricted_roles', array()); if ($op != 'view' && !empty($restricted)) { foreach ($restricted as $role_id) { if (isset($user->roles[$role_id])) { $grants = array(); } } } } Sunday, July 22, 2012
  • 71. hook_query_alter() /** * Implements hook_query_TAG_alter(). * * If enabled, force admins to use Domain Access rules. */ function domain_query_node_access_alter($query) { $admin_force = variable_get('domain_force_admin', FALSE); // In any of the following cases, do not enforce any rules. if (empty($admin_force) || !user_access('bypass node access') || domain_grant_all()) { return; } domain_alter_node_query($query); } Sunday, July 22, 2012
  • 73. It’s not a tumor. Sunday, July 22, 2012
  • 74. Drupal 8 Changes • Language-sensitive • Abstract to all entities • Remove hook_node_access()? • Better list queries in core? • Support AND and OR logic? Sunday, July 22, 2012
  • 75. function node_access($op, $node, $account = NULL, $langcode = NULL) { $rights = &drupal_static(__FUNCTION__, array()); ... // If we've already checked access for this node, user and op, return from // cache. if (isset($rights[$account->uid][$cid][$langcode][$op])) { return $rights[$account->uid][$cid][$langcode][$op]; } if (user_access('bypass node access', $account)) { $rights[$account->uid][$cid][$langcode][$op] = TRUE; return TRUE; } if (!user_access('access content', $account)) { $rights[$account->uid][$cid][$langcode][$op] = FALSE; return FALSE; } Sunday, July 22, 2012
  • 76. Key issues • Make a general access API • http://drupal.org/node/777578 • Make node_access() language aware • http://drupal.org/node/1658814 • Query madness • http://drupal.org/node/1349080 Sunday, July 22, 2012
  • 77. Let’s get to work Sunday, July 22, 2012
  • 78. • THANK YOU! • Ken Rickard • rickard@Palantir.net • @agentrickard Sunday, July 22, 2012