Delete and upload files into Azure webapp local storage programatically - c#

I've deployed a website into Azure and i want to access programaticaly this path : "D:\home\site\app" from a c# desktop application and delete all files and upload new ones programatically.
i have searched and found many ways but all are for AzureStorage or using Kudu consol or FTP while what i realy want is to access the local storage where the website is deployed programatiacally, and make some edits on files programatically.

Sure thing, the Site Control Manager (Kudu) has an API for that, the VFS API:
https://github.com/projectkudu/kudu/wiki/REST-API#vfs
You can use either of these for authentication:
A Bearer token that you obtain from the STS (reference implementation in ARMClient)
Site-level credentials (the long ugly ones under your Web App → Properties)
Git/FTP credentials (subscription level)
Sample usage (using site-level credentials):
# Line breaks brutally used to improve readability
# /api/vfs/ is d:\home
# Append path as necessary, i.e. /api/vfs/site/app
$ curl -k https://$are-we-eating-too-much-garlic-as-a-people:6sujXXX
XXXXXXq7Zc#are-we-eating-too-much-garlic-as-a-people.scm.azurewebsites.net
/api/vfs/site/wwwroot/ill-grab-this-file-over-vfs-api.txt
There, i did it.
I'm assuming here that you want to do all that from the outside world - since you don't clearly state otherwise.

