HTTPOnly Cookies with WebBrowser and WebClient - vb.net

I made a program that allows a user to login with a WebBrowser control to our CRM system (ConnectWise)
The cookies would then be moved a Web Client control, where it would parse a url which came back with a .csv file. The Webclient would then download the csv to "C:\Temp\unassigned.csv" and I would then use this file to do other things in the program.
This worked great for months, until there was an update to Connectwise which brought in the use of HTTPOnly Cookies, of which I cannot extract the cookies from the Web Browser Control. The WebBrowser1.Document.Cookie string is now blank.
Here is the code:
Private Sub Internetr()
If WebBrowser1.Url.ToString.StartsWith("REDACTED") Then 'if connectwise is logged in
Dim _url As String = "REDACTED"
Dim _filename As String = ("C:\Temp\unassigned.csv")
WebBrowser1.Visible = False 'Hide the webbrowser
Refresh.Enabled = True 'Enable the ticker
Dim csv As WebClient = New WebClient 'new download webclient
'THIS IS WHERE I MOVED THE COOKIES FROM WEB BROWSER TO WEBCLIENT BEFORE
Try
csv.DownloadFile(_url, _filename)
load.Text = "Updating List..."
csv.Dispose()
DoUnassigned()
Catch ex As Exception
load.Text = "Failed to update list, Last updated at: " & gettime
debugbtn.Visible = True
exception = ex.ToString
Failed()
End Try
Else
WebBrowser1.Visible = True 'if not logged in, show the webbrowser
End If
End Sub
Does anyone have any ideas please?

Related

Google Drive API v3 VB.NET Upload and Download Files to ServiceAccount

I've been trying to follow https://developers.google.com/drive/v3/web/quickstart/dotnet and the Google API documentation, as well as searching all over the internet, but there really isn't a straightforward example to use (especially for v3)
I have a VB.NET GUI that contains a listview with the names of all plain text files in a folder. Clicking on one will display its' contents in a textbox. You can also type into a blank text box and save it. I want to allow multiple users to upload their text file to the Google Drive and be able to download all text files that are stored there.
I don't have much of an issue translating code from C# to VB.NET, and I think I'm fine with authenticating the service account with Google (or at least I don't get an error), but uploading only shows me response = Nothing. Any help is appreciated.
I created the service account through Google and have the following:
Dim service = AuthenticateServiceAccount("xxxxx#xxxxx.iam.gserviceaccount.com", "C:\Users\xxxxx\Documents\Visual Studio 2015\Projects\MyProject\accountkey-0c1aa839896b.json")
If drive.UploadFile(service, "C:\Users\xxxxx\Documents\Visual Studio 2015\Projects\MyProject\file.txt") Is Nothing Then
MsgBox("File not uploaded")
Else
MsgBox("File uploaded")
End If
Authenticate:
Public Function AuthenticateServiceAccount(ByVal serviceAccountEmail As String, ByVal serviceAccountCredentialFilePath As String) As DriveService
Dim scopes As String() = {DriveService.Scope.Drive, DriveService.Scope.DriveAppdata, DriveService.Scope.DriveReadonly, DriveService.Scope.DriveFile, DriveService.Scope.DriveMetadataReadonly, DriveService.Scope.DriveReadonly, DriveService.Scope.DriveScripts}
Try
If (String.IsNullOrEmpty(serviceAccountCredentialFilePath)) Then
Throw New Exception("Path to the service account credentials file is required.")
End If
If Not IO.File.Exists(serviceAccountCredentialFilePath) Then
Throw New Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath)
End If
If (String.IsNullOrEmpty(serviceAccountEmail)) Then
Throw New Exception("ServiceAccountEmail is required.")
End If
If (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() = ".json") Then
Dim credential As GoogleCredential
Dim sstream As New FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read)
credential = GoogleCredential.FromStream(sstream)
credential.CreateScoped(scopes)
'Create the Analytics service.
Return New DriveService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "Drive Service Account Authentication Sample"
})
Else
Throw New Exception("Unsupported Service accounts credentials.")
End If
Catch e As Exception
MsgBox("Create service account DriveService failed" + e.Message)
Throw New Exception("CreateServiceAccountDriveFailed", e)
End Try
End Function
Upload File:
Public Function UploadFile(service As DriveService, FilePath As String) As Google.Apis.Drive.v3.Data.File
If (System.IO.File.Exists(FilePath)) Then
Dim body As New Google.Apis.Drive.v3.Data.File()
body.Name = System.IO.Path.GetFileName(FilePath)
body.Description = "Text file"
body.MimeType = "text/plain"
'files content
Dim byteArray As Byte() = System.IO.File.ReadAllBytes(FilePath)
Dim stream As New System.IO.MemoryStream(byteArray)
Try
Dim request As FilesResource.CreateMediaUpload = service.Files.Create(body, stream, "text/plain")
request.Upload()
Return request.ResponseBody
Catch e As Exception
MsgBox("An error occurred: " + e.Message)
Return Nothing
End Try
Else
MsgBox("File does not exist: " + FilePath)
Return Nothing
End If
End Function
As stated here, since you are using a Service Account, all the folders and files will be created in this Service Account's Drive which cannot be accessed through a web UI and will be limited to the default quota.
To add content in a user's Drive, you will need to go through the regular OAuth 2.0 flow to retrieve credentials from this user. You can find more information about OAuth 2.0 on this pages:
Retrieve and use OAuth 2.0 credentials.
Quickstart: it has a quickstart sample in C# that you could use.
Using OAuth 2.0 to access Google APIs
You may also check this related thread: upload files to Google drive in VB.NET - searching for working code

