官术网_书友最值得收藏!

Scripting in scoped apps

Scoped applications represent a fresh start for ServiceNow. Application scope, introduced in the previous chapter, provides a bubble around each app, very carefully controlling what it can do.

Note

Almost all the code in this book is for our Hotel application. All the scripting functionality discussed, unless indicated otherwise, uses the scoped API.

Without scoping, when you run a server-side script, you have access to the whole database. Remember the warning when you ran a background script? You can easily delete every record in the user table. Your boss probably won't be happy if he can't log in to run some reports.

In many regards, scripting outside of a scoped application is like the Wild West: there is an "anything goes" attitude, where your clever moves might result in a gold mine-or the sheriff may take offence to your attitude. There are numerous clever tricks letting you access deep, dark parts of the platform, but this often results in relying on functionality that the ServiceNow developers wish you'd never found.

Note

A good example is the use of Java packages, discussed later in this chapter, which in older versions provides access to the core platform.

To provide a clean, wholesome scripting environment, scoped applications have access only to the scoped API. Think of it like a newly designed and constructed town. The roads are straight, the grass trimmed, and the buildings neat. But it also means that many of the facilities of an older town are absent.

Being in scope

The scoped API gives a fresh start, but does mean that any fewer ServiceNow classes are available. Several have had methods renamed. But those that can be used are deemed to be 'safe', and much more documentation is available.

Tip

For example, the old way of writing to the system log was gs.log(<message>). One simple impact of the scoped API is that this has now changed to gs.info(<message>) (or gr.error and so on). The immediate impact of this means that copying and pasting old code might not work! The new method does work in non-scoped apps, though.

The Fuji release of ServiceNow introduced the scoped API, and it quickly became apparent that developers building apps on the platform wanted to do many more things than were initially allowed. Later versions of ServiceNow have dramatically expanded what is available.

Note

To see what has changed, navigate to the API on the developers portal, and toggle between the different API versions. Fuji has 35 classes available, Geneva has 49, and Helsinki has 50.

Improving scripting with ECMAScript 5

But what's most exciting about scripting in Helsinki-based scoped applications is the use of ECMAScript 5. JavaScript aficionados may roll their eyes since ECMAScript 5 is pretty old hat; being published in 2011. But considering that all server-side scripts historically used ECMAScript 3, this is a big change.

Tip

ECMAScript is the standard that JavaScript is based on. The history of ECMAScript is outlined in this Wikipedia article: https://en.wikipedia.org/wiki/ECMAScript#History

ECMAScript 5 brings many improvements, including several new array functions. Previously, to work through an array, you would typically use a for loop. For example, if you wanted to log all the elements of an array, you could run this code:

var x = [1, 3, 5]; 
for (var i = 0; i < x.length; i++) { 
  gs.info(x[i]); 
} 

But ECMAScript 5 gives you a forEach function, which accepts a callback function. Both these scripts give exactly the same output, but ECMAScript 5 is shorter and more descriptive.

[1, 3, 5].forEach(function (x) { gs.info(x) }); 

Direct JSON encoding and decoding is also available (with JSON.stringify and JSON.parse), as is support for getters and setters. Also rather exciting is the availability of trim - so " test ".trim() will remove the spaces.

Perhaps most importantly, ECMAScript 5 introduces strict mode. This removes some of quirks of JavaScript, making the execution of your code less forgiving. JavaScript was designed to be forgiving and easy, but this sometimes stores up errors for the future. For example, accidently making global variables is much harder.

Tip

Strict mode is invoked by starting the script or a function with "use strict";. For more information on strict mode, take a look at MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode.

Whilst the majority of the code you write may not change, many libraries take advantage of these benefits. This lets you bring in outside code much more easily. Lodash is one of those libraries that can now be available in ServiceNow. Check out https://lodash.com/ if you wish to take advantage of its many features.

Tip

There are many articles exploring what ECMAScript 5 can do. Try this one to start with: http://speakingjs.com/es5/ch25.html.

Activating ECMAScript 5

ServiceNow has a quite a few customers, who have written quite a lot of code. In order to protect it, and ensure it doesn't break when upgrading, the introduction of ECMAScript 5 in Helsinki is done using a compatibility mode. This mimics some of the idiosyncrasies of ServiceNow's version of ECMAScript 3, including ignoring references to properties of undefined objects and ignoring calls to non-existent functions. Strict mode is also not supported in compatibility mode.

ECMAScript 5 is only officially supported in scoped applications. To ensure it is turned on, open Studio, then go to the Application Settings, and verify that ES5 Standards Mode is selected in JavaScript Mode. Compatibility mode is always used for script in in the global scope.

