566 lines
21 KiB
C#
566 lines
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.Security;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using System.Windows;
|
|
using ChatController.Core;
|
|
using ChatController.Data;
|
|
using ChatController.LoginKlassen;
|
|
using ChatController.Utilities;
|
|
|
|
using Newtonsoft.Json;
|
|
using RestSharp;
|
|
|
|
|
|
namespace ChatController.HauptKlassen
|
|
{
|
|
public class Login
|
|
{
|
|
private Action<string> _ExceptionCallback;
|
|
|
|
private void PinCertificate()
|
|
{
|
|
ServicePointManager.ServerCertificateValidationCallback = PinPublicKey;
|
|
}
|
|
|
|
private bool PinPublicKey(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
|
|
{
|
|
try
|
|
{
|
|
if(certificate is null || chain is null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var chainContainsPk = false;
|
|
|
|
foreach(var element in chain.ChainElements)
|
|
{
|
|
var pk = element.Certificate.GetPublicKeyString();
|
|
if(pk == PubKeyX3 || pk == PubKeyR3 || pk == PubKeyE1)
|
|
{
|
|
chainContainsPk = true;
|
|
}
|
|
}
|
|
|
|
var subjectAccepted = certificate.Subject.Trim().ToLower().EndsWith(".bewoplaner.de") || certificate.Subject.Trim().ToLower().EndsWith(".ownchat.de");
|
|
|
|
var result = chainContainsPk && subjectAccepted;
|
|
|
|
if(false == result)
|
|
{
|
|
throw new Exception(PinningFailMessage);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch(Exception exception)
|
|
{
|
|
if(exception.Message?.Equals(PinningFailMessage) ?? false)
|
|
{
|
|
_ExceptionCallback?.Invoke(PinningFailMessage);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private const string PinningFailMessage = "Es konnte keine sichere Verbindung zum Server hergestellt werden.";
|
|
|
|
private const string PubKeyX3 = "3082010A02820101009CD30CF05AE52E47B7725D3783B3686330EAD735261925E1BDBE35F170922FB7B84B4105ABA99E350858ECB12AC468870BA3E375E4E6F3A76271BA7981601FD7919A9FF3D0786771C8690E9591CFFEE699E9603C48CC7ECA4D7712249D471B5AEBB9EC1E37001C9CAC7BA705EACE4AEBBD41E53698B9CBFD6D3C9668DF232A42900C867467C87FA59AB8526114133F65E98287CBDBFA0E56F68689F3853F9786AFB0DC1AEF6B0D95167DC42BA065B299043675806BAC4AF31B9049782FA2964F2A20252904C674C0D031CD8F31389516BAA833B843F1B11FC3307FA27931133D2D36F8E3FCF2336AB93931C5AFC48D0D1D641633AAFA8429B6D40BC0D87DC3930203010001";
|
|
|
|
private const string PubKeyR3 = "3082010A0282010100BB021528CCF6A094D30F12EC8D5592C3F882F199A67A4288A75D26AAB52BB9C54CB1AF8E6BF975C8A3D70F4794145535578C9EA8A23919F5823C42A94E6EF53BC32EDB8DC0B05CF35938E7EDCF69F05A0B1BBEC094242587FA3771B313E71CACE19BEFDBE43B45524596A9C153CE34C852EEB5AEED8FDE6070E2A554ABB66D0E97A540346B2BD3BC66EB66347CFA6B8B8F572999F830175DBA726FFB81C5ADD286583D17C7E709BBF12BF786DCC1DA715DD446E3CCAD25C188BC60677566B3F118F7A25CE653FF3A88B647A5FF1318EA9809773F9D53F9CF01E5F5A6701714AF63A4FF99B3939DDC53A706FE48851DA169AE2575BB13CC5203F5ED51A18BDB150203010001";
|
|
|
|
private const string PubKeyE1 = "04245C2DA22AFD1C4BA65D97732731ACB2A06962EF65E8A6B0F0AC4B9FFF1C0B700FD3982F4DFC0F009B37F074055732972E05EF2A4325A3FB6E342713F64F7E69D302995EEB244792C1249BE6B1218FC12481FC68CC1F69BA58F51922F774C616";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private string _BaseUrl = string.Empty;
|
|
|
|
private const string DictionaryServerUrl = "https://dict.ownchat.de/api/server/resolve/1/";
|
|
|
|
public string ServerUrl { get; set; } = string.Empty;
|
|
|
|
private string _AuthToken = string.Empty;
|
|
|
|
private readonly string _UserName;
|
|
private readonly string _Password;
|
|
private readonly string _Tenant;
|
|
private readonly string _ChatCode;
|
|
private readonly string _ApiKey;
|
|
|
|
private long? _UserId;
|
|
|
|
private bool _OwnchatVerbindungsaufbauOk;
|
|
private bool _GruppeholenverbindungsaufbauOk;
|
|
|
|
private UserDaten _LoggedInUser;
|
|
private ChatGruppenDaten _AllGroups;
|
|
|
|
private readonly bool _ShouldShowMessageBox = true;
|
|
|
|
public Login(string pTenant, string pChatCode, string pUserName, string pPassword)
|
|
{
|
|
_Tenant = pTenant;
|
|
_ChatCode = pChatCode;
|
|
_UserName = pUserName;
|
|
_Password = pPassword;
|
|
_ApiKey = "0000";
|
|
}
|
|
|
|
// Wird im BeWoPlaner benutzt
|
|
public Login(string pTenant, string pChatCode, string pUserName, string pPassword, string pApiKey)
|
|
{
|
|
_Tenant = pTenant;
|
|
_ChatCode = pChatCode;
|
|
_UserName = pUserName;
|
|
_Password = pPassword;
|
|
_ApiKey = pApiKey;
|
|
}
|
|
|
|
// Wird im BeWoPlaner benutzt
|
|
public Login(string tenant, Action<string> callback)
|
|
{
|
|
_Tenant = tenant;
|
|
_ShouldShowMessageBox = false;
|
|
|
|
// TODO: Ändern, sonst wird keine Fehlermeldung angezeigt!
|
|
LookupServerUrlAsync(isSuccessful => { callback(ServerUrl); }, null);
|
|
}
|
|
|
|
// Wird im BeWoPlaner benutzt
|
|
public Login(string tenant, Action<string> callback, Action<string> exceptionCallback)
|
|
{
|
|
_Tenant = tenant;
|
|
_ShouldShowMessageBox = false;
|
|
|
|
LookupServerUrlAsync(isSuccessful => { callback(ServerUrl); }, exceptionCallback);
|
|
}
|
|
|
|
// Wird im BeWoPlaner benutzt
|
|
public ChatDatenUebergabe AnmeldevorgangDurchFuehren()
|
|
{
|
|
if(!ServerErmittlung())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var dic = new Dictionary<string, string>
|
|
{
|
|
{ "username", _UserName},
|
|
{ "password", _Password},
|
|
{ "chatcode", _ChatCode}
|
|
};
|
|
|
|
VerbindeMitChatServer(dic);
|
|
|
|
if(_OwnchatVerbindungsaufbauOk)
|
|
{
|
|
GetGroups();
|
|
}
|
|
|
|
if(!_GruppeholenverbindungsaufbauOk)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var maxUploadSize = GetMaiximumAllowedFileUploadSize(_AuthToken, _Tenant);
|
|
|
|
return new ChatDatenUebergabe(_LoggedInUser, _AllGroups, ServerUrl, _AuthToken, _UserId, _Tenant, _ApiKey, maxUploadSize);
|
|
|
|
}
|
|
|
|
public void DoLoginAsync(Action<ChatDatenUebergabe> callback, Action<string> exceptionCallback)
|
|
{
|
|
try
|
|
{
|
|
_ExceptionCallback = exceptionCallback;
|
|
|
|
LookupServerUrlAsync(isConnectedWithServer =>
|
|
{
|
|
if(isConnectedWithServer)
|
|
{
|
|
ConnectWithChatServerAsync(
|
|
isSuccessfullyLoggedIn =>
|
|
{
|
|
if(isSuccessfullyLoggedIn)
|
|
{
|
|
GetGroupsAsync(wasSuccessful =>
|
|
{
|
|
if(wasSuccessful)
|
|
{
|
|
GetMaximumAllowedFileUploadSizeAsync(maxUploadFileSize =>
|
|
{
|
|
callback?.Invoke(new ChatDatenUebergabe(_LoggedInUser, _AllGroups, ServerUrl, _AuthToken, _UserId, _Tenant, _ApiKey, maxUploadFileSize));
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
errorMessage => { exceptionCallback?.Invoke(errorMessage); });
|
|
}
|
|
}, errorMessage => { exceptionCallback?.Invoke(errorMessage); });
|
|
}
|
|
catch(Exception exception)
|
|
{
|
|
exceptionCallback?.Invoke(exception.Message);
|
|
}
|
|
}
|
|
|
|
public void LookupServerUrlAsync(Action<bool> callback, Action<string> exceptionCallback)
|
|
{
|
|
try
|
|
{
|
|
if(!string.IsNullOrWhiteSpace(ServerUrl))
|
|
{
|
|
callback?.Invoke(false);
|
|
return;
|
|
}
|
|
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
|
|
|
PinCertificate();
|
|
|
|
var client = new RestClient(DictionaryServerUrl);
|
|
var request = new RestRequest(_Tenant);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
var lookupResult = JsonConvert.DeserializeObject<LookupResult>(response.Content);
|
|
|
|
if(lookupResult is null)
|
|
{
|
|
if(response.ErrorException?.InnerException?.Message.Equals(PinningFailMessage) ?? false)
|
|
{
|
|
exceptionCallback?.Invoke(PinningFailMessage);
|
|
}
|
|
else
|
|
{
|
|
exceptionCallback?.Invoke("Anmeldung nicht möglich. Bitte prüfen Sie Ihre Internet-Verbindung.");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
_BaseUrl = lookupResult.Url;
|
|
ServerUrl = _BaseUrl;
|
|
OwnChatCache.BaseUri = _BaseUrl;
|
|
|
|
var result = false;
|
|
|
|
switch(lookupResult.Status)
|
|
{
|
|
case 0:
|
|
result = true;
|
|
break;
|
|
case 1:
|
|
exceptionCallback?.Invoke("Fehler: Kundennummer unbekannt.\nBitte überprüfen Sie die Anmeldeinformationen.");
|
|
break;
|
|
case 2:
|
|
exceptionCallback?.Invoke("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.");
|
|
MessageBox.Show("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk);
|
|
break;
|
|
}
|
|
|
|
callback?.Invoke(result);
|
|
});
|
|
}
|
|
catch(Exception exception)
|
|
{
|
|
exceptionCallback?.Invoke(exception.Message);
|
|
}
|
|
}
|
|
|
|
public bool ServerErmittlung()
|
|
{
|
|
if(string.IsNullOrEmpty(ServerUrl))
|
|
{
|
|
var serverURl = DictionaryServerUrl + _Tenant;
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
|
var request = WebRequest.Create(serverURl);
|
|
|
|
request.Credentials = CredentialCache.DefaultCredentials;
|
|
|
|
var response = request.GetResponse();
|
|
var responseFromServer = Utils.ReadStream(response);
|
|
|
|
try
|
|
{
|
|
var jsonDatentyp = JsonConvert.DeserializeObject<AuthenticationDataType1>(responseFromServer);
|
|
|
|
switch(jsonDatentyp.Status)
|
|
{
|
|
case 1:
|
|
if (_ShouldShowMessageBox)
|
|
{
|
|
MessageBox.Show("Fehler: Kundennummer unbekannt.\nBitte überprüfen Sie die Anmeldeinformationen.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk);
|
|
}
|
|
|
|
return false;
|
|
case 2:
|
|
if (_ShouldShowMessageBox)
|
|
{
|
|
MessageBox.Show("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
_BaseUrl = jsonDatentyp.Url;
|
|
}
|
|
catch(Exception)
|
|
{
|
|
var jsonDatentyp = JsonConvert.DeserializeObject<AuthenticationDataType2>(responseFromServer);
|
|
|
|
switch(jsonDatentyp.Status)
|
|
{
|
|
case 1:
|
|
if (_ShouldShowMessageBox)
|
|
{
|
|
MessageBox.Show("Fehler: Kundennummer unbekannt.\nBitte überprüfen Sie die Anmeldeinformationen.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk);
|
|
}
|
|
|
|
return false;
|
|
case 2:
|
|
if (_ShouldShowMessageBox)
|
|
{
|
|
MessageBox.Show("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
_BaseUrl = jsonDatentyp.Url;
|
|
}
|
|
|
|
response.Close();
|
|
|
|
ServerUrl = _BaseUrl;
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void VerbindeMitChatServer(Dictionary<string, string> postparameter)
|
|
{
|
|
var endurl = _BaseUrl + Constants.LoginWithChatCodeUrl;
|
|
|
|
var requestBody = postparameter.Keys.Aggregate(string.Empty, (current, key) => current + HttpUtility.UrlEncode(key) + "=" + HttpUtility.UrlEncode(postparameter[key]) + "&");
|
|
|
|
var client = new RestClient(endurl);
|
|
var request = new RestRequest(Method.POST);
|
|
|
|
request.AddHeader("content-type", "application/x-www-form-urlencoded");
|
|
request.AddParameter(Constants.CustomerId, _Tenant, ParameterType.HttpHeader);
|
|
request.AddParameter("application/x-www-form-urlencoded", requestBody, ParameterType.RequestBody);
|
|
|
|
var response = client.Post(request);
|
|
|
|
if(response.StatusCode == HttpStatusCode.OK)
|
|
{
|
|
Debug.WriteLine(response.Content);
|
|
var userDaten = JsonConvert.DeserializeObject<UserDaten>(response.Content);
|
|
|
|
if(userDaten.Success)
|
|
{
|
|
_AuthToken = userDaten.Response.User.Token;
|
|
_UserId = userDaten.Response.User.Oid;
|
|
|
|
Utils.AuthToken = _AuthToken;
|
|
Utils.Tenant = _Tenant;
|
|
|
|
_LoggedInUser = userDaten;
|
|
|
|
_OwnchatVerbindungsaufbauOk = true;
|
|
}
|
|
else
|
|
{
|
|
if(!(userDaten.Error?.ChatCodeFailed is null))
|
|
{
|
|
if(_ShouldShowMessageBox)
|
|
{
|
|
MessageBox.Show("Fehler: " + userDaten.Error.ChatCodeFailed[0] + "\nBitte überprüfen Sie die Anmeldeinformationen.", "Info", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
else if(!(userDaten.Error?.LoginFailed is null))
|
|
{
|
|
if(_ShouldShowMessageBox)
|
|
{
|
|
MessageBox.Show("Fehler: " + userDaten.Error.LoginFailed[0] + "\nBitte überprüfen Sie die Anmeldeinformationen.", "Info", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
_OwnchatVerbindungsaufbauOk = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show(response.Content, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
private void GetGroups()
|
|
{
|
|
var endurl = _BaseUrl + Constants.GetChatGroupsUrl;
|
|
|
|
var request = WebRequest.Create(endurl);
|
|
|
|
request.Credentials = CredentialCache.DefaultCredentials;
|
|
request.Headers[Constants.Token] = _AuthToken;
|
|
request.Headers[Constants.CustomerId] = _Tenant;
|
|
|
|
using(var response = request.GetResponse())
|
|
{
|
|
var serverResponse = Utils.ReadStream(response);
|
|
|
|
if(string.IsNullOrEmpty(serverResponse))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var jsonDaten = JsonConvert.DeserializeObject<ChatGruppenDaten>(serverResponse);
|
|
|
|
_AllGroups = jsonDaten;
|
|
|
|
_GruppeholenverbindungsaufbauOk = true;
|
|
}
|
|
}
|
|
|
|
private void ConnectWithChatServerAsync(Action<bool> callback, Action<string> exceptionCallback)
|
|
{
|
|
var url = _BaseUrl + Constants.LoginWithChatCodeUrl;
|
|
var requestBody = $"{HttpUtility.UrlEncode("username")}={HttpUtility.UrlEncode(_UserName)}&{HttpUtility.UrlEncode("password")}={HttpUtility.UrlEncode(_Password)}&{HttpUtility.UrlEncode("chatcode")}={HttpUtility.UrlEncode(_ChatCode)}";
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest(Method.POST);
|
|
|
|
request.AddHeader(Constants.ContentTypeKey, Constants.FormUrlEncodedContentTypeValue);
|
|
request.AddParameter(Constants.CustomerId, _Tenant, ParameterType.HttpHeader);
|
|
request.AddParameter(Constants.FormUrlEncodedContentTypeValue, requestBody, ParameterType.RequestBody);
|
|
|
|
client.PostAsync(request, (response, handle) =>
|
|
{
|
|
var connectionData = JsonConvert.DeserializeObject<UserDaten>(response.Content);
|
|
|
|
if(connectionData?.Success ?? false)
|
|
{
|
|
_AuthToken = connectionData.Response.User.Token;
|
|
_UserId = connectionData.Response.User.Oid;
|
|
|
|
Utils.AuthToken = _AuthToken;
|
|
Utils.Tenant = _Tenant;
|
|
|
|
_LoggedInUser = connectionData;
|
|
|
|
OwnChatCache.GetInstance().LoggedOnUserId = _LoggedInUser.Response.User.Oid;
|
|
|
|
callback?.Invoke(true);
|
|
}
|
|
else
|
|
{
|
|
var errorMessage = string.Empty;
|
|
|
|
if(!(connectionData?.Error?.ChatCodeFailed is null))
|
|
{
|
|
errorMessage = $"Fehler: {connectionData.Error.ChatCodeFailed[0]}";
|
|
}
|
|
else if(!(connectionData?.Error?.LoginFailed is null))
|
|
{
|
|
errorMessage = $"Fehler: {connectionData.Error.LoginFailed[0]}";
|
|
}
|
|
|
|
if(!string.IsNullOrWhiteSpace(errorMessage))
|
|
{
|
|
exceptionCallback?.Invoke(errorMessage);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private void GetGroupsAsync(Action<bool> callback)
|
|
{
|
|
var url = _BaseUrl + Constants.GetChatGroupsUrl;
|
|
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
|
|
|
var client = new RestClient(url);
|
|
|
|
var request = new RestRequest();
|
|
request.AddHeader(Constants.Token, _AuthToken);
|
|
request.AddHeader(Constants.CustomerId, _Tenant);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
var groups = JsonConvert.DeserializeObject<ChatGruppenDaten>(response.Content);
|
|
|
|
_AllGroups = groups;
|
|
|
|
callback?.Invoke(true);
|
|
});
|
|
}
|
|
|
|
public long GetMaiximumAllowedFileUploadSize(string pToken, string pCustomerId)
|
|
{
|
|
long maximumFileSize = 0L;
|
|
|
|
var endurl = ServerUrl + Constants.MaxUploadFileSizeUrl;
|
|
|
|
var request = WebRequest.Create(endurl);
|
|
request.Headers[Constants.Token] = pToken;
|
|
request.Headers[Constants.CustomerId] = pCustomerId;
|
|
|
|
request.Credentials = CredentialCache.DefaultCredentials;
|
|
request.Proxy = null;
|
|
|
|
using (var response = request.GetResponse())
|
|
{
|
|
var responseFromServer = Utils.ReadStream(response);
|
|
|
|
var definiti = new {file_upload_max_size = ""};
|
|
|
|
var jsonDatentyp = JsonConvert.DeserializeAnonymousType(responseFromServer, definiti);
|
|
maximumFileSize = Convert.ToInt64(jsonDatentyp.file_upload_max_size);
|
|
}
|
|
|
|
return maximumFileSize;
|
|
}
|
|
|
|
public void GetMaximumAllowedFileUploadSizeAsync(Action<long> callback)
|
|
{
|
|
var url = ServerUrl + Constants.MaxUploadFileSizeUrl;
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest();
|
|
|
|
request.AddHeader(Constants.Token, _AuthToken);
|
|
request.AddHeader(Constants.CustomerId, _Tenant);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
var maxFileSizeAnonymous = JsonConvert.DeserializeAnonymousType(response.Content, new { file_upload_max_size = string.Empty });
|
|
|
|
var maxUploadFileSize = Convert.ToInt64(maxFileSizeAnonymous.file_upload_max_size);
|
|
|
|
callback?.Invoke(maxUploadFileSize);
|
|
});
|
|
}
|
|
}
|
|
}
|