vb.net downloading a file without popups

I am trying to download tracking information from FedEx's website. First I have to pass login credentials and then navigate to a webpage which triggers an automatic download. My code so far works fine for this. However; as soon as the download is triggered a popup comes up asking if I want to save the file and then when I click save I asks where I want to save the file to. I want to disable the popups and have the file just automatically saved in my downloads folder. Is there a way to do this? Thanks in advance for any help!
Here is my code so far.
Dim WebBrowser1 As New WebBrowser
Dim url As String = "https://www.fedex.com/insight/manifest/manifest.jsp?&__QS=252D0F3B4E380B211B122B1A09251510050E0F5C273A223E34360539237976645E45745E57776C&"
WebBrowser1.Navigate(url)
WebBrowser1.ScriptErrorsSuppressed = True
Threading.Thread.Sleep(2000)
Application.DoEvents()
Do Until WebBrowser1.IsBusy = False
Threading.Thread.Sleep(1000)
Application.DoEvents()
Loop
WebBrowser1.Document.GetElementById("username").SetAttribute("value", "MyUsername")
WebBrowser1.Document.GetElementById("password").SetAttribute("value", "MyP#ssw0rd")
WebBrowser1.Document.GetElementById("login").InvokeMember("click")
Threading.Thread.Sleep(1000)
Application.DoEvents()
Do Until WebBrowser1.IsBusy = False
Threading.Thread.Sleep(1000)
Application.DoEvents()
Loop
WebBrowser1.Navigate("https://www.fedex.com/insight/manifest/download_post.jsp?VIEW=|Outbound_View&INFOTYPE=STATUS")
Do Until WebBrowser1.IsBusy = False
Threading.Thread.Sleep(1000)
Application.DoEvents()
Loop
So I tried this code but all this does is still just download the page's source.
Using client As New WebClient()
client.Headers("User-Agent") = "Mozilla/4.0"
client.Credentials = New NetworkCredential("Username", "P#sword")
client.Credentials = CredentialCache.DefaultCredentials ' << if Windows Authentication
Dim content As String = client.DownloadString("https://www.fedex.com/insight/manifest/download.jsp?VIEW=/Outbound_View")
Console.WriteLine(content.Substring(0, 15))
End Using
I checked the webpage's source again to try to find a different url but also could not find anything else. I was wondering if it would be easier to download using WebBrowser.Navigate and then suppress the popups. Is there away to suppress or get rid of the download popups in vb? I am just not having much success with the WebClient. Thanks for all the help as I am still pretty new at vb.net!