However, there is only one JavaScript engine in ServiceNow. So while scripts in compatibility mode can access some of the great new features of ECMAScript 5 (such as array.forEach), it isn't fully compliant. So beware!

Protecting data from scripts

As we are seeing, scoped applications have many advantages, including being able to control and protect data from scripts. To see how this works, we need multiple interacting applications. Let's create another application that wants to interact with the information in our hotel application in order to alter the list of guests and look at their rooms. Consider that Gardiner Hotels is branching out into amusement parks and wants to build an application to manage the hair-raising rollercoasters and other attractions that will inevitably feature.

  1. To create an application, navigate to System Applications > Applications and click on New.
  2. Since we only want the container for this experiment, click on Create next to Start from scratch. Fill in the following values, and note the value that is automatically populated in the Scope field.
    • Name: Theme Park

    Tip

    If you are using a developer instance, the scope field should be unique, and look something like x_69373_theme_park. Depending on your situation, you may need to adjust this to be unique.

  3. Click on Create, then OK to create the application. Close the dialog box when you are told the application has been created.
  4. Once done, ensure you are in the standard interface, and navigate to System Definition > Scripts - Background.
  5. Paste in this code, but before pressingRun script, change the scope to <prefix>_theme_park, the application scope you just created:
    var results = []; 
    var gr = new GlideRecord('x_hotel_room'); 
    gr.setLimit(1); 
    gr.query(); 
    while(gr.next()) { 
      gr.update(); 
    } 
    

    This code creates a new GlideRecord object to query the Room table and attempts to save the record to the database. (Since no fields in the table were altered, nothing will actually change, but it is still a good test.)

  6. You should get three messages:

    Security restricted: Read operation against 'x_hotel_room' from scope 'x_69373_theme_park' was granted and added to 'x_69373_theme_park' cross-scope privileges Security restricted: Access to API 'ScopedGlideRecord' from scope 'x_69373_theme_park' was granted and added to 'x_69373_theme_park' cross-scope privileges Security restricted: Write operation against 'x_hotel_room' from scope 'x_69373_theme_park' has been refused due to the table's cross-scope access policy

    These three messages tell you what is happening:

    • Firstly, the script attempts to query the Room [x_hotel_room] table. By default, read access from outside the scope is allowed. So this was granted, and recorded.
    • Additionally, this was the first time that the Theme Park application used GlideRecord. You may remember this message from Chapter 2Developing Custom Applications.
    • It essentially says that you are using one of the ServiceNow APIs, which are also allowed by default. (You could stop the Theme Park application from querying the database through scripts by revoking this cross-site privilege.)

      Tip

      Note that the message refers to ScropedGlideRecord rather than just GlideRecord. Global and scoped code actually use different ServiceNow APIs; the ones that are allowed are documented as noted above.

    • Finally, your attempt to update the record is thwarted. By default, scripts running from a different application cannot update database tables. If you want to change this behavior, you can use the Application Access fields in the Table record, as described in the Controlling application access section in Chapter 2, Developing Custom Applications.

Running scripts in global

Helsinki brought a pretty fundamental change. Previously, scripts running in the global scope had access to everything - even tables of another application. But this has now changed. Now scripts running in the global scope are subject to the same access requirements as those running in application scopes.

To see this, try running the script again, but change the scope selection to global. You will notice that access to updating the table will again be denied. The diagram below shows how scripts from different scopes are handled.

Building the restrictions

The behavior of restricting table access is designed to prevent applications from interfering with each other. It moves towards having sandbox-style protection, ensuring that two applications are separate and independent. It prevents malicious-or buggy!-apps from causing havoc by deleting or changing data they should not. As you build your applications, consider what data you want to expose. In general, keeping it restricted is a good idea. To let other applications control your data, consider building an API-explored later in the chapter.

Note

Table application access is a key protection mechanism to allow for applications that have been developed by third-party developers. As discussed in Chapter 10, Packaging with Applications, Update Sets, and Upgrades, the app store lets you download and use code that could potentially interact with your data.

主站蜘蛛池模板: 水富县| 嘉祥县| 宝清县| 南投市| 洛阳市| 桃江县| 庆元县| 根河市| 琼结县| 兴安县| 米泉市| 山东| 长泰县| 镇远县| 饶河县| 商河县| 封开县| 丰台区| 土默特右旗| 石阡县| 眉山市| 湖北省| 准格尔旗| 林口县| 沿河| 合水县| 平江县| 佛冈县| 仙居县| 鲜城| 泸水县| 武城县| 靖宇县| 鄱阳县| 鄂托克前旗| 班玛县| 缙云县| 石泉县| 梅河口市| 清原| 湖北省|