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.Security; using ChatController.Utilities; using Newtonsoft.Json; using RestSharp; namespace ChatController.HauptKlassen { public class Login { private Action _ExceptionCallback; private void PinCertificate() { ServicePointManager.ServerCertificateValidationCallback = CertificateChecker.PinPublicKey; } 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 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 callback, Action 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 { { "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 callback, Action 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 callback, Action 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(response.Content); if(lookupResult is null) { if(response.ErrorException?.InnerException?.Message.Equals(CertificateChecker.PinningFailMessage) ?? false) { exceptionCallback?.Invoke(CertificateChecker.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(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(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 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(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(serverResponse); _AllGroups = jsonDaten; _GruppeholenverbindungsaufbauOk = true; } } private void ConnectWithChatServerAsync(Action callback, Action 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(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 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(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 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); }); } } }