Page 1 of 1

Open Dental - OmniDefend: Hook Request

Posted: Fri Mar 08, 2019 12:08 pm
by SoftexDEV
Hi OpenDental,

Would like to request a bunch of hooks to be added to Open Dental to make it work with our biometric & multi-factor authentication software OmniDefend.

1. Hook in function "FormLogOn_Load" at line 61
File - "\opendental\forms\FormLogOn.cs"
Function - "private void FormLogOn_Load(object sender,EventArgs e)"

Code: Select all

			FillListBox();
			this.Focus();//Attempted fix, customers had issue with UI not defaulting focus to this form on startup.
			textSelectOnLoad.Select();//Give focus to appropriate text box.
			Plugins.HookAddCode(this, "FormLogOn.Load_end");
        }
2. Hook in function "FillGrid" at line 558
File - "\opendental\forms\FormProgramLinkEdit.cs"
Function - "private void FillGrid()"

Code: Select all

		private void FillGrid(){
			List<ProgramProperty> ProgramPropertiesForProgram=ProgramProperties.GetForProgram(ProgramCur.ProgramNum);
			Plugins.HookAddCode(this, "FormProgramLinkEdit_FillGrid_GetProgramProperties", ProgramPropertiesForProgram, ProgramCur);
			gridMain.BeginUpdate();
			gridMain.Columns.Clear();
3. Hook in function "SaveRx" at line 883
File - "\opendental\forms\FormRxEdit.cs"
Function - "private bool SaveRx()"

Code: Select all

            RxPatCur.ClinicNum=(comboClinic.SelectedClinicNum==-1 ? RxPatCur.ClinicNum : comboClinic.SelectedClinicNum);//If no selection, don't change the ClinicNum
            
            // hook for additional authorization before prescription is saved
            bool[] authorized = new bool[1] { false };
            if (Plugins.HookMethod(this, "FormRxEdit.SaveRx_Authorize", authorized, prov, RxPatCur, _rxPatOld))
            {
                if (!authorized[0])
                    return false;
            }

            //pharmacy is set when using pick button.
            if (IsNew){
4. Hook in function "Tool_eRx_Click" at line 4793
File - "\opendental\main modules\ContrChart.cs"
Function - "private void Tool_eRx_Click(bool isShowRefillsAndErrors=false)"

Code: Select all

                        DoseSpot.ValidateProvider(prov,clinicNum);

                        // hook for additional authorization before prescription is saved
                        bool[] authorized = new bool[1] { false };
                        if (Plugins.HookMethod(this, "ContraChart.Tool_eRx_Click_Authorize", authorized, prov))
                        {
                            if (!authorized[0])
                                isDoseSpotAccessAllowed = false;
                        }

                        string provNpi =Regex.Replace(prov.NationalProvID,"[^0-9]*","");//NPI with all non-numeric characters removed.
5. Hook in function "Tool_eRx_Click" at line 4888
File - "\opendental\main modules\ContrChart.cs"
Function - "private void Tool_eRx_Click(bool isShowRefillsAndErrors=false)"

Code: Select all

                Erx.ValidateProv(prov);

                // hook for additional authorization before prescription is saved
                bool[] authorized = new bool[1] { false };
                if (Plugins.HookMethod(this, "ContraChart.Tool_eRx_Click_Authorize", authorized, prov))
                {
                    if (!authorized[0])
                        throw new Exception(Lans.g("Erx", "Provider is not authenticated"));
                }

                Erx.ValidatePat(PatCur);
6. Hook in function "butClockIn_Click" at line 1370
File - "\opendental\main modules\ContrStaff.cs"
Function - "private void butClockIn_Click(object sender,System.EventArgs e)"

Code: Select all

			try{
                bool[] authorized = new bool[1] { false };
                if (Plugins.HookMethod(this, "ContrStaff.butClockIn_Click_ClockIn", authorized, EmployeeCur))
                {
                    if (!authorized[0])
                        throw new Exception(Lans.g(this, "You need to authenticate to clock-in"));
                }
                ClockEvents.ClockIn(EmployeeCur.EmployeeNum);
			}
7. Hook in function "butClockOut_Click" at line 1404
File - "\opendental\main modules\ContrStaff.cs"
Function - "private void butClockOut_Click(object sender,System.EventArgs e)"

Code: Select all

			try{
                bool[] authorized = new bool[1] { false };
                if (Plugins.HookMethod(this, "ContrStaff.butClockOut_Click_ClockOut", authorized, EmployeeCur, _listShownTimeClockStatuses[listStatus.SelectedIndex]))
                {
                    if (!authorized[0])
                        throw new Exception(Lans.g(this, "You need to authenticate to clock-out"));
                }

                ClockEvents.ClockOut(EmployeeCur.EmployeeNum,_listShownTimeClockStatuses[listStatus.SelectedIndex]);
			}
8. Hook in function "FinishLogOff" at line 8766
File - "\OpenDental\Forms\FormOpenDental.cs"
Function - "private void FinishLogOff(bool isForced)"

Code: Select all

		private void FinishLogOff(bool isForced) {
			if(this.InvokeRequired) {
				this.Invoke(() => { FinishLogOff(isForced); });
				return;
			}

			Plugins.HookAddCode(this, "FormOpenDental.LogOffNow_start", isForced);  // perform logoff 

			LastModule = myOutlookBar.SelectedIndex;
			myOutlookBar.SelectedIndex=-1;
Thank you. Let us know if there are any questions.

Re: Open Dental - OmniDefend: Hook Request

Posted: Mon Mar 11, 2019 8:54 am
by cmcgehee
Softex DEV team,

I'm excited to hear that someone is doing biometric authentication. That's something I've been wanting to see happen for a while. We will get these hooks added to the program.

I would like to make a suggestion for changing one hook. For hook #5 in ContrChart.Tool_eRx_Click I would recommend throwing an ODException so that a message box will show. Throwing a normal Exception will cause the program to terminate.

Re: Open Dental - OmniDefend: Hook Request

Posted: Mon Mar 11, 2019 2:20 pm
by SoftexDEV
Thank you for the suggestion.
Updated code for #5 below.
5. Hook in function "Tool_eRx_Click" at line 4888
File - "\opendental\main modules\ContrChart.cs"
Function - "private void Tool_eRx_Click(bool isShowRefillsAndErrors=false)"

Code: Select all

                Erx.ValidateProv(prov);

                // hook for additional authorization before prescription is saved
                bool[] authorized = new bool[1] { false };
                if (Plugins.HookMethod(this, "ContraChart.Tool_eRx_Click_Authorize", authorized, prov))
                {
                    if (!authorized[0])
                        throw new ODException(Lan.g(this, "Provider is not authenticated"));
                }

                Erx.ValidatePat(PatCur);

Re: Open Dental - OmniDefend: Hook Request

Posted: Wed Mar 13, 2019 2:46 pm
by cmcgehee
These hooks have been added to 18.4.30. I did change a couple of them slightly to match our patterns a little better.

Re: Open Dental - OmniDefend: Hook Request

Posted: Wed Mar 20, 2019 5:06 pm
by SoftexDEV
Hi,

It looks there is a change from 18.3 to 18.4 that will require us to modify one of the hooks. Mainly, in 18.3, you had a public member of the FormLogOn called IsSimpleSwitch which would allow us to determine if we needed to set the Security.CurUser or not in our plugin after the user authenticates with their fingerprint. So we would ask that you change the hook

Code: Select all

Plugins.HookAddCode(this,"FormLogOn.Load_end");
to

Code: Select all

Plugins.HookAddCode(this,"FormLogOn.Load_end", _isSimpleSwitch);
This way our plugin will know the value of the _isSimpleSwitch and can take action accordingly after a fingerprint authentication.

Also, we have one more request.

Currently the app.config of OpenDental has a reference to NewtonsoftJson

Code: Select all

      <dependentAssembly>
          <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
          <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
      </dependentAssembly>
We have one of the libraries that we use in our plugin that references Newtonsoft.Json version 10.0.0.0. This may be the case for other plugins also. So we would like to see the following change.

Code: Select all

      <dependentAssembly>
          <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
          <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="9.0.0.0"/>
      </dependentAssembly>
Of course, maybe it is best to change the oldVersion range to the latest version instead of 10.0.0.0, but I am not sure what that is off hand.

Re: Open Dental - OmniDefend: Hook Request

Posted: Thu Mar 21, 2019 7:58 am
by cmcgehee
I think we'll probably be able to make those changes.

Re: Open Dental - OmniDefend: Hook Request

Posted: Mon Mar 25, 2019 7:22 am
by SoftexDEV
Thanks, let us know when they are done so we can download the build and try it out.

Re: Open Dental - OmniDefend: Hook Request

Posted: Tue Mar 26, 2019 12:17 pm
by cmcgehee
We changed several app.config files to this:

Code: Select all

<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
    <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="9.0.0.0"/>
</dependentAssembly>
This should allow any third-party dll that you use that was compiled on a higher version of Netwonsoft.Json to use version 9. This shouldn't cause any problems as long as your third-party doesn't use any features that were introduced in version 10 or later. If they do, you would probably get a runtime-exception. When you distribute your dll(s), I don't think you will want to include a higher version of Netwonsoft because the main Open Dental program would break.

I also included your modification to FormLogOn.Load_end. These changes will be available in 19.1.9.

Re: Open Dental - OmniDefend: Hook Request

Posted: Thu Mar 28, 2019 10:21 am
by SoftexDEV
Is it possible to have this hook change put back into the 18.4 branch? Our customer is using 18.4

Re: Open Dental - OmniDefend: Hook Request

Posted: Thu Mar 28, 2019 6:01 pm
by cmcgehee
Our company policy is to only backport hook requests to the beta version, and I'm hesitant to make an exception here because the app.config change we made is more intrusive than a typical hook.