Well, in my azure code. my task was to save a excel file and upload its contents to SQL server.
I used this plain and simple to access home site.
string fileToSave = string.Format("{0}\\{1}", HostingEnvironment.MapPath(#"~\Temp"), FileUpload.FileName);
if (!Directory.Exists(HostingEnvironment.MapPath(#"~\Temp")))
Directory.CreateDirectory(HostingEnvironment.MapPath(#"~\Temp"));
FileUpload.PostedFile.SaveAs(fileToSave);
you could use something like this to delete and save a new file or other I/O operations.

Related

Using Realm Sync with Azure Functions

I'm trying to use Realm Cloud in an Azure Function but it keeps giving me an error:
make_dir() failed: Permission denied Path: /realm-object-server/
Is there a way to configure Azure Functions to have permissions to create files? I'm new to Azure Functions, this is my first one so I'm not really sure of all the particulars.
I have found one solution to this. Inside Azure function, you can only create any file or folder inside the temp folder. So if you use following sync configuration, it should work. It worked for me.
var configuration = new FullSyncConfiguration(new Uri("/~/<your-realm-name>", UriKind.Relative), _realmUser, Path.Combine(Path.GetTempPath(), "realm-object-server"));
So basically, here you are passing the folder name to store the realm locally. If you don't pass the folder name, it will try to store it in a default location where you will get the access error.
I am not familiar with Realm, but functions has permissions to interact with the file system by default. See these links for information on the app service file system (this applies for functions too):
https://learn.microsoft.com/en-us/azure/app-service/operating-system-functionality#file-access
https://github.com/projectkudu/kudu/wiki/Understanding-the-Azure-App-Service-file-system
If the function is deployed using run from package, then the wwwroot is readonly. But since the path in the error message doesn't point to wwwroot, this is probably not the issue.
My best guess is that the code that is failing is trying to write to in an inappropriate location. The information in the links above should help resolve that. Maybe check to see if realm has a config setting that lets you specify which location it should be creating "realm-object-server" in.
You can use
SyncConfigurationBase.Initialize(UserPersistenceMode.NotEncrypted, basePath: Path.GetTempPath());

URL to access private blob in Azure Storage

We're just getting started with Azure Storage.
In our scenario we upload to private blobs that we later need to access directly from our client app, e.g. images.
Is there a way to address private blobs in Azure Storage with a URL containing the access key?
Sifting through the MS docs all I could find so far is simple URL access via the blob URI, e.g. as given by the URI property of the CloudBlockBlob instance when listing blobs via the .net API.
Naturally accessing this from a web browser fails due to the blob not being public.
However, can we qualify the URL to also include the access key in order to allow authorized clients to access the blob..?
You can generate an SAS URL and token for the private blob. Here's the process for generating this manually in the Azure portal, to test the concept. It will work even if your storage container is private, as it allows temporary, time limited access to the file using a URL that contains a token in it's query string.
Click on your file within the storage container, select the 'Generate SAS' tab, and in the right pane select
This will generate a token, and a URL that includes the token, like below:
You can test downloading the URL as a file by using curl. Use the 2nd URL shown in the image above (the one that includes the full token and other parameters in the querystring), then do this (IMPORTANT - the URL must be in double quotes):
curl "<YOUR_URL>" --output myFileName.txt
Tip - this is also a good method for making files available to an Azure VM, if you need to install a file directly on the VM for any reason (I needed to do this to install an SSL certificate), you can generate the URL then curl to download the file, on the VM itself. E.g. connect to the VM first with Bastion or SSH, then use curl to download the file somewhere.
This is the API for how you read blobs from storage:
https://learn.microsoft.com/en-us/rest/api/storageservices/get-blob
There is no URL-Parameter to pass the access key, only the header value Authorization. So you could do the request manually and e.g. add the resulting data as a base64 encoded image. I would advise against it if at all possible.
You must also be aware that by passing your access key to the client, you are effectively making your blob public anyways. You would be putting your data at more risk than anonymous access, since the access key allows more operations than anonymous access. This would also hold true for your objective-c app, even though its much more obfuscated there. SAS is the way to go there - create a backend service that creates a defined set of SAS tokens for given resources. It is however much more effort than simply obfuscating the full access key somewhere.
See "Features available to anonymous users":
https://learn.microsoft.com/en-us/azure/storage/blobs/storage-manage-access-to-resources

Retrieve files from cloud public folder

We are creating c# console beta version app for our clients in which they just paste the public folder/file URL of Google drive OR one drive OR drop box OR etc. And in back-end we need to retrieve the file and process it...
I just wanted to know how do we retrieve those cloud files without any prompts for authentication(as given URL will b public, so it should not ask for Id pw)
Any help from you all experts?
With OneDrive, you can use the "shares" API to retrieve a sharing link without authentication.
You just need to encode the sharing URL correctly and then pass that to the API endpoint. The details of encoding are on the page above, but it's just URL safe base64 encoding.
GET https://api.onedrive.com/shares/{encoded_sharing_url}/root/content
The API will return the content of the file.
Edit: I got the URL slightly wrong. The /shares/ API returns a "sharing root" which looks somewhat like a drive object. To access the actual shared file, you need to add /root before the /content part of the path. I've updated this above.

How to create usable URL for opening document?

The general problem: I have some code that needs a URL to a PDF file. It seems to work for URLs I find online, but not the ones I create myself.
For example, when I use a random URL from Xamarin it works fine, but when I try to generate a URL from either DropBox or Amazon Cloud Drive it does not work.
Example URLs:
These links open harmless PDF files. Please try it:
Xamarin (works fine)
DropBox (does not work)
Amazon Cloud Drive (does not work)
As you see, in a browser (I have used Chrome to test) you will get the PDF documents to open, but not without some kind of context (except for the Xamarin one).
The code: I am developing in MonoTouch and I am using a component called mTouch PDF Reader. The code is simply:
var documentViewController = new DocumentViewController (1, "Some name here", "http://someurlhere.pdf");
ActivateController (documentViewController);
This opens a nice PDF reader inside my app, but, as I can't use my own created URLs this does not help me. This is a 3rd party library so I can't look at the code. By the way, when I use one of my URLs, the code crashes with a System.NullReferenceException with this stacktrace:
MonoTouch.Foundation.NSArray.FromNativeObjects (items={MonoTouch.UIKit.UIViewController[1]}, count=1) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:109
MonoTouch.Foundation.NSArray.FromNativeObjects (items={MonoTouch.UIKit.UIViewController[1]}) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:96
MonoTouch.Foundation.NSArray.FromNSObjects (items={MonoTouch.UIKit.UIViewController[1]}) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:48
MonoTouch.UIKit.UIPageViewController.SetViewControllers (viewControllers={MonoTouch.UIKit.UIViewController[1]}, direction=MonoTouch.UIKit.UIPageViewControllerNavigationDirection.Forward, animated=false, completionHandler={MonoTouch.UIKit.UICompletionHandler}) in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIPageViewController.g.cs:144
mTouchPDFReader.Library.Views.Core.DocumentViewController.ViewDidLoad () in
MonoTouch.UIKit.UIApplication.UIApplicationMain () in
MonoTouch.UIKit.UIApplication.Main (args={string[0]}, principalClassName=(null), delegateClassName="AppDelegate") in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
Exam936.Application.Main (args={string[0]}) in /Users/EdGriMac/Dropbox/Quiz/Code/Exam926/Exam936/Main.cs:16
The frustration:
Is there a specific way to create URLs that work in this way? It does seem like DropBox does something different as it sort of iFrames the document or something. I don't know what Amazon Cloud Drive does. What has Xamarin done? Is it, as pointed out in the comments, because of http vs https?
I am completely lost. Am I missing something simple? Do you have any other way to create URLs to suggest? Googling this is really difficult as I continue to hit examples of how to share a URL in DropBox and so on...
By the way, I do not want to have the documents as part of the app as this means I will have to create a new version of the app just to change something in a document.
Update 1: I have added links above. I will try some other suggestions later and will leave more updates. Thanks in advance for any further suggestions!
Update 2: I have used Fiddler to look at the response on each of the URLs. The Xamarin URL has Content-Type: application/pdf while both DropBox and Amazon Cloud Drive has Content-Type: text/html; charset=UTF-8. This explains a lot. I will try andersr's suggestion later today as I do have a web server to put files on.
Update 3 When I put the PDF file on my Amazon EC2 server, created a virtual directory under my web site in IIS, the URL to my website + virtual directory + filename worked! Turns out the Content-Type had to be application/pdf for the mTouch PDF Reader to open it through a URL.
Thanks everyone for your help!
It seems to me that the first two URLS, link directly to the PDF files, but the latter one, ie. the one on Amazon Cloud Drive links to a page which again links to the PDF. I suggest the following potential solutions:
Find a reliable way to extract the direct url to the document on cloud drive. The link to the document is not the one you provided, but this: link . Perhaps Amazon has documentation on how you can avoid the html interface in order to retrive your file. I am not familiar with cloud drive at all. Note that the url provided has some time limited token attached to it.
Host the document on infrastructure you have more control over. IE. setup your own web server and host the documents there. Alternatively use another cloud storage provider which gives you the ability to link to files directly.

IIS Virtual Folder URL encryption

We have a c# asp.net web application that, amongst other things, allows users to download previously uploaded files such as PDF's, Word docs etc. The asp.net app is served up via an IIS6 server and the file resources live on a different server.
When the user requests a file (i.e. click a button on the web form), we stream the file back to their browser, changing the ContentType appropriately.
This seemed a good way to avoid going down the IIS virtual folder route to serve up the file resources - which we had concerns about due to the potential for users to hack the URL. i.e. with a URL like https://mydomain/myresource/clientid/myreport.docx, a savvy user could have a good stab at guessing alternative cvlientid's and document names.
The trouble with streaming a Word document to the browser is that when the browser throws it at Word, Word treats it as a brand new doc, which means the original document's properties & margin info is lost.
Our users store metadata information in the Word doc properties, so this solution is not acceptable to them.
Serving up via IIS virtual folders solves that problem, but introduces the URL security problem.
So my questions are ...
Does anyone know how we can use URL encryption/decryption (or obfuscation) with IIS Virtual folders?
Or does anyone know of any open source projects that do a similar job.
Or does anyone have any sugestions on how to go about writing our own implementation of Virtual folders but with encrypted URLs?
Many thanks in advance.
ps. our web app is delivered over https
Sorry guys, in my question, I have made some incorrect assumptions.
What am I trying to do is persist the properties stored on a word document when they are delivered from server (using either Response.TransmitFile or via a virtual folder) to a client browser.
I set up a test scenario with an IIS virtual folder and dropped a docx file (that I know contains info in the title & subject properties) in my virtual folder's physical path.
I pointed my browser at the virtual folder alias and the browser popped up its message to either open or save the doc.
If I choose to save it, the saved docx still has the properties intact.
If I choose to open it fist and then save it from Word, the saved docx has lost the properties.
So I think I need to post a different question!
You may find that the ClaimsAuthorizationManager class in "Windows Identity Foundation" does what you want. You get to implement whatever logic you like to determine who can download what without using "directory security".

Categories

Resources