Sentry in 8.0 Windows client generally and COM plugin examples

Hi forum

 

i'm working on creating a sentry plugin for a customer running 8.0 SR4

However, i experience that the netserver modules doesn't seem to do their job yet, with regard to read only permissions etc. Then i came across a thread mentioning that i would still need to use the old COM sentry interface in order to make it work on the windows clients.

I then looked it up in the documentation

https://community.superoffice.com/documentation/SDK/SO.COM.IDatabase/html/exampleSentry.htm

This article mentions a zip file - am i blind, or is there no link to that zip file? 

Also am i wasting time, with looking in this direction in the first place since the customer is running 8.0?

 

Here's what i'm trying to do:

1. Check appointment if a userdefined field is set to yes or no 

2. Check if current associate and the appointments owner is member of a specific group via the usergrouplink table 

3. If field is yes, and the current associate is not member of the specific group, provide read only access on the table, and no access on the text field

The above has been implemented in a netserver sentry plugin, and does actually hide the text field with EFieldRight.none.

But When i try to put read only on tables with ETableRight.R it simply does not respect it in the windows client (in the web client the delete button is disabled in the archive view, but you can still edit the appointment and delete it from the dialog.)

 

public void ModifyTableRights(TableRights rights)
{

string yes = "8";
string no = "9";


using (_sentry.Lookups.BeginIgnoreSentryCheck())
{
var udappSmall = TablesInfo.GetUDAppntSmallTableInfo();

if (_sentry.IsTableCovered(udappSmall))
{
var isConfidential = GetFieldValue(udappSmall.Long06);
var appid = GetFieldValue(QueryInfo.MainTable.AppointmentId);

if (isConfidential != null && appid != null) {
if (isConfidential.ToString() == yes) {

foreach (TableInfo ti in rights.Keys.ToArray())
{

rights[ti] = RightsFactory.Get(ETableRight.R, "make all read only since 4");


}

}
}

}


}

 

 

}

 

So hope you can provide me with the samples for the windows sentry plugin, or tell me what i need in ModifyTableRights in order to make the client respect it. I thought that i need to register sentry as active via a preference in SuperOffice like the beforementioned COM plugin, but i can't seem to find anything about that, so i suppose it's not necessary...

 

thanks in advance :)

 

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Hi Dennis, yes you need to implement both since some parts of the windows client use COM and others (mainly the archives) NetServer, like described here https://community.superoffice.com/documentation/SDK/SO.COM.IDatabase/html/SentryPluginsandNetServer.htm

Af: Carlo Pompen 7. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Thanks for clarifying that - hopefully i can get the examples soon too :)

Af: Dennis Mortensgaard 7. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

I think the samples used to be included with the old school expander SDK, the same help file is also there: https://community.superoffice.com/en/content/resources/superoffice-expander-sdk/SuperOffice-Expander-Toolkit-75/

The sentry samples haven't changed since 6 I believe, so you could try this 7.5 version.

Af: Carlo Pompen 7. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Hi Dennis,

Thanks Carlo! Yes, the examples are embedded in the documentation included in the SuperOffice Expander SDK installer. So is the COM Interop assembly for sentry.

There is some setup to get the com-sentry up and running, but the initial requirements can seem daunting at first. Here are a few getting started tips:

  1. Create a .NET Framework class library
  2. Use nuget to get the netserver assemblies
  3. Download and install the 8.0 Expander SDK to get the SOSentryPlugin.Interop.dll assembly and SentryPluginInterface.tlb file. Then reference the interop assembly.
  4. Mark your project as COM-Visible
  5. Generate a new GUID for each sentry and type that into the corresponding class attribute.
  6. Implement the interfaces according the guidance in the NetServer and Windows SDK.
  7. When installing on users machines, make sure the components are registered.

Creating an updated article on this and the document plugin are waaaay overdue. I am sorry about that.

Here is a rough skeleton of what your sentry would look like (without implementation):

using SuperOffice.CRM.Security;
using SuperOffice.Data.SQL;
using System;
using System.Runtime.InteropServices;
 
