SlideShare una empresa de Scribd logo
1 de 78
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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 a 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 a 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
 

Más de 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
 

Más de 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
 

Último

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 

Último (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 

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