Progressive Decoupling How U.S. Courts added a headless

Progressive Decoupling How U.S. Courts added a headless

Progressive Decoupling How U.S. Courts added a headless D8/Angular service to a legacy D7 intranet Natalie Beneventi | Kevin McCulloch Natalie Beneventi Kevin McCulloch Web Operations Coordinator

Lead Developer/DevOps Engineer Project management ninja. Total nerd. I can probably beat you on Rock Band (but only on medium). Drupal geek since 2011. First DrupalCon Denver 2012 Coder, nerd, etc. Easily beaten on Rock Band. Drupaler since 2010. First DrupalCon Portland 2013

@NatBeneventi https://github.com/kmcculloch https://www.drupal.org/u/kmcculloch Who are these guys anyway? The Administrative Office of the United States Courts is an agency within the judicial branch that provides a broad range of legislative, legal, financial, technology, management, administrative, and program support services to federal courts.

Uscourts.gov What did they want to do? Court/Administrative Office Exchange Programs Image of legacy coax?

What were they trying to do? Convert a legacy D6 web site into a headless D8/JSON API web app and display it

on a D7 web site. Why (on Earth) did they want to do that? What you always wanted to know about our Intranet (but were afraid to ask) First Drupal Site Launched in 2013

Serves the entire Judiciary Large and unwieldly (and grumpy) Heavily dependent on Workbench suite Due for a redesign Undergoing usability study and content review It all came down to two choices: Expand our Drupal 7 code to handle usersubmitted content outside of our preexisting publishing workflow

Or build a separate web app for application handling and host it on JNet. Oh no you didnt. Grumpy JNet

Advantages of a Decoupled Approach No more bloat in our D7 code No new D7 content types with non-standard workflow Lightweight development environment Chance to try D8 Chance to evaluate decoupling for other services No angry kittens Why Angular? Team had some prior experience

Online tutorials fit our expectation of how the app should be structured Its well established Had to pick one js framework and try it in order to really evaluate any of them Was Angular the Right Choice? Maybe? Learning curve for PHP developers is steep Promises and observables an unfamiliar paradigm Took more lines of code than we expected We like the strict typing approach of Typescript Resulting application is large, but very robust

Ultimately, It Was a Trade-Off: But we expected to get much more value for that work. We knew that a decoupled approach would be as much (or more) work than expanding our D7 code

Demo How did they do it? Three Components Drupal 8 back end Angular front end Drupal 7 application loader module to load the Angular app and pass it the Drupal 7 user context

1. Drupal Application Loader Module Self-service registration and a single-login experience were must-have requirements Agile wisdom: do the riskiest part first Account Strategy JNet registration already self-service Added a new, auto-generated COAX Password field on every account When user visits the portal, the user name and COAX pw are passed to Angular Angular requests a token

If the token request fails, Angular posts the username and pw to /rest/register The new back end account has default permissions (able to apply) The COAX Password is handled by the users browser but is invisible to the user (unless they inspect their requests) D7: Use hook_menu( ) to make a home for the app

'Account Portal', 'page callback' => 'jnet_coax_wrapper_page', 'access callback' => TRUE,

); return $items; } D7: Pass an array of user data to Drupal. settings function jnet_coax_wrapper_page() {

// ... // Pass an array of config values to bind to the JavaScript window. $coaxConfig = array( 'baseUrl' => $backend_url, 'clientId' => $client_id, 'clientSecret' => $client_secret, 'authenticated' => FALSE, 'username' => '', 'password' => '', 'mail' => '', 'xCsrfToken' => $xcsrf_token,

'debug' => FALSE, 'portalPath' => JNET_COAX_BASE_URL, ); if ($user->uid !== 0) { $account = user_load($user->uid); $wrapper = entity_metadata_wrapper('user', $account); $password = $wrapper->field_coax_password->value(); $coaxConfig['username'] = $user->name; $coaxConfig['password'] = $password; $coaxConfig['mail'] = $user->mail; $coaxConfig['authenticated'] = TRUE;

} drupal_add_js(array('coaxConfig' => $coaxConfig), 'setting'); function jnet_coax_wrapper_page() { D7: Pass an array of Angular assets to Drupal. settings

// ... // Pass an array of Angular assets to load. $path = drupal_get_path('module', 'jnet_coax'); $coaxPaths = array( '/' . $path . '/dist/inline.b3008e6eda770fa1abaf.bundle.js', '/' . $path . '/dist/polyfills.55206efc080210e2e43f.bundle.js', '/' . $path . '/dist/vendor.b9d9328276e4955fdf69.bundle.js', '/' . $path . '/dist/main.c5e0676673775805c27b.bundle.js', ); drupal_add_js(array('coaxPaths' => $coaxPaths), 'setting');

// Add CSS assets. drupal_add_css($path . '/dist/styles.2f3fdb9c3cca6cde2cf3.bundle.css'); // Add JS loader. drupal_add_js($path . '/jnet_coax.js'); function jnet_coax_wrapper_page() { D7: Return the markup to anchor

Angular // ... // Add the base header tag so that Angular can handle routing. drupal_add_html_head(array( '#tag' => 'base', '#attributes' => array( 'href' => '/' . JNET_COAX_BASE_URL, ), ), 'base_href'); // Finally, return a tiny bit of markup: the Angular directive

// needed to bootstrap the app. return array(array('#markup' => ')); } D7: Use js to load Angular and hand over configuration

(function($) { $(document).ready(function() { // Pass coaxConfig values to the window, so Angular can get them. window.coaxConfig = Drupal.settings.coaxConfig; // Set up a recursive function that will load the scripts in strict order. function load_scripts(scripts) { var script = scripts.shift(); if (script) { $.getScript(script, function () { if (scripts.length > 0) {

load_scripts(scripts); } }); } } // Fetch the name of the Angular scripts to load. var scripts = Drupal.settings.coaxPaths || []; // Call the script loader. load_scripts(scripts); }); }(jQuery));

2. Drupal 8 Back End Key architectural principle: all application security is enforced in the back end Use Drupal content types to model data (opportunities, applications) Use Drupal roles to define permission levels (applicants, approvers, managers) Use custom fields to define workflow (application status: submitted, accepted, rejected) Use a custom module with node access hooks to fine-tune the permissions and hide sensitive data (applicants cannot see rejected status) Back End Inputs/Outputs

/user/register REST endpoint for account creation /oauth/token endpoint (simple_oauth) for authentication /jsonapi endpoints (jsonapi) for CRUD Lock down everything you do not need Behat is perfect for validating your setup and guarding against regressions Feature: Application status visibility Example Behat Test

Background: Given applicants: | name | | applicant1 | Given applications: | id | author | status | application1 | applicant1 | submitted

| application2 | applicant1 | rejected | | | Scenario: Applicants can see "submitted" status Given I am "applicant1" When I request application "application1" Then I should see application status "submitted" Scenario: Applicants can not see "rejected" status

Given I am "applicant1" When I request application "application2" Then I should see application status "submitted" 3. Angular Front End Angular code and node.js tooling lives in separate repo Build a container for the app that simulates JNet Build a little widget to pass sample user contexts into the app Use node to serve the app on localhost and code easily To deploy, build a release and move assets to the JNet application loader

Local Developmen t is Easy! BUT One last hurdle! The Dreaded SECURITY SCAN! Not that bad actually This architecture was new to them, too Grateful for an external review Security team found a vulnerability in a contrib module and were amazed when

Kevin submitted a patch and got an immediate response from the maintainer How did it turn out? Nailed it! Seamless launch Flawless integration with JNet Improved end user and manager experience Only minor change requests post launch

JNet still happy U.S. Courts security team sold on the value of open source ? Join us for contribution sprints Friday, April 13, 2018 Mentored

Core sprint First time sprinter workshop General sprint 9:00-12:00 Room: Stolz 2

9:00-12:00 Room: Stolz 2 9:00-12:00 Room: Stolz 2 #drupalsprint What did you think? Locate this session at the DrupalCon Nashville website: http://nashville2018.drupal.org/schedule

Take the Survey! https://www.surveymonkey.com/r/nashiville

Recently Viewed Presentations

  • Big Bang Theory - Grosse Pointe Public School System

    Big Bang Theory - Grosse Pointe Public School System

    Expansion(bang) hurled material in all directions Allmatter/space/time created in that instant Evidence that supports the Big Bang Theory 1.Cosmological Red Shift- all galaxies (outside the Local Group) are showing a red shift Equal expansion Hubble's Law Farther galaxies are receding...
  • Chapter 1: Statistics - Radford University

    Chapter 1: Statistics - Radford University

    2. One variable is qualitative (attribute) and the other is quantitative (numerical). 3. Both variables are quantitative (both numerical). Two Qualitative Variables: When bivariate data results from two qualitative (attribute or categorical) variables, the data is often arranged on a...
  • Diapositiva 1 - Eartvic

    Diapositiva 1 - Eartvic

    Pintura metafísica ARTISTES: Giorgio de Chirico Paul Klee Carlo Carrà GIORGIO DE CHIRICO Recupera la perspectiva del segle XV, alterant deliberadament la seva lògica, l'estabilitat i l'ordre Presència d'estàtues clàssiques, edificis del renaixement i xemeneies de fàbriques Cada objecte té...
  • שקופית 1 - meyda.education.gov.il

    שקופית 1 - meyda.education.gov.il

    From this remarkable legacy came the Mahzor Vitry in two-volumes, a Festival prayer book copied in France around the middle of the 13th century , the Lexicon of Menahem ben Saruk dated 1091 , probably the oldest extant copy known,...
  • 590 Division Project Reviews 12/01/04 Project Plan, Tasks ...

    590 Division Project Reviews 12/01/04 Project Plan, Tasks ...

    Spacewire (1355) TBD. UART/Serial I/F. Comments. Only 1 UART (LAMP) EEPROM. 64 K PROM for Boot Loader Only (SDO heritage) 20 MRAM >50% >80%. Margin. 2 banks of 2M each cFe and other heritage s/w makes estimate quite mature. LRO...
  • The Sound of Silence - Prairie Ridge Integrated Behavioral ...

    The Sound of Silence - Prairie Ridge Integrated Behavioral ...

    The Sound of Silence. ... PET scans show that, in someone with a history of addiction, when presented with pictures of the drug or paraphenalia, the amygdala becomes very active. ... However, the areas of the brain that do self-reflection,...
  • Thinking and Language

    Thinking and Language

    Thinking and concepts. Without concepts, we would need a different name for every person, event, object, and idea. We could not just simply say, "They are angry."
  • Shepway District Governor Briefing Autumn 2015 Welcome Agenda

    Shepway District Governor Briefing Autumn 2015 Welcome Agenda

    Progress in Implementing Proposals. For September 2015 our commissioning intentions were to: Open Martello Grove Academy -opened off-site in Morehall PS.