namespace SuperOffice.DevNet.Sentry
{
    [SentryPlugin("appointment", "MyCompany.AppointmentSentry")] // NetServer
    [SentryPluginQueryTableUpdater("appointment")]               // --
    [ProgId("MyCompany.AppointmentSentry")]                      // COM requirements
    [Guid("D9E7ACBE-0829-4375-9BF7-0EF0D4F468C1")]               // --
    [ComVisible(true)]                                           // --
public class AppointmentSentry : 
        ISentryPlugin, ISentryPluginQueryTableUpdater, // NetServer
        SOSentryPlugin.Interop.ISentryPlugin,
        SOSentryPlugin.Interop.ISentryPlugin2
    {
        // NetServer 
        #region ISentryPlugin
        public void Init(CRM.Security.Sentry sentry)
        {
            throw new NotImplementedException();
        }
 
        public void ModifyFieldRights(FieldRights rights)
        {
            throw new NotImplementedException();
        }
 
 
        public void ModifyTableRights(TableRights rights)
        {
            throw new NotImplementedException();
        } 
        #endregion
 
        #region ISentryPluginQueryTableUpdater
        public void ModifySelect(Select sql, TableInfo tableInfo)
        {
            throw new NotImplementedException();
        }
 
        #endregion
 
        // COM - Windows Client
 
        #region Interop.ISentryPlugin
        public void GetTableList(ref object[] TableNames)
        {
            throw new NotImplementedException();
        }
 
        public void GetProviderDetails(string TableName, ref bool SupportFieldLevelSecurity, ref bool NeedFullDataToWork)
        {
            throw new NotImplementedException();
        }
 
        public void GetRowSecurity(int AssocId, int GroupId, int RecordId, string TableName, ref object[] RecordData, ref bool o_IsReadOk, ref bool o_IsWriteOk, ref string o_ToolTip)
        {
            throw new NotImplementedException();
        }
 
        public void GetFieldSecurity(int AssocId, int GroupId, int RecordId, string TableName, ref object[] RecordData, ref int[] o_CanReadFields, ref int[] o_CanWriteFields, ref string o_ToolTip)
        {
            throw new NotImplementedException();
        }
        #endregion
 
        #region Interop.ISentryPlugin2
        public void Initialize(string adoConnectionString, string prefix)
        {
            throw new NotImplementedException();
        }
 
        public void GetTableRights(int AssocId, int GroupId, int RecordId, string TableName, ref object[] RecordData, ref bool o_CanInsertRow, ref bool o_CanReadRow, ref bool o_CanUpdateRow, ref bool o_CanDeleteRow, ref string o_ToolTip)
        {
            throw new NotImplementedException();
        }
 
        public void GetFieldRights(int AssocId, int GroupId, int RecordId, string TableName, ref object[] RecordData, ref object[] o_FieldRights)
        {
            throw new NotImplementedException();
        } 
        #endregion
    }
}

Hope this helps!

Af: Tony Yates 7. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Thanks Tony, I will try it out asap!

Have a nice weekend

Af: Dennis Mortensgaard 7. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

So, i've tried to implement the above into my sentry dll.

 

I'm getting an error during building though, first it tells me that SODatabase.dll is not registered for COM interop, and that i should run regasm.exe /tlb on it - when i do that however, it throws a lot of warnings at me, and i can still not build the dll.

 

The warnings are in danish, but mentions that there is not enough memory to complete the action, but my pc is only using 50% RAM.

i managed to get it compiled bu running /codebase instead, and then building the dll - after that i ran the vbs script for setting the preference, but now when i try to log in to WEB it fails, with the exception that it cannot find the sentry plugin, despite having ít referenced in dynamic load.

I can log into the windows client just fine, but it doesn't seem that my Netserver sentry plugin does anything anymore - it's like no data is fetched via the GetFieldValue function - it always gives Null now, after implementing the COM sentry dll.

 

My god i HATE COM interop registration -_-

 

I'm unsure what details i can post here in order for you to help me further, guess i just need to experiment around with it i guess, previous experiences with COM plugins have always been trial and error for me. A reference in the config file, is much easier to work with...

But please let me know if i can supply any information, that could identify my problem

