An access mask is used to grant access permissions on objects, set audit and keep history in relevant properties and methods. This mask is based on values of the MetabaseObjectPredefinedRights enumeration. If specific operations are available for an object, mask value is filled with values of one of the following enumerations:
AuditLogSpecificRights - specific operations available for access protocol.
CalculatedCubeSpecificRights - specific operations available for calculated cubes.
CubeLoaderSpecificRights - specific operations available for cube data loader.
CubeSpecificRights - specific operations available for various types of cubes.
CustomObjectSpecificRights - specific operations available for custom class objects.
DataBaseSpecificRights - specific operations available for the Database repository object.
DictionarySpecificRights - specific operations available for the MDM Dictionary and Composite MDM dictionary repository objects.
MDCalcSpecificRights - specific operations available for the Multidimensional Calculation on DB Server repository object.
ProblemSpecificRights - specific operations available for the Modeling Problem modeling container object.
ProcedureSpecificRights - specific operations available for the Procedure repository object.
ScenarioDimensionSpecificRights - specific operations available for the Modeling Scenario repository object.
ScheduledTaskSpecificRights - specific operations available for tasks created in scheduled tasks container.
SecuritySpecificRights - specific operations available for security policy.
TableSpecificRights - specific operations available for the following repository objects - Table, View, Log, External Table.
UpdateObjectSpecificRights - specific operations available for the Update repository object.
ValidationSpecificRights - specific operations available for the Validation Rule and Validation Group repository objects.
It is not difficult to create a mask value from values of specified enumerations while granting permissions, setting audit and history. It is necessary to use logical Or to make combinations.
Mask := MetabaseObjectPredefinedRights.Access Or MetabaseObjectPredefinedRights.Delete;
If there is a reverse situation when it is necessary to determine which operations are available by the given mask, it is necessary to write custom function to analyze mask value.
Consider the example of mask analysis returned by the GetEffectiveRights method. Mask value is a 4-byte binary number converted to decimal form. To analyze a mask, it is necessary to have a function that makes inverse conversion from decimal into binary form:
Function DecToBin(Value: Double): String;
Var
i, k: Integer;
Str, Str2: String;
Begin
// Take into account 32 bit of the mask, which presence makes the value negative
If Value < 0 Then
Str := "1";
Value := (Value - Integer.MinValue) As Double;
k := 29 - (Math.Trunc(Math.Log(Value, 2), 0) As Integer);
For i := 0 To k Do
Str := Str + "0";
End For;
End If;
While Value > 1 Do
k := (Value - (2 * Math.Quotient(Value, 2))) As Integer;
Value := Math.Trunc(Value / 2, 0);
Str := Str + k.ToString;
End While;
Str := Str + Value.ToString;
For i := 0 To Str.Length - 1 Do
Str2 := Str2 + Str.SubString(Str.Length - i - 1, 1);
End For;
Return Str2;
End Function DecToBin;
This function returns a binary number as a character string.
Suppose there is an object with the Obj_1 identifier in the repository. The TestUser user is created in the security manager of the platform.
Create a form and put a button on it. Create the OnClick event handler for a button and write the following code:
Sub Button1OnClick(Sender: Object; Args: IMouseEventArgs);
Var
MB: IMetabase;
MDesc: IMetabaseObjectDescriptor;
SecDesc: ISecurityDescriptor;
Subj: ISecuritySubject;
Rights: Integer;
BinRights: String;
Begin
MB := MetabaseClass.Active;
//Security subject
Subj := MB.Security.ResolveName("TestUser");
//Object on which effective permissions will be determined for security subject
MDesc := MB.ItemById("Obj_1");
SecDesc := MDesc.SecurityDescriptor;
//Get effective permissions in decimal form
Rights := SecDesc.GetEffectiveRights(Subj);
//Display effective permissions in binary form
BinRights := DecToBin(Rights);
End Sub Button1OnClick;
On clicking the button the Rights variable will contain values corresponding with effective user permissions on a specified object displayed in binary form. The BinRights variable will contain the same value displayed in binary form.
Suppose that only basic and additional operations are available for the Obj_1 object, and the method returned the following value:
Rights := 114440 and BinRights := 11011111100001000. Each mask bit corresponds with one of the operations. If bit value is 0, the operation for the user is undefined (operation value is not set or forbidden). If bit value is 1, operation is allowed for the user.
To compare operations and bits in binary mask, make inverse conversion of each bit particularly into decimal form. Conversion from decimal form into binary form means to raise a number 2 to the power that equals to bit number. Bit numeration starts with 0, at the same time binary number is considered from right to left.
In the specified enumerations each value according to any operation also equals certain power of number 2 (MetabaseObjectPredefinedRights.All = 1 = 2^0; MetabaseObjectPredefinedRights.Print = 16384 = 2^14, and so on.). That is why to check mask bits, raise number 2 to the power that equals to bit number and compare received value with values in enumerations.
To compare values with values of enumerations, write the following function:
Public Function CheckRight(Right: Double): String;
Begin
Select Case Right
//Basic permissions
Case MetabaseObjectPredefinedRights.All:
Return "All";
Case MetabaseObjectPredefinedRights.Read:
Return "Read";
Case MetabaseObjectPredefinedRights.Write:
Return "Write";
Case MetabaseObjectPredefinedRights.Access:
Return "Access";
Case MetabaseObjectPredefinedRights.Delete:
Return "Delete";
Case MetabaseObjectPredefinedRights.ReadDescr:
Return "ReadDescr";
Case MetabaseObjectPredefinedRights.WriteDescr:
Return "WriteDescr";
Case MetabaseObjectPredefinedRights.ReadPars:
Return "ReadPars";
Case MetabaseObjectPredefinedRights.WritePars:
Return "WritePars";
Case MetabaseObjectPredefinedRights.ReadBody:
Return "ReadBody";
Case MetabaseObjectPredefinedRights.WriteBody:
Return "WriteBody";
Case MetabaseObjectPredefinedRights.Create_:
Return "Create_";
//additional permissions
Case MetabaseObjectPredefinedRights.Print:
Return "Print";
Case MetabaseObjectPredefinedRights.ExportData:
Return "ExportData";
Case MetabaseObjectPredefinedRights.ImportData:
Return "ImportData";
Else
Return "Unknown rights"
End Select;
End Function CheckRight;
This function returns its name by operation value. If the passed value is absent among values used in enumerations, the function will return "Unknown rights".
Create an additional procedure to check all bits of a mask.
Sub CheckBits(BinRights: String);
Var
i: Integer;
TwoPower: Double;
c: Char;
Begin
//Check bits of binary mask
//Inverse cycle to view a string from right to left
For i := BinRights.Length To 1 Step - 1 Do
//As indexing in character string begins with 0 decrement current position by 1
//It is necessary for correct work of the String.Chars property
c := BinRights.Chars(i - 1);
//Bits numbering is from right to left. To get bit number, subtract
//the current position from general length.
//Get decimal value for corresponding bit by raising 2 to the power,
//that equals to bit number.
TwoPower := Math.Power(2, BinRights.Length - i);
//If the current bit value is 1, operation is available
//If the current bit value is 0, the operation is not determined or forbidden
If c = '1' Then
Debug.WriteLine("Available operation: " + CheckRight(TwoPower));
Else
Debug.WriteLine("Undefined/Forbidden operation: " + CheckRight(TwoPower));
End If;
End For;
End Sub CheckBits;
In this procedure, the mask is viewed from right to left. Information about available and not determined operations will be displayed in the development environment console.
It is necessary to add a procedure call in a button click handler:
//...
//Get effective permissions in decimal form
Rights := SecDesc.GetEffectiveRights(Subj);
//Display effective permissions in binary form
BinRights := DecToBin(Rights);
CheckBits(BinRights);
//...
For specified above mask values (Rights := 114440 and BinRights := 11011111100001000) the following values will be displayed in the development environment console:
Bit number: 0 Undefined/Forbidden operation: All
Bit number: 1 Undefined/Forbidden operation: Read
Bit number: 2 Undefined/Forbidden operation: Write
Bit number: 3 Available operation: Access
Bit number: 4 Undefined/Forbidden operation: Delete
Bit number: 5 Undefined/Forbidden operation: Unknown rights
Bit number: 6 Undefined/Forbidden operation: Unknown rights
Bit number: 7 Undefined/Forbidden operation: Unknown rights
Bit number: 8 Available operation: ReadDescr
Bit number: 9 Available operation: WriteDescr
Bit number: 10 Available operation: ReadPars
Bit number: 11 Available operation: WritePars
Bit number: 12 Available operation: ReadBody
Bit number: 13 Available operation: WriteBody
Bit number: 14 Undefined/Forbidden operation: Print
Bit number: 15 Available operation: ExportData
Bit number: 16 Available operation: ImportData
For 5-7 bits values are unknown because they are not used in enumerations to assign operation.
The CheckRight function can be easily improved to check specific operations depending on object class.
The above analyzed example is used to check all access mask bits. If it is required to check existence of permissions for certain operations, it can be done in an easier way. As mask is a binary number, the logical And can be used to check bits values. If the result does not equal to zero, the 1 value is set in a relevant bit, which mean availability of permissions on operation:
Sub UserProc;
Var
MB: IMetabase;
MDesc: IMetabaseObjectDescriptor;
SecDesc: ISecurityDescriptor;
Subj: ISecuritySubject;
Rights: Integer;
Begin
MB := MetabaseClass.Active;
//Security subject
Subj := MB.Security.ResolveName("TestUser");
//Object, on which effective permissions will be determined for security subject
MDesc := MB.ItemById("Obj_1");
SecDesc := MDesc.SecurityDescriptor;
//Get effective permissions in decimal form
Rights := SecDesc.GetEffectiveRights(Subj);
//Check availability of permissions to delete object
If (Rights And MetabaseObjectPredefinedRights.Delete) <> 0 Then
Debug.WriteLine("Delete allowed");
Else
Debug.WriteLine("Delete denied");
End If;
End Sub UserProc;
See also: