Modules/Interfaces/GraphQLInterface.vb

182 lines
6.1 KiB
VB.net

Imports System.IO
Imports System.Net
Imports System.Security.Cryptography.X509Certificates
Imports System.Text
Imports DigitalData.Modules.Logging
Imports Newtonsoft.Json
Public Class GraphQLInterface
Private _logConfig As LogConfig
Private _logger As Logger
Private _baseUrl As String
Private _userEmail As String
Private _userPassword As String
Private _certificate As X509Certificate2
Private _cookieJar As CookieContainer
Private _Encoding As New UTF8Encoding
Private Const MAX_COOKIE_SIZE As Integer = 32768
Private Const MAX_COOKIE_COUNT As Integer = 300
Private Const MAX_COOKIE_COUNT_PER_DOMAIN As Integer = 20
Public Property Proxy As WebProxy
Public Property Credentials As NetworkCredential
Public Sub New(LogConfig As LogConfig, BaseUrl As String, Email As String, Password As String, CertificateFingerprint As String)
Try
_logConfig = LogConfig
_logger = LogConfig.GetLogger()
_baseUrl = BaseUrl
_userEmail = Email
_userPassword = Password
Dim oStore As New X509Store(StoreName.Root, StoreLocation.CurrentUser)
oStore.Open(OpenFlags.ReadOnly)
_logger.Debug("Available Certificates ({0}):", oStore.Certificates.Count)
For Each oCert In oStore.Certificates
_logger.Debug("FriendlyName: {0}", oCert.FriendlyName)
_logger.Debug("IssuerName: {0}", oCert.IssuerName.Name)
_logger.Debug("SubjectName: {0}", oCert.SubjectName.Name)
_logger.Debug("Fingerprint: {0}", oCert.Thumbprint)
Next
_logger.Debug("Looking for Certificate with Fingerprint [{0}]", CertificateFingerprint)
Dim oFoundCerts = oStore.Certificates.Find(X509FindType.FindByThumbprint, CertificateFingerprint, False)
If oFoundCerts.Count = 0 Then
_logger.Warn("Certificate could not be found! Exiting.")
Exit Sub
End If
_certificate = oFoundCerts.Item(0)
Catch ex As Exception
_logger.Error(ex)
End Try
End Sub
Public Sub SaveCookies(Cookie As Cookie)
GetCookies().Add(Cookie)
End Sub
Public Function Login() As HttpWebResponse
Try
Dim oLoginData As New LoginData() With {.email = _userEmail, .token = _userPassword}
Dim oBytes As Byte() = ToBytes(JsonConvert.SerializeObject(oLoginData))
Dim oRequest As HttpWebRequest = GetRequest("/login", oBytes)
Using oStream = oRequest.GetRequestStream()
oStream.Write(oBytes, 0, oBytes.Length)
End Using
Return oRequest.GetResponse()
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Function Logout() As HttpWebResponse
Try
Dim oLogoutData As New LogoutData() With {.email = _userEmail}
Dim oBytes As Byte() = ToBytes(JsonConvert.SerializeObject(oLogoutData))
Dim oRequest As HttpWebRequest = GetRequest("/logout", oBytes)
Using stream = oRequest.GetRequestStream()
stream.Write(oBytes, 0, oBytes.Length)
End Using
Return oRequest.GetResponse()
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Function GetData(Query As String, OperationName As String) As HttpWebResponse
Try
Dim oQueryData As New QueryData() With {
.operationName = OperationName,
.query = Query,
.variables = New Object
}
Dim oJson = JsonConvert.SerializeObject(oQueryData)
Dim oBytes = ToBytes(oJson)
Dim oRequest = GetRequest("/graphql", oBytes)
Using stream = oRequest.GetRequestStream()
stream.Write(oBytes, 0, oBytes.Length)
End Using
Return oRequest.GetResponse()
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Function ReadJSONPathFragmented(pObject As Linq.JObject, pJsonPath As String)
Dim oSplitPath As List(Of String) = pJsonPath.Split(".").ToList()
Dim oCurrentPath As String = String.Empty
For Each oPart In oSplitPath
If oCurrentPath = String.Empty Then
oCurrentPath = oPart
Else
oCurrentPath &= "." & oPart
End If
_logger.Debug("Selecting Path Fragment [{0}]", oCurrentPath)
Try
pObject.SelectToken(oCurrentPath, errorWhenNoMatch:=True)
Catch ex As Exception
_logger.Warn("Path Fragment [{0}] did not return a valid token", oCurrentPath)
Return False
End Try
Next
Return True
End Function
Private Function GetRequest(Url As String, PostData As Byte()) As HttpWebRequest
Try
Dim oRequest As HttpWebRequest = WebRequest.Create($"{_baseUrl}{Url}")
oRequest.Method = "POST"
oRequest.ContentType = "application/json"
oRequest.ContentLength = PostData.Length
oRequest.ClientCertificates.Add(_certificate)
oRequest.CookieContainer = GetCookies()
oRequest.Proxy = Nothing
If Proxy Is Nothing Then
oRequest.Proxy = Nothing
Else
oRequest.Proxy = Proxy
oRequest.Credentials = Credentials
End If
Return oRequest
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Private Function GetCookies() As CookieContainer
If _cookieJar Is Nothing Then
_cookieJar = New CookieContainer(MAX_COOKIE_COUNT, MAX_COOKIE_COUNT_PER_DOMAIN, MAX_COOKIE_SIZE)
End If
Return _cookieJar
End Function
Private Function ToBytes(Str As String) As Byte()
Return _Encoding.GetBytes(Str)
End Function
End Class