Af: Dennis Mortensgaard 8. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Hi Dennis, make sure your plugin is build as x86 (32bit) and make sure it targets the same .net framework as the netserver version you're using, that is pretty important.

Af: Carlo Pompen 10. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Hi all - i ended up getting it to work after i split the code into two dll's: one for the netserver stuff, and one for the COM plugin :)

 

So far so good - so now i only have one last question:

 

How do i know what data is inside ref object[] RecordData?

 

I get 45 members, that only has a numbered index, but i cannot seem to find any documentation on how i am supposed to know what is inside it?

 

I have tried casting it to AppointmentTableInfo, but that does not seem to be valid.

I guess im not supposed to load an appointment manually during each lookup in order to get recorddata in a readable format?

 

Thanks in advance.

Af: Dennis Mortensgaard 10. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Anyone? :)

Af: Dennis Mortensgaard 11. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Hi,

I’m guessing no one knows what you are referring to. RecordData isn’t used in sentries, normally just TableInfo, FieldInfo TableRights and FieldRights.

I believe there is a fair explanation and examples here:

https://community.superoffice.com/documentation/SDK/SO.NetServer.Data.Access/html/Examples-Plugins-PluginSentry-PluginSentry.htm

: Sentry Plugins Overview

Af: Tony Yates 12. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Hi again Tony

The netserver part is pretty straight forward - it's the RecordData element in the com plugin.

The question is - how do you know that RecordData(1) equals the contacts name?

This is the example in the documentation:

Private Sub SOSentryPlugin2\_GetTableRights(ByVal AssocId As Long, ByVal GroupId As Long, ByVal RecordId As Long, ByVal TableName As String, RecordData() As Variant, o\_CanInsertRow As Boolean, o\_CanReadRow As Boolean, o\_CanUpdateRow As Boolean, o\_CanDeleteRow As Boolean, o\_ToolTip As String)
    If TableName = "contact" And RecordId > 0 Then
        Dim name As String
        name = LCase(RecordData(1))
        log " checking name=" & name
       
        ' case-insensitive name check
        If InStr(1, name, "superoffice", vbTextCompare) > 0 Then
            log "  found superoffice - mark as read-only"
            o\_CanReadRow = True
            o\_CanUpdateRow = False
            o\_ToolTip = "Name contains magic word 'superoffice'"
        End If
       
    End If
End Sub




Af: Dennis Mortensgaard 12. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

I suspect it follows the db table layout. contact.contact_id would be index 0, name 1, kananame 2 etc..
Worth a try..

/conrad

Af: Conrad Weyns 12. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Ah yes, sorry about that. :-S I believe Conrad is correct.

Best regards.

Af: Tony Yates 12. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

I can confirm that it is equal to the table layout - thank you very much for the clarification.

I'm almost through now - thanks for your incredible help on this thread, i really appreciate it! 

The last thing (i hope) that gives me trouble is when i try to hide the text from the user when the appointment dialogue is opened:

I have tried setting these fieldrights in GetFieldRights:

o_FieldRights[0] = "appointment.Text=0,Text is hidden"; //does not do anything
o_FieldRights[1] = "Text.text=0,Text is hidden"; //does not do anything
o_FieldRights[2] = "appointment.Text.text=0,Text is hidden"; //does not do anything

So how can i hide the text from being shown in the appointment dialogue? I managed to get it hidden in the archive via the netserver plugin, but how do i do it here?

Thanks again so much - i think i will make a blog tutorial about this when i'm done for everyone else experiencing the same issues as me.

 

 

Af: Dennis Mortensgaard 12. sep 2018

RE: Sentry in 8.0 Windows client generally and COM plugin examples

Looking at the code, the form is: "table.field = value,tooltip"
Since this refers to the main entity only, I think you need "appointment.text_id=0"

SInce you are hiding, the tooltip will do you no good as the Win gui cannot have a tooltip on a hidden control.

Internaly, the table.field name will be converted to a FieldId and this must then be used in our GUI control to ask for AccessRights.
For the appointment dialog's Description view, this is kAppntText_id.

 

/conrad

Af: Conrad Weyns 12. sep 2018