Hide Picturebox if image is invalid

I am creating reports using Telerik Reporting Tool and has some image on it. I display the Image in the picturebox using a URL that came from the clients but there are instances where the given URL is invalid so it will display an error message in the report. I want to just hide the picturebox whenever the Image is not available so that the error will not appear in the report. how can I do it? thanks in advance :)
Do a webrequest on your website.
For example:
Public Sub Run()
Dim myReportImage As Image = GetControl("ReportImage")
myReportImage.Visible = CheckWebImage()
' or
myReportImage.Enabled = CheckWebImage()
End Sub
Private Function CheckWebImage() As Boolean
Dim url As New System.Uri("http://www.url.com/yourImage.jpg")
Dim request As System.Net.WebRequest = System.Net.WebRequest.Create(url)
Dim response As System.Net.WebResponse
Try
response = req.GetResponse()
response.Close()
request = Nothing
Msgbox("Website Found!")
Return True
Catch ex As Exception
request = Nothing
Msgbox("Website not found. Check the url and internet connection")
Return False
End Try
End Sub

How can I launch a URL in .NET with an Authorization header?

We are creating a plug-in to Ellie Mae's Encompass system for a client.
This particular plugin just has one button, which when clicked launches a URL and passes in the userid of the currently logged in Encompass user. This is all very straight forward using the following code...
Private Sub btnProductSearch_Click(sender As Object, e As EventArgs)
Handles btnProductSearch.Click
Try
Dim cliid = EncompassApplication.Session.ClientID,
unm As String = EncompassApplication.CurrentUser().ID,
url As String = GetServiceUrl(cliid)
If String.IsNullOrEmpty(url) Then
MsgBox("No matching URL found for current Encompass Client ID.")
Else
Process.Start(url & unm)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Now for the fun part... they don't want the user to have to log in to the URL being launched, but want us to pass the authentication to the URL via an Authorization HTTP header.
This would be easy enough if we were doing our own web request in code, something like the following:
Dim wreq = HttpWebRequest.CreateHttp(url)
wreq.Method = "POST"
Dim authBytes As Byte() = Encoding.UTF8.GetBytes("EncodedInfoHere".ToCharArray())
wreq.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(authBytes))
wreq.ContentType = "application/json"
However, we are not doing a code web request, but rather are simply launching the URL via Process.Start. Is there any way while doing this to pass the Authorization header?
With help from this question, I dropped a hidden WebBrowser control on my form, and then launched the URL in an external browser, with Authorization header, as follows...
' wb is the WebBrowser
Dim hdr = "Authorization: Basic " & Convert.ToBase64String(Encoding.UTF8.GetBytes("EncodedInfoHere".ToCharArray()))
wb.Navigate(url & unm, "_blank", {}, hdr)

Finding the default browser in VB.net

I am using Process.Start(url) to launch a URL in the default web browser and then I plan to close it using Process.Kill().
The problem is finding the default browser to know which process to kill. Suggestions?
Taken from: Opening default web browser
Private Function getDefaultBrowser() As String
Dim browser As String = String.Empty
Dim key As RegistryKey = Nothing
Try
key = Registry.ClassesRoot.OpenSubKey("HTTP\shell\open\command", False)
'trim off quotes
browser = key.GetValue(Nothing).ToString().ToLower().Replace("""", "")
If Not browser.EndsWith("exe") Then
'get rid of everything after the ".exe"
browser = browser.Substring(0, browser.LastIndexOf(".exe") + 4)
End If
Finally
If key IsNot Nothing Then
key.Close()
End If
End Try
Return browser
End Function
There you can get the default browser. Then you can loop through the running process and kill the browser.
Dim browser As String
browser = getDefaultBrowser()
For Each p As Process In Process.GetProcesses
If p.ProcessName = browser Then
p.Kill()
Exit For
End If
Next