Refactor to api connections. Update Checker.

This commit is contained in:
Matthew Burke 2023-08-24 12:45:56 -04:00
parent 4a4bcc81e0
commit 87a73ff24b
14 changed files with 355 additions and 45 deletions

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<Config>
<ODhost>10.0.1.107</ODhost>
<ODuser>root</ODuser>
<ODpassword></ODpassword>
<pwuserid>testdoctor</pwuserid>
<pwpassword>testdoctor</pwpassword>
<pwpracticeid>210</pwpracticeid>
<pwapiid>12345678</pwapiid>
</Config>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Config>
<PWBaseURI>http://apipatientweb.azurewebsites.net/</PWBaseURI>
<PWUpdateURI>https://localhost:44354/api/PWAppVersion</PWUpdateURI>
</Config>

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Media; using System.Windows.Media;
/** /**
@ -17,16 +18,22 @@ namespace PWAPPv2
/// </summary> /// </summary>
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
static Source.APIConfig apiconfig = new Source.APIConfig(); static Source.APIConfig apiconfig;// = new Source.APIConfig();
static Source.Database.DatabaseConfig DataConfig; static Source.Database.DatabaseConfig DataConfig;
static Source.API.APIConnection apiConnection; static Source.API.APIConnection apiConnection;
Source.DataObjects.APICredentials apiCreds; Source.DataObjects.APICredentials apiCreds;
Source.API.PWApiConnection pwapiConnection;
Source.DataObjects.ComboBoxData TypeBox; Source.DataObjects.ComboBoxData TypeBox;
Source.DataObjects.ComboBoxData ToBox; Source.DataObjects.ComboBoxData ToBox;
Source.DataObjects.ComboBoxData FromBox; Source.DataObjects.ComboBoxData FromBox;
Source.Config.Configuration practiceConfig;
Source.Config.Configuration universalConfig;
string[] args; string[] args;
Source.Patient patient; Source.Patient patient;
@ -43,18 +50,49 @@ namespace PWAPPv2
} }
catch (Exception) catch (Exception)
{ } { }
try
{
practiceConfig = new Source.Config.Configuration(".\\Config\\PracticeConfig.xml");
universalConfig = new Source.Config.Configuration(".\\Config\\UniversalConfig.xml");
}
catch
(Exception)
{
System.Windows.MessageBox.Show("An error has occured in the configurations files.");
}
pwapiConnection = new Source.API.PWApiConnection(practiceConfig, universalConfig);
try
{
if(pwapiConnection.CheckForUpdate() == true)
{
string message = "An update is available! Would you like to install it?";
string title = "Update available!";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result = System.Windows.Forms.MessageBox.Show(message, title, buttons);
if(result == System.Windows.Forms.DialogResult.Yes)
{
System.Windows.MessageBox.Show("HAHA NO UPDATE FOR YOU!");
}
}
}
catch (Exception)
{
System.Windows.MessageBox.Show("An error has occured while checking for updates");
}
try try
{ {
images = new List<Source.DataObjects.PWImage>(); images = new List<Source.DataObjects.PWImage>();
apiconfig.LoadConfig(ConfigPath);
DataConfig = new Source.Database.DatabaseConfig(ConfigPath);
Source.Database.DatabaseConnection dbcon = new Source.Database.DatabaseConnection(DataConfig);
Source.Database.DatabaseConnection dbcon = new Source.Database.DatabaseConnection(practiceConfig);
apiconfig = new Source.APIConfig(practiceConfig, universalConfig);
apiCreds = new Source.DataObjects.APICredentials(apiconfig); apiCreds = new Source.DataObjects.APICredentials(apiconfig);
apiConnection = new Source.API.APIConnection(universalConfig.Get("PWBaseURI"), apiCreds);
apiConnection = new Source.API.APIConnection("http://apipatientweb.azurewebsites.net/",
apiCreds);
InitializeComponent(); InitializeComponent();
@ -72,7 +110,7 @@ namespace PWAPPv2
} }
catch(Exception e) catch(Exception e)
{ {
MessageBox.Show(e.Message); System.Windows.MessageBox.Show(e.Message);
} }
} }
@ -176,11 +214,11 @@ namespace PWAPPv2
string json = att.ToJsonString(); string json = att.ToJsonString();
apiConnection.SendPostRequestAsync("api/PWAttachment", json); apiConnection.SendPostRequestAsync("api/PWAttachment", json);
} }
MessageBox.Show("Referral added successfully!"); System.Windows.MessageBox.Show("Referral added successfully!");
} }
else else
{ {
MessageBox.Show(result); System.Windows.MessageBox.Show(result);
} }
this.Close(); this.Close();
} }
@ -193,12 +231,12 @@ namespace PWAPPv2
//AddImage Button //AddImage Button
private void Button_Click_2(object sender, RoutedEventArgs e) private void Button_Click_2(object sender, RoutedEventArgs e)
{ {
OpenFileDialog openFileDialog = new OpenFileDialog(); System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
openFileDialog.Multiselect = true; openFileDialog.Multiselect = true;
openFileDialog.Filter = "Image files (*.jpg,*.jpeg)|*.jpg;*.jpeg"; openFileDialog.Filter = "Image files (*.jpg,*.jpeg)|*.jpg;*.jpeg";
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
if (openFileDialog.ShowDialog() == true) if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{ {
foreach (string filename in openFileDialog.FileNames) foreach (string filename in openFileDialog.FileNames)
{ {
@ -252,7 +290,7 @@ namespace PWAPPv2
{ {
Grid imageGrid = new Grid(); Grid imageGrid = new Grid();
imageGrid.Width = 477; imageGrid.Width = 477;
imageGrid.HorizontalAlignment = HorizontalAlignment.Left; imageGrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
imageGrid.VerticalAlignment = VerticalAlignment.Top; imageGrid.VerticalAlignment = VerticalAlignment.Top;
imageGrid.ShowGridLines = true; imageGrid.ShowGridLines = true;

View File

@ -213,6 +213,8 @@
<Compile Include="Source\API\APIConfig.cs" /> <Compile Include="Source\API\APIConfig.cs" />
<Compile Include="Source\API\APIConnection.cs" /> <Compile Include="Source\API\APIConnection.cs" />
<Compile Include="Source\API\APIRequestBuilder.cs" /> <Compile Include="Source\API\APIRequestBuilder.cs" />
<Compile Include="Source\API\PWApiConnection.cs" />
<Compile Include="Source\Config\Configuration.cs" />
<Compile Include="Source\Database\DatabaseConfig.cs" /> <Compile Include="Source\Database\DatabaseConfig.cs" />
<Compile Include="Source\Database\DatabaseConnection.cs" /> <Compile Include="Source\Database\DatabaseConnection.cs" />
<Compile Include="Source\DataObjects\APICredentials.cs" /> <Compile Include="Source\DataObjects\APICredentials.cs" />

View File

@ -1,4 +1,5 @@
using System; using PWAPPv2.Source.Config;
using System;
using System.Xml; using System.Xml;
namespace PWAPPv2.Source namespace PWAPPv2.Source
@ -10,6 +11,25 @@ namespace PWAPPv2.Source
public string PWPracticeID; public string PWPracticeID;
public string PWApiID; public string PWApiID;
public string PWBaseURI;
public string PWUpdateURI;
public string PWAppVersion;
public APIConfig() { }
public APIConfig(Config.Configuration practiceConfig, Config.Configuration universalConfig)
{
PWUserID = practiceConfig.Get("pwuserid");
PWPassword = practiceConfig.Get("pwpassword");
PWPracticeID = practiceConfig.Get("pwpracticeid");
PWApiID = practiceConfig.Get("pwapiid");
PWBaseURI = universalConfig.Get("PWBaseURI");
PWUpdateURI = universalConfig.Get("PWUpdateURI");
PWAppVersion = universalConfig.Get("PWAppVersion");
}
public void LoadConfig(string path) public void LoadConfig(string path)
{ {
XmlDocument cfgDoc = new XmlDocument(); XmlDocument cfgDoc = new XmlDocument();

View File

@ -1,4 +1,6 @@
using System; using Microsoft.Identity.Client.Platforms.Features.DesktopOs.Kerberos;
using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
@ -13,34 +15,28 @@ namespace PWAPPv2.Source.API
public DataObjects.APICredentials Credentials; public DataObjects.APICredentials Credentials;
private static bool ResponseReady = false;
private static string Response = ""; HttpClient Client;
public APIConnection(string baseUrl, DataObjects.APICredentials credentials) public APIConnection(string baseUrl, DataObjects.APICredentials credentials)
{ {
Credentials = credentials; Credentials = credentials;
BaseURL = baseUrl; BaseURL = baseUrl;
Client = new HttpClient();
Client.BaseAddress = new Uri(BaseURL);
Client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
} }
public string GetResponse()
{
while (!ResponseReady) ;
return Response;
}
/// <summary>
/// Dont use. Doesn't work, sillyhead.
/// </summary>
/// <param name="Call"></param>
public static async void APIGet(string Call) public static async void APIGet(string Call)
{ {
//WebRequest request = WebRequest.Create(BaseURL + Call);
//request.Method = "GET";
//request.ContentType = "application/json; charset=utf-8";
//var response = (HttpWebResponse)request.GetResponse();
//string text;
//using (var sr = new StreamReader(response.GetResponseStream()))
//{
// text = sr.ReadToEnd();
//}
//return text;
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {
client.BaseAddress = new Uri(BaseURL); client.BaseAddress = new Uri(BaseURL);
@ -52,16 +48,16 @@ namespace PWAPPv2.Source.API
} }
} }
/// <summary>
/// Send a post requst without data. Essentially an advanced get since I was a retard when I wrote the original API.
/// </summary>
/// <param name="apiUri"></param>
/// <returns></returns>
public string SendPostRequestAsync(string apiUri) public string SendPostRequestAsync(string apiUri)
{ {
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(BaseURL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
StringContent contetnt = new StringContent(Credentials.ToJsonString(), Encoding.UTF8, "application/json"); StringContent contetnt = new StringContent(Credentials.ToJsonString(), Encoding.UTF8, "application/json");
var response = client.PostAsync(apiUri, contetnt).Result; var response = Client.PostAsync(apiUri, contetnt).Result;
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -69,16 +65,18 @@ namespace PWAPPv2.Source.API
} }
return ""; return "";
} }
/// <summary>
/// Send a post request with data
/// </summary>
/// <param name="apiUri"></param>
/// <param name="PostData"></param>
/// <returns></returns>
public string SendPostRequestAsync(string apiUri, string PostData) public string SendPostRequestAsync(string apiUri, string PostData)
{ {
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(BaseURL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
StringContent contetnt = new StringContent(PostData, Encoding.UTF8, "application/json"); StringContent contetnt = new StringContent(PostData, Encoding.UTF8, "application/json");
var response = client.PostAsync(apiUri, contetnt).Result; var response = Client.PostAsync(apiUri, contetnt).Result;
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -87,5 +85,46 @@ namespace PWAPPv2.Source.API
return ""; return "";
} }
/// <summary>
/// Send a post request with the API credengials in the header of the request.
/// </summary>
/// <param name="apiUri"></param>
/// <param name="PostData"></param>
/// <returns></returns>
/// <exception cref="RequestFailedExcpetion"></exception>
public string SendPostWithCredsInHeader(string apiUri, string PostData)
{
Client.DefaultRequestHeaders.Add("UserID", Credentials.UserID);
Client.DefaultRequestHeaders.Add("Password", Credentials.Password);
Client.DefaultRequestHeaders.Add("PracticeID", Credentials.PracticeId);
Client.DefaultRequestHeaders.Add("ApiID", Credentials.APIid);
StringContent content = new StringContent(PostData, Encoding.UTF8, "application/json");
var response = Client.PostAsync(apiUri, content).Result;
Client.DefaultRequestHeaders.Remove("UserID");
Client.DefaultRequestHeaders.Remove("Password");
Client.DefaultRequestHeaders.Remove("PraticeID");
Client.DefaultRequestHeaders.Remove("ApiID");
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsStringAsync().Result;
}
throw new RequestFailedExcpetion(response.StatusCode.ToString());
}
}
public class RequestFailedExcpetion : Exception
{
public string RequestError;
public RequestFailedExcpetion(string errorCode)
{
RequestError = "Server responded with error code: " + errorCode;
}
} }
} }

View File

@ -0,0 +1,50 @@
using PWAPPv2.Source.DataObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PWAPPv2.Source.API
{
public class PWApiConnection
{
private APIConnection BaseConnection;
private APIConnection UpdateConnection;
private APICredentials Credentials;
private string AppVersion;
public PWApiConnection(Source.Config.Configuration practiceConfig, Source.Config.Configuration universalConfig)
{
Credentials = new APICredentials(practiceConfig);
BaseConnection = new APIConnection(universalConfig.Get("PWBaseURI"), Credentials);
UpdateConnection = new APIConnection(universalConfig.Get("PWUpdateURI"), Credentials);
AppVersion = universalConfig.Get("PWAppVersion");
}
public string PostToApi(string uri, string data)
{
return BaseConnection.SendPostRequestAsync(uri, data);
}
public string GetFromApi(string uri)
{
return BaseConnection.SendPostRequestAsync(uri);
}
public bool CheckForUpdate()
{
string currentVersion = UpdateConnection.SendPostWithCredsInHeader("", "");
currentVersion = currentVersion.Replace("\"", "");
if(currentVersion != AppVersion)
{
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.IO;
namespace PWAPPv2.Source.Config
{
public class Configuration
{
private Dictionary<string, string> values;
public Configuration(string file)
{
values = new Dictionary<string, string>();
if(!File.Exists(file))
{
throw new ConfigFileNotFoundException();
}
string f = File.ReadAllText(file);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(f);
XmlNodeList xmlNodeList = xmlDoc.DocumentElement.ChildNodes;
foreach (XmlNode xmlNode in xmlNodeList)
{
values.Add(xmlNode.Name, xmlNode.InnerText);
}
}
public string Get(string key)
{
try
{
return values[key];
}
catch
{
throw new ConfigValueNotFoundException();
}
}
}
public class ConfigFileNotFoundException : Exception { }
public class ConfigValueNotFoundException: Exception { }
}

View File

@ -20,6 +20,14 @@
APIid = config.PWApiID; APIid = config.PWApiID;
} }
public APICredentials(Source.Config.Configuration practiceConfig)
{
UserID = practiceConfig.Get("pwuserid");
Password = practiceConfig.Get("pwpassword");
PracticeId = practiceConfig.Get("pwpracticeid");
APIid = practiceConfig.Get("pwapiid");
}
public string BuildJsonBodyContents() public string BuildJsonBodyContents()
{ {
return "'UserID':'" + UserID + "'," + return "'UserID':'" + UserID + "'," +

View File

@ -4,6 +4,9 @@ using System.Collections.Generic;
namespace PWAPPv2.Source.Database namespace PWAPPv2.Source.Database
{ {
/// <summary>
/// Class <c>DatabaseConnection</c> creates and maintains a connection to and OpenDental MySqlDatabase.
/// </summary>
class DatabaseConnection class DatabaseConnection
{ {
@ -18,6 +21,12 @@ namespace PWAPPv2.Source.Database
Connection = new MySqlConnection(SqlString); Connection = new MySqlConnection(SqlString);
} }
public DatabaseConnection(Config.Configuration config)
{
SqlString = "server=" + config.Get("ODhost") + ";Uid=" + config.Get("ODuser") + ";database=" + config.Get("ODdatabase") + ";Pwd=" + config.Get("ODpassword");
Connection = new MySqlConnection(SqlString);
}
public void Connect() public void Connect()
{ {
try try

21
UnitTests/ConfigTest.cs Normal file
View File

@ -0,0 +1,21 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using PWAPPv2.Source;
namespace UnitTests
{
[TestClass]
public class ConfigTest
{
[TestMethod]
public void TestGetPracticeConfigs()
{
PWAPPv2.Source.Config.Configuration configuration = new PWAPPv2.Source.Config.Configuration(".\\Config\\PracticeConfig.xml");
Assert.IsNotNull(configuration);
string apiKey = configuration.Get("pwapiid");
Assert.IsNotNull(apiKey);
}
}
}

View File

@ -0,0 +1,22 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace UnitTests
{
[TestClass]
public class PWConnectionTest
{
[TestMethod]
public void TestCheckUpdate()
{
PWAPPv2.Source.Config.Configuration practiceConfig = new PWAPPv2.Source.Config.Configuration(".\\Config\\PracticeConfig.xml");
PWAPPv2.Source.Config.Configuration universalConfig = new PWAPPv2.Source.Config.Configuration(".\\Config\\UniversalConfig.xml");
PWAPPv2.Source.API.PWApiConnection pwApiConnection = new PWAPPv2.Source.API.PWApiConnection(practiceConfig, universalConfig);
Assert.IsNotNull(pwApiConnection);
Assert.IsFalse(pwApiConnection.CheckForUpdate());
}
}
}

View File

@ -25,5 +25,35 @@ namespace UnitTests
Assert.AreEqual("\"1|Endo|2|Implant|3|Oral Surgery|4|Ortho|5|Pedo|6|Perio|7|Restore|8|Other \\n\"", res); Assert.AreEqual("\"1|Endo|2|Implant|3|Oral Surgery|4|Ortho|5|Pedo|6|Perio|7|Restore|8|Other \\n\"", res);
} }
[TestMethod]
public void TestV2Get()
{
APICredentials creds = new APICredentials();
creds.UserID = "testdoctor";
creds.Password = "testdoctor";
creds.PracticeId = "210";
creds.APIid = "12345678";
APIConnection conn = new APIConnection("https://localhost:44354/", creds);
string res = conn.SendPostWithCredsInHeader("api/PWAppVersion", "");
}
[TestMethod]
[ExpectedException(typeof(RequestFailedExcpetion))]
public void TestInvalidCredentialsV2()
{
APICredentials creds = new APICredentials();
creds.UserID = "testdoctor";
creds.Password = "badPassword";
creds.PracticeId = "210";
creds.APIid = "12345678";
APIConnection conn = new APIConnection("https://localhost:44354/", creds);
string res = conn.SendPostWithCredsInHeader("api/PWAppVersion", "");
}
} }
} }

View File

@ -51,6 +51,8 @@
<ItemGroup> <ItemGroup>
<Compile Include="UnitTest1.cs" /> <Compile Include="UnitTest1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ConfigTest.cs" />
<Compile Include="PWConnectionTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />