レコード権限 DSL (ドメイン固有言語) を使用して、特定のテーブルのレコードに対するアクセスルールを指定します。
レコード権限 DSL の主な目的は、Java コーディングを必要とせず、プログラミングの深い知識がない人でも簡単に使用できるようにすることです。
スクリプトを使用して、任意のテーブルに対する権限を指定できます。スクリプトは、レコードの権限を示す一連の if then else および return ステートメントで構成されます。
データモデルアシスタント (DMA) を使用してスクリプトを編集できます。
スクリプトの構造は次のとおりです。
begin <statement 1> <statement 2> ... <last statement> end
最後のステートメントを除くすべてのステートメントは、「if then」または「if then else」ステートメントにする必要があります。
最後のステートメントは「if then」、「if then else」または「return」ステートメントです。
例
if isMember(administrator) then // Administrator has no restrictions. return readWrite; if isMember('french-team') and record.Country='F' then //Members of 'french-team' can view and modify data for France. return readWrite; if isMember('us-team') and record.Country='US' then //Members of 'us-team' can view and modify data for US. return readWrite; // This statement is not actually needed as 'hidden' is the default permission. return hidden;
Unicode 文字セットがサポートされています。
DSL では大文字と小文字が区別されます。
1 行のコメントは、// から現在の行の終わりまで拡張されます。
// This is a comment if record.LastName = 'Doe' then // This is another comment. return readOnly;
複数行のコメントは /* から始まり、*/ で終わります。
/* This is a sample of a multi-line comment */ if record.isActive then return readWrite;
キーワードには次の 2 種類があります。
予約済みキーワード:if、then、else、begin、end、return、null、and、or、not 、true、false。
予約されていないキーワードは、DSL によって定義されている他のすべてのキーワードです。
2 種類のキーワードの主な違いは、予約されていないキーワードは、プレーンな (引用符で囲まれていない) 識別子として使用できることです。
引用符なしの識別子 は、文字、数字、またはアンダースコア ( _ ) の無制限の長さのシーケンスです。最初の文字は、文字またはアンダースコアにする必要があります。
有効な文字は a から z および A から Z です。有効な数字は 0 から 9 です。
引用符で囲まれていない識別子は、予約済みのキーワードと同じにすることはできません。
引用符付き識別子は、二重引用符 ( " ) を除く、無制限の長さの任意の Unicode 文字です。
引用符で囲まれた識別子は、二重引用符で囲んで使用する必要があります。
引用符なしの識別子は、二重引用符で囲んで使用できます。これは、識別子 ”a_name” が a_name と等しいことを意味します。
引用符付きの識別子は予約済みのキーワードにすることができます。
次の型がサポートされています。
型 | EBX® 対応型 |
---|---|
ブール値 | xs:boolean |
10 進数 | xs:decimal xs:int xs:integer |
文字列 | xs:string xs:anyURI xs:Name osd:text osd:html osd:email osd:password osd:color osd:resource osd:locale osd:dataspaceKey osd:datasetName |
タイムスタンプ | xs:dateTime |
日付 | xs:date |
時間 | xs:time |
文字列リテラルは、一重引用符で囲まれた Unicode 文字の任意のシーケンスにすることができます。次の表は、エスケープシーケンスで置き換える必要のある文字を示しています。
文字 | エスケープシーケンス |
---|---|
タブ | \t |
バックスペース | \b |
改行 | \n |
キャリッジリターン | \r |
フォームフィード | \f |
一重引用符 | \' |
バックスラッシュ | \\ |
文字は、Unicode 文字の 16 進コード XXXX を使用した \uXXXX 形式の Unicode エスケープシーケンスで指定できます。
例
値 | 構文 |
---|---|
O’Harra | 'O\'Harra' |
Noël | 'No\u00EBl' |
été | '\u00e9\u00E9' |
注意
無効なエスケープまたは Unicode シーケンスは、コンパイル時にエラーを生成します。
次の 10 進形式がサポートされています。
形式 | 例 |
---|---|
整数 | 546 -67 |
浮動小数点数 | 54.987 -433.876 0.00054 -0.0032 |
指数表記 | 34.654e-5 -45E+65 1.543e23 |
タイムスタンプリテラルの形式は dt(yyyy-MM-dd hh:mm:ss.sss) です。
秒はオプションです。秒が指定されていない場合、0 が想定されます。秒は、ミリ秒の精度までの小数部を持つことができます。
グレゴリオ暦で無効な日付は、コンパイル時にエラーを生成します。
例
dt(2010-01-02 00:00:00.000) dt(2019-2-3 12:56:7) dt(2019-2-3 12:56:7.5) dt(2019-5-7 1:6)
日付リテラルの形式は d(yyyy-MM-dd) です。
グレゴリオ暦で無効な日付は、コンパイル時にエラーを生成します。
例
d(2010-01-02) d(2019-2-3) dt(2019-5-7)
時間リテラルの形式は t(hh:mm:ss.sss) です。
秒はオプションです。秒が指定されていない場合、0 が想定されます。秒は、ミリ秒の精度までの小数部を持つことができます。
無効な時間は、コンパイル時にエラーを生成します。
例
t(00:00:00) t(12:56:7) t(12:56:7.5) t(1:6)
ブール値リテラルは true と false です。
最適化/インデックス付きテーブルフィールドへのアクセスのみがサポートされています。ドット表記は、テーブルフィールドにアクセスするために使用されます。たとえば、パスが ./OfficeAddress/City である現在のテーブルフィールドの条件は次のようになります。
if record.OfficeAddress.City = 'Paris' then return readWrite;
エイリアス record は、常に現在のレコードを参照します。コンテキストによっては、他のエイリアスが使用できる場合があります。
各ステップ (ドットで区切られた部分) は識別子です。これは、次の引用表記を任意のステップに使用できることを意味します。
if record."OfficeAddress".City = 'Paris' then return readWrite;
これは、予約済みのキーワードに相当するステップや、マイナス文字 ( - ) やドット ( . ) などの文字を使用するステップに役立ちます。これらは、引用符で囲まれていない識別子と互換性がありません。
実行時に、どのステップも null と評価される可能性があります。この場合、完全なフィールド式は null と評価されます。
ドット表記を使用して外部キーを「フォロー」することにより、外部テーブルにアクセスできます。
次の例では、フィールド Supervisor は外部キーです。
if record.Supervisor.Name = 'John Doe' then return readWrite;
次の例のように、複数レベルの外部キーが存在する場合もあります。
if record.Supervisor.Supervisor.Supervisor.Name = 'John Doe' then return readOnly;
複数値フィールドはサポートされていません。
集計関数は、関連付けに基づいて入力式として受け取ることができます。次の例では、フィールド ManagedUsers は関連付けです。
// All users that manage at least 2 persons have read write access. if count(record.ManagedUsers[]) >= 2 then return readWrite;
関連付けにフィルターを適用できます。関連付けからフィールドにアクセスするには、エイリアスを使用する必要があります。関連エイリアスは : を使用して宣言されます。次の例では、エイリアスは u1 です。
// All users that manage at least one person whose office is in Briton has read only access. if exists(record.ManagedUsers:u1[u1.OfficeAddress.City='Briton']) then return readOnly;
関連付けのフィルターは、現在のレコードのフィールドを参照できます。
// All users that manage at least one person whose office is in the same city as user has read only access. if exists(record.ManagedUsers:t1[t1.OfficeAddress.City=record.OfficeAddress.City]) then return readOnly;
注意
現在、次のことはできません。
[] の間に集約関数を使用する。
値を集計する関連付けのフィールドを選択する。
デフォルトでは、操作の評価順序は優先順位と結合性に基づいています。評価の順序は、括弧を使用して明示的に示すことができます。
次の表は、優先順位の高いものから低いものへのすべての演算子とそれらの関連性を示しています。
優先順位 | 演算子 | オペランド型 | 結果型 | 結合性 |
---|---|---|---|---|
8 | [] (リストのエレメントへのアクセス) . (フィールドへのアクセス) () (括弧) | リストインデックスは 10 進数にする必要があります。 | 任意の型にすることができます。 | 左から右へ |
7 | not | ブール値 | ブール値 | |
6 | * / | 10 進数 | 10 進数 | 左から右へ |
5 | + - | 10 進数 | 10 進数 | 左から右へ |
4 | < <= >> >= | 文字列、10 進数、タイムスタンプ、日付、時刻 (3)。 | ブール値 | 連想的ではありません。 |
3 | = <> | 文字列、10 進数、タイムスタンプ、日付、時刻、ブール値 (3)。 | ブール値 | |
2 | and | ブール値 | ブール値 | 左から右へ |
1 | or | ブール値 | ブール値 | 左から右へ |
算術演算子 ( * 、/ 、+ および - ) は null を返します。オペランドは null です。
比較演算子 ( <、<=、>、=>、= および <> ) は、いずれかのオペランドが null の場合、 null を返します。
ブール演算子はスレッド値ロジックを使用します。
AND の真偽 (true/false) 表は次のとおりです。
And | true | false | null |
true | true | false | null |
false | false | false | false |
null | null | false | null |
OR の真偽 (true/false) 表は次のとおりです。
Or | true | false | null |
true | true | true | true |
false | true | false | null |
null | true | null | null |
null と評価されるか範囲外のインデックスを持つインデックス付き式は、 null を返します。
パラメーターが null の場合、関数は通常 null を返します。例外は関数 isNull(value) で、null を返すことはありません。
「if then」ステートメントの構文は次のとおりです。
if condition-expression then then-body-statement
条件式はブール型として評価される必要があります。
式が true と評価された場合、「then」ステートメントが実行されます。式が false または null と評価された場合、「then」ステートメントは無視されます。
「then」ステートメントは body ステートメント です。
「if then else」ステートメントの構文は次のとおりです。
if condition-expression then then-body-statement else else-body-statement
条件式はブール型にする必要があります。
式が true と評価された場合、「then」ステートメントが実行されます。式が false または null と評価された場合、「else」ステートメントが実行されます。
「then」または「else」ステートメントは body ステートメント です。
注意
if condition-expression then statement-a; else statement-b;
上記の式は、以下の式とは同等ではない可能性があります。
if not condition-expression then statement-b; else statement-a;
実際、式が null の場合、どちらの場合も「else」ステートメントが実行されます。
本文のステートメントは次のようになります。
「if then」または「if then else」ステートメント
ステートメントブロック
ステートメントブロックは、複数のステートメントをグループ化するために使用されます。キーワード begin で始まり、キーワード end で終わります。
begin <statement 1> <statement 2> ... <last statement> end
最後のステートメントを除くすべてのステートメントは、「if then」または「if then else」ステートメントにする必要があります。
最後のステートメントは 「if then」、「if then else」または「return」ステートメントです。
if isMember('sales-team')then begin if record.Country='F' then return readWrite; if record.Country='UK' then return readOnly; end else begin if record.Country='D' then return readOnly; if record.Country='B' then return readWrite; return hidden; end
return ステートメントは、特定の条件を満たすレコードへのアクセスを指定します。
次の表に、有効な return ステートメントを示します。
return ステートメント | 説明 |
---|---|
return hidden; | レコードは非表示になっています (ユーザーにはアクセス権がありません)。 |
return readOnly; | レコードは、現在のユーザーに対してのみ読み取られます。 |
return readWrite; | レコードは、現在のユーザーが読み取って変更できます。 |
特定のレコードに適用される return ステートメントがない場合、値 hidden が想定されます。
レコードの権限は、現在のデータスペース、データセット、またはセッションによって異なります。
事前定義されたエイリアス dataspace は、現在のデータスペースに関する情報へのアクセスを提供します。
このエイリアスは、次のフィールドへのアクセスを提供します。
名前 | 型 | 説明 |
---|---|---|
name | 文字列 | データスペースの名前。データスペースの名前空間とスナップショットの名前空間は独立しているため、返される文字列は名前空間の 1 つのコンテキストにおける識別子にすぎません。グローバルデータスペースまたはスナップショット識別子には、フィールド id を使用します。 |
id | 文字列 | データスペースまたはスナップショットの永続的な識別子。name と比較すると、この識別子は、この ID がデータスペース用かスナップショット用かをさらに指定します。 |
isSnapshot | boolean | データスペースがスナップショットの場合は true であり、データスペースがブランチの場合は false です。 |
例
if dataspace.name = 'branch-R' then return readOnly;
事前定義されたエイリアス dataset は、現在のデータセットに関する情報へのアクセスを提供します。
このエイリアスには次のフィールドがあります。
名前 | 型 | 説明 |
---|---|---|
name | 文字列 | データセットの名前 |
例
if dataset.name = 'TEST' then return readWrite;
事前定義されたエイリアス session は、現在のユーザーセッションに関する情報へのアクセスを提供します。
このエイリアスには次のフィールドがあります。
名前 | 型 | 説明 |
---|---|---|
userId | 文字列 | 現在のユーザーの ID |
userEmail | 文字列 | 現在のユーザーのメール |
trackingInfo | 文字列 | 現在のセッションの追跡情報。 |
現在のユーザーのロールを確認するには、ロールを参照してください。
例
if session.userId = 'jdoe' then return readWrite;
次の表では、isMember() 関数について説明します。
構文 | 説明 |
---|---|
isMember('rolea', 'roleb'…) | 現在のユーザーが指定されたロールの少なくとも 1 つを持っている場合、true を返します。 ビルトインロール administrator、readOnly、everyone は、引用符なしで指定する必要があります。 カスタムロールは文字列リテラルとして指定されます。存在しないロールを指定してもエラーにはなりません (メンバーのいないロールと見なされます)。 注意 ロール administrator と 'administrator' は 2 つの異なるロールにすることができます。これは、isMember(administrator) が is_member('administrator') と同じ結果を返さない可能性があることを意味します。同じルールが他のビルトインロールにも適用されます。 |
例
if isMember('SALES', 'SUPPORT') then return readWrite; // Role administrator and not surrounded by quotes: if isMember(administrator, 'SUPPORT') then return readOnly;
次の表では、セッション関数について説明します。
構文 | 説明 |
---|---|
getSessionInputParameter(parameterKey, lookupInParentSessions) | 指定された parameterKey に対応するセッション入力パラメーターを返します。 ワークフローインタラクションのコンテキストでは、関数はワークフロータスクの入力パラメーターでパラメーターを検索します。 lookupInParentSessions が true の場合、関数は親セッションでパラメーターを検索します。 それ以外の場合は、現在のセッションでのみパラメーターを検索します。 |
isInWorkflowInteraction(lookupInParentSessions) | 現在のセッションがワークフローインタラクションコンテキスト内にある場合は、true を返します。 lookupInParentSessions が true の場合、親セッションがワークフローインタラクションコンテキスト内にある場合、この関数は true を返します。 それ以外の場合、関数は現在のセッションのコンテキストのみを評価します。 |
例
// Give read write access if the scripted rule is called in a workflow interaction context and the 'instance' input parameter for the workflow task is 'Library'. if isInWorkflowInteraction(true) and getSessionInputParameter('instance', true) = 'Library' then return readWrite;
文字列照合関数は、次の 3 つのパラメーターを取ります。
文字列として評価される stringExpression。
文字列リテラルの必要がある pattern。
照合で大文字と小文字が区別されるかどうかを示すオプションのブールリテラル isCaseSensitive。省略した場合、照合では大文字と小文字が区別されないと見なされます。
構文 | 説明 |
---|---|
matches(stringExpression, pattern, isCaseSensitive) | stringExpression が Java 正規表現 pattern と一致する場合、true を返します。 |
startWith(stringExpression, pattern, isCaseSensitive) | stringExpression が文字列 pattern で始まる場合、true を返します。 |
extendsWith(stringExpression, pattern, isCaseSensitive) | stringExpression が文字列 pattern で終わる場合、true を返します。 |
contains(stringExpression, pattern, isCaseSensitive) | stringExpression に文字列 pattern が含まれている場合、true を返します。 |
containsWholeWord(stringExpression, pattern, isCaseSensitive) | stringExpression に単語全体 pattern が含まれている場合、true を返します。 |
例
// Give read write access if first name starts with 'a', 'b' or 'c' (case-sensitive). if matches(record.FirstName, '[a-c].*', true) then return readWrite; // Give read only access if first name starts with 'Lé' (case-insensitive). if startsWith(record.FirstName, 'Lé') then return readOnly; // Give read only access if first name ends with 'my' (case-insensitive). if endsWith(record.FirstName, 'my') then return readOnly; // Give read only access if email contains with 'BeauMont@' (case-sensitive). if contains(record.Email, 'BeauMont@', true) then return readOnly; // Give read write access if last name contains the whole word 'Michel' (case-insensitive). if containsWholeWord(record.LastName, 'Michel', false) then return readWrite;
次の集計関数は、関連付けで使用できます。
構文 | 説明 |
---|---|
count(expression) | 式の行数を返します。 |
exists(expression) | 式が少なくとも 1 行と評価された場合、true を返します。 |
例
// Give read write access if managed users count is at least 2. if count(record.ManagedUsers[]) >= 2 then return readWrite; // Give read only access if count of managed users that are not in Paris is less than 4. if count(record.ManagedUsers:m1[m1.OfficeAddress.City<>'Paris']) < 4 then return readOnly; // Give read write access if managed users count is at least 1. if exists(record.ManagedUsers[]) then return readWrite; // Give read write access if count of managed users that are not in Briton is at least 1. if exists(record.ManagedUsers:u1[u1.OfficeAddress.City<>'Briton']) then return readWrite;
次の表に、日付と時刻の関数を示します。
構文 | 説明 |
---|---|
datetimeNow() | 現在の日付と時刻を返します。 |
dateNow() | 現在の日付を返します。 |
timeNow() | 現在の時刻を返します。 |
例
// Give read write access if the last possible update date hasn't expired yet. if record.LastPossibleUpdateDate >= dateNow() then return readWrite; else return readOnly;
次の表は、ブール値を返すビルトイン関数についての説明です。
構文 | 説明 |
---|---|
isNull(value) | 値が null の場合は true を返します。値は、任意のタイプの式にすることができます。 |
例
// Give read write access if no supervisor. if isNull(record.supervisor) then return readWrite;