How can I upload files to Office365 SharePoint with Perl? - perl

Can someone please advise on uploading files to Office365 SharePoint?
I believe this should be done using the DAV protocol, so HTTP::DAV should be right library for that, but how to code it to make it work with Office365? Each account hosted with Office365 has a TeamSite website, which hopefully can be accessible with DAV. Please advise.

Upload large documents to SharePoint site using WebClient class gives an example of using DAV to upload a document.
WebClient oWebClient = new WebClient();
oWebClient.UseDefaultCredentials = true;
byte[] bFile = System.IO.File.ReadAllBytes(#"C:\Sundar\WEB315.wmv");
string ulr = #"http://lt010593/Shared Documents/WEB315.wmv";
System.Uri oUri = new System.Uri(ulr);
oWebClient.UploadDataAsync(oUri, "PUT", bFile);
oWebClient.UploadDataCompleted += new UploadDataCompletedEventHandler(oWebClient_UploadDataCompleted);
With that example in mind, the task is to look at WebClient documentation to figure out what oWebClient.UseDefaultCredentials = true; really does.
Set this property to true when requests made by this WebClient object should, if requested by the server, be authenticated using the default credentials of the currently logged on user. For client applications, this is the desired behavior in most scenarios. For middle tier applications, such as ASP.NET applications, instead of using this property, you would typically set the Credentials property to the credentials of the client on whose behalf the request is made.
So, it seems, the task is to figure out what credential information is sent. The rest seems to be a simple PUT request.

Related

Pass Windows Credentials to a RESTful Web API using Windows.Web.Http.HttpClient

I know this question was asked time and again, here and here. The answers given are pretty much the same, but in my case I still miss something and I cannot figure out exactly what it is. I have a RESTful Web API deployed and that is configured to accept only domain-authenticated calls. So on my client side, in my UWP application, I used the HttpClient class from the Windows.Web.Http namespace. The resources found online all show that I need to do two things:
Enable Enterprise Authentication in the package manifest of my UWP app. I did that. Here is a screen shot of the capabilities selected for my app:
Set the "AllowUI" flag to be false, so that the user is not prompted to enter its credentials. I did that too. Here is a code snippet of what I am doing:
Uri uri = new Uri(_myUriRoute);
var filter = new HttpBaseProtocolFilter { AllowUI = false };
var httpClient = new HttpClient(filter);
HttpResponseMessage response = await httpClient.GetAsync(uri);
With this code in place, I don't get prompted for the credentials, but the response.IsSuccessStatusCode flag comes back as false and the error that I get is 401 - Unauthorized.
Before you ask, yes, the server-side endpoint is properly configured and works fine. If I try this:
Uri uri = new Uri(_myUriRoute);
var filter = new HttpBaseProtocolFilter();
var httpClient = new HttpClient(filter);
HttpResponseMessage response = await httpClient.GetAsync(uri);
I am asked for my credentials and when I enter them correctly, I get a proper HTTP 200 code in response. I also tried this:
Uri uri = new Uri(_myUriRoute);
var filter = new HttpBaseProtocolFilter
{
AllowUI = false,
ServerCredential = new PasswordCredential(_myUriRoute, _myUserName, _myPassword)
};
var httpClient = new HttpClient(filter);
HttpResponseMessage response = await httpClient.GetAsync(uri);
and again, I get a nice HTTP 200.
So what am I missing? I don't want to be prompted and I don't want to store credentials either. I want to have Windows pass automatically the credentials of the current user of the app.
Two things worth mentioning. The above-described behavior happens in my development environment (Visual Studio 2017) while I try debugging/running my app using the "Local Machine" option. Also, the first thing that happens when I start the app is I am prompted to grant permissions to the app to access the pictures folder and account info:
This happens despite the fact that I have selected "User Account Information" among the Capabilities set for the application, as can be seen in the above screen shot of the Capabilities tab, in the application's package manifest.
Any idea of what is missing? Any idea of what else should be tried?
Any suggestion will be highly appreciated.
Cheers,
Eddie
PS: I posted the same question on the MSDN Forums as well
PS2: The Web API is running in IIS Express, started from Visual Studio 2017, in a different instance. I configured IIS Express to expose my Web API using the IP address of my development machine instead of the "localhost". In its web.config file, I have the following setting:
<system.web>
<authentication mode="Windows"/>
</system.web>
I post this, just in case the issue is on the Server side, which I think it isn't.

WPF talking to secured web api using AutoRest

I just can't seem to get anywhere with this.
I have a web api running fine, with a wpf application using the api via AutoRest.
The api has been uploaded to Azure (App Services)
I now want to lock down the api, so users log in via Active Directory. Again, all users are currently there.
RestCredentials = new TokenCredentials(tokenAuthResult.AccessToken);
Using the RestCredentials I pass in the credentials as type
ServiceClientCredentials
using (var db = new BuxtedAPI(Model.Helpers.Credentials.RestCredentials))
{
var res = db.GetComboList();
ComboValueList = new ObservableCollection<ComboValue>(res);
return ComboValueList;
}
I can see on the log in Azure that the user successfully logs in.
But the system just dies with
Operation returned an invalid status code 'InternalServerError'
No more feedback at all.
Just to note, I am using swagger also here.
I am assuming that the BuxtedAPI call that passing the credentials should pass through the bearer token for the api call to authorise.
I have set nothing else on on webapi code base, no [AUTHORIZED] or anything.
Any chance anyone can help me along here.
Thanks Scott
If anyone else gets in this situation.
The process required Resource Id to be the web app and the clientid to be the native app id.
Scott

How to use new enhanced sessions in Parse with users created on cloud code?

I was trying out the new enhanced revocable sessions in Parse on my Android app. It works well when logging in or signing up via email password or facebook but doesn't work well for custom authentication, e.g. google+.
I'm currently logging in the user using the cloud code which also creates the new user when signing up. This does not create a new Session object, that means the new enhanced sessions are not used and it still uses the legacy sessions.
I pass the session token back to client where using the become method the user logs in but it's the legacy sessions.
This feels like the feature is not complete but I would really like to move to the new enhanced sessions with my app. Has anyone worked with them yet? Are there any workarounds using the REST API or by creating the sessions manually and handling them manually? I looked into the JS API but it says it's only read only.
Here's the Blog post on Enhanced Sessions.
Where should I go next?
Yes, I found a solution but it's a workaround, works for my case because I don't support signing up with user/password.
Basically, the solution (cloud code) in semi pseudo-code is:
Fetch the user with master key
Check if user.getSessionToken() has value
if it has, return the session token and do a user.become() in the client as usual
if it's not, here the workaround, do the following:
yourPreviousPromiseInOrderToChainThem.then(function(user)
password = new Buffer(24);
_.times(24, function(i) {
password.set(i, _.random(0, 255));
});
password = password.toString('base64')
user.setPassword(password);
return user.save();
}).then(function(user) {
return Parse.User.logIn(user.get('username'), password)
}).then(function(user) {
var sessionToken = user.getSessionToken();
// Return the session token to the client as you've been doing with legacy sessions
})
That means, I'm changing the user password each time in order to make a remote login and, of course, I know thist can't be applied to all cases, it's enough for app because I don't support login with user/password (only third party logins) but I understand that maybe it's not for all cases.
I got the idea from this official Parse example.
I don't like this solution because I think is not a workaround, it's a mega hack but I think there is no other way to do it currently (either Parse.com or Parse-Server)
If you find other workaround, please, share it :)

Google Data/OAuth/AppEngine/Python - Properly Registering a Web Application

I'm creating a webapp with this combination of tools. I'm authenticating with App Engine in the following manner:
class googleLogin(webapp.RequestHandler):
def get(self):
callbackURL = 'http://%s/googleLoginCallback' % getHost()
#Create a client service
gdClient = gdata.docs.service.DocsService()
gdata.alt.appengine.run_on_appengine(gdClient)
gdClient.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.HMAC_SHA1,
_GoogleConsumerKey,
consumer_secret=_GoogleConsumerSecret)
#Get a Request Token
requestToken = gdClient.FetchOAuthRequestToken(scopes=_GoogleDataScope,
extra_parameters={'xoauth_displayname': APP_NAME})
#Persist token secret
self.session = Session()
self.session[TOKENSECRETKEY] = requestToken.secret
gdClient.auto_set_current_token = True
gdClient.SetOAuthToken(requestToken)
authUrl = gdClient.GenerateOAuthAuthorizationURL(callback_url=callbackURL)
self.redirect(authUrl)
I authenticated my domain with Google at https://www.google.com/accounts/ManageDomain, entering a target URL and am using the given Consumer Key/Secret. For instance, if my domain was 'juno.appspot.com', I am using http://juno.appspot.com as the target url path prefix.
The process is working; however, Google presents this message to the user in a yellow security box:
"The application that directed you
here claims to be 'xxxxxx'. We are
unable to verify this claim as the
application runs on your computer, as
opposed to a website. We recommend
that you deny access unless you trust
the application."
I don't think I should be getting this error, since my server is getting the request token and creating the authorization URL. Does anyone have any insight on how to get rid of this warning?
Google's domain registration has an option to upload a certificate, but I shouldn't need to do that because I'm using OAuth with the HMAC_SHA1 signature method.
Also, not that it should matter, but I'm doing all this through a UIWebView on the iPhone. I'm specifically trying to do all authentication server-side to avoid exposing my Consumer Key/Secret.
Thank you for any tips :)
Solved.
The culprit is this line from above:
extra_parameters={'xoauth_displayname': APP_NAME})
Setting this value for a registered application intentionally triggers a warning to users, as indicated by the Google documentation:
xoauth_displayname:
(optional) String identifying the
application. This string is displayed
to end users on Google's authorization
confirmation page. For registered
applications, the value of this
parameter overrides the name set
during registration and also triggers
a message to the user that the
identity can't be verified. For
unregistered applications, this
parameter enables them to specify an
application name, In the case of
unregistered applications, if this
parameter is not set, Google
identifies the application using the
URL value of oauth_callback; if
neither parameter is set, Google uses
the string "anonymous".
Removing this line no longer allows me to use a 'nice' name in place of the domain, but it gets rid of that annoying yellow box :)
I'm not sure exactly where the issue may be in your code, but I've got a one page oauth/appengine/gdata example which may at least set you in the right direction. Have you tried to navigate to the site directly from the iPhone/desktop browser to see what message is delivered?
Hope it helps.
Alternatively, is it possibly to do with the user agent the UIWebView sets?

How to check SharePoint document permissions?

I have a custom web service deployed in SharePoint, web method of this webservice expects a SharePoint docuentUri as a parameter. As it is deployed in the SharePoint environment i am done with SharePoint authentication, but the question here is that how do i check whether the user reqesting for a perticular document is authroized or not ? In other words web service method should return some unauthorized exception if the user does not have privilege to view the document ? All i have is the SharePoint documentUri to pass as an inpurt parameter.
thanks.
Assuming your web service is deployed in the context of SharePoint in the /_vti_bin virtual directory of your SharePoint site, you can use the SharePoint object model like below to check if the calling user has specific privileges to your document. Unfortunately, the CheckPermissions call will throw an UnauthorizedException if the check fails, so it would have to be caught.
string uri = "http://localhost/Shared%20Documents/Document1.doc"; //full path to doc
using (Microsoft.SharePoint.SPSite site = new Microsoft.SharePoint.SPSite(uri))
using (Microsoft.SharePoint.SPWeb web = site.OpenWeb())
{
Microsoft.SharePoint.SPListItem item = web.GetListItem(uri);
item.CheckPermissions(Microsoft.SharePoint.SPBasePermissions.OpenItems);
}
Hope this helps,
Steve