Google Docs API - Impersonate User File Download - google-docs

Using the Google Docs Java API with a Google Apps account, is it possible to impersonate a user and download a file?
When I run the program below, it is clearly logging on to the domain and impersonating the user because it retrieves the details of one of the files and prints out the file title. However, when it tries to download the file, a ServiceForbiddenException is thrown.
If it is not possible with the Java API, does anyone know if it is possible for my program to write an HTTP request to download the file using the Protocol API?
public class AuthExample {
private static DocsService docService = new DocsService("Auth Example");
public static void main(String[] args)
throws Exception
{
String adminUser = args[0];
String adminPassword = args[1];
String authToken = args[2];
String impersonatedUser = args[3];
loginToDomain(adminUser, adminPassword, authToken);
URL url = new URL( "https://docs.google.com/feeds/" + impersonatedUser + "/private/full" );
DocumentListFeed feed = docService.getFeed(url, DocumentListFeed.class);
DocumentListEntry entry = feed.getEntries().get(0);
String title = entry.getTitle().getPlainText();
System.out.println( title );
String type = entry.getType();
if ( type.equals("document") )
{
String encodedAdminUser = URLEncoder.encode(adminUser);
String resourceId = entry.getResourceId();
String resourceIdNoPrefix = resourceId.substring( resourceId.indexOf(':')+1 );
String downloadUrl =
"https://docs.google.com/feeds/download/documents/Export" +
"?xoauth_requestor=" + encodedAdminUser +
"&docId=" + resourceIdNoPrefix +
"&exportFormat=doc";
downloadFile( downloadUrl, title + ".doc" );
}
}
private static void loginToDomain(String adminUser, String adminPassword, String authToken)
throws OAuthException, AuthenticationException
{
String domain = adminUser.substring( adminUser.indexOf('#')+1 );
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(domain);
oauthParameters.setOAuthConsumerSecret(authToken);
oauthParameters.setOAuthType(OAuthType.TWO_LEGGED_OAUTH);
oauthParameters.setScope("https://docs.google.com/feeds/ http://spreadsheets.google.com/feeds/ http://docs.googleusercontent.com/");
docService.useSsl();
docService.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
docService.setUserCredentials(adminUser, adminPassword);
}
// Method pasted directly from Google documentation
public static void downloadFile(String exportUrl, String filepath)
throws IOException, MalformedURLException, ServiceException
{
System.out.println("Exporting document from: " + exportUrl);
MediaContent mc = new MediaContent();
mc.setUri(exportUrl);
MediaSource ms = docService.getMedia(mc);
InputStream inStream = null;
FileOutputStream outStream = null;
try {
inStream = ms.getInputStream();
outStream = new FileOutputStream(filepath);
int c;
while ((c = inStream.read()) != -1) {
outStream.write(c);
}
} finally {
if (inStream != null) {
inStream.close();
}
if (outStream != null) {
outStream.flush();
outStream.close();
}
}
}
}

Impersonation will work as intended if you use Oauth2 with ServiceAccounts

Related

Download sharepoint webpart programmatically

We are migrating webparts programmatically.
We used this code in the past but it is not working with modern authentication.
Can you share piece of code for doing this when legacyauth is turned off?
private string DownloadFile(string url)
{
SecureString theSecureString = new NetworkCredential("", _password).SecurePassword;
SharePointOnlineCredentials onlineCredentials = new
SharePointOnlineCredentials(_username, theSecureString);
_authCookieValue = onlineCredentials.GetAuthenticationCookie(new Uri(fileUrl));
using (CookieAwareWebClient client = new CookieAwareWebClient())
{
client.CookieContainer = new CookieContainer();
client.CookieContainer.Add(new Cookie("SPOIDCRL",
_authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()), String.Empty, authority));
string localPath = Path.GetTempPath();
string temporaryGuid = Guid.NewGuid().ToString();
string path = System.IO.Path.Combine(localPath, temporaryGuid);
client.DownloadFile(fileUrl, path);
document = System.IO.File.ReadAllText(path);
System.IO.File.Delete(path);
}
}
etc...
}
We were calling it this way:
string itemWebPartDefUrl = string.Format(
"{0}{1}/_vti_bin/exportwp.aspx?pageurl={2}&guidstring={3}",
_rootPrefixURL,
webServerRelativeUrl,
pageURL,
wpDef.Id.ToString().ToLower()
);
Uri targetSite = new Uri(_context.Web.Url);
string xmlDef = DownloadFile(itemWebPartDefUrl, targetSite.Authority);

Authentication Failed for get file using file service REST API Azure

I am trying to get a file using the shared key. I already get a list of files and directories by the shared key, but when I request to receive a specific file, I encounter this problem.
Code to generate shared key:
using System;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace StorageRestApiAuth
{
internal static class AzureStorageAuthenticationHelper
{
internal static AuthenticationHeaderValue GetAuthorizationHeader(
string storageAccountName, string storageAccountKey, DateTime now,
HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "")
{
// This is the raw representation of the message signature.
HttpMethod method = httpRequestMessage.Method;
String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
method.ToString(),
(method == HttpMethod.Get || method == HttpMethod.Head) ? String.Empty
: httpRequestMessage.Content.Headers.ContentLength.ToString(),
ifMatch,
GetCanonicalizedHeaders(httpRequestMessage),
GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
md5);
byte[] SignatureBytes = Encoding.UTF8.GetBytes(MessageSignature);
HMACSHA256 SHA256 = new HMACSHA256(Convert.FromBase64String(storageAccountKey));
string signature = Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
returned.
AuthenticationHeaderValue authHV = new AuthenticationHeaderValue("SharedKey",
storageAccountName + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes)));
return authHV;
}
private static string GetCanonicalizedHeaders(HttpRequestMessage httpRequestMessage)
{
var headers = from kvp in httpRequestMessage.Headers
where kvp.Key.StartsWith("x-ms-", StringComparison.OrdinalIgnoreCase)
orderby kvp.Key
select new { Key = kvp.Key.ToLowerInvariant(), kvp.Value };
StringBuilder sb = new StringBuilder();
foreach (var kvp in headers)
{
StringBuilder headerBuilder = new StringBuilder(kvp.Key);
char separator = ':';
foreach (string headerValues in kvp.Value)
{
string trimmedValue = headerValues.TrimStart().Replace("\r\n", String.Empty);
headerBuilder.Append(separator).Append(trimmedValue);
separator = ',';
}
sb.Append(headerBuilder.ToString()).Append("\n");
}
return sb.ToString();
}
private static string GetCanonicalizedResource(Uri address, string storageAccountName)
{
StringBuilder sb = new StringBuilder("/").Append(storageAccountName).Append(address.AbsolutePath);
NameValueCollection values = HttpUtility.ParseQueryString(address.Query);
foreach (var item in values.AllKeys.OrderBy(k => k))
{
sb.Append('\n').Append(item).Append(':').Append(values[item]);
}
return sb.ToString().ToLower();
}
}
}
With this code I can get a list of directories and files, but I can’t get a specific file.
I'm use this url to request: https://myaccount.file.core.windows.net/myshare/mydirectorypath/myfile
Error sending request:
{
"Error": {
"Code": "AuthenticationFailed",
"Message": "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:4c9ca5be-301a-0045-29c9-f20135000000\nTime:2020-03-05T08:36:05.9908405Z",
"AuthenticationErrorDetail": "The MAC signature found in the HTTP request 'here is my key' is not the same as any computed signature. Server used following string to sign: 'GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Thu, 05 Mar 2020 08:36:05 GMT\nx-ms-version:2017-04-17\n/my storage account/my share/myfile.JPG'."
}
}
I test in my site with your code and it works well. With your AzureStorageAuthenticationHelper and here it the following code that I get file content.
static void Main(string[] args)
{
GetFileContentAsyncREST("youraccount", "yourkey", CancellationToken.None).GetAwaiter().GetResult();
Console.WriteLine("Press any key to continue.");
Console.ReadLine();
}
private static async Task GetFileContentAsyncREST(string storageAccountName, string storageAccountKey, CancellationToken cancellationToken)
{
string uri = "https://xxxxx.file.core.windows.net/helloworld/directory/helloworld.txt";
Byte[] requestPayload = null;
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri)
{
Content = (requestPayload == null) ? null : new ByteArrayContent(requestPayload) })
{
DateTime now = DateTime.UtcNow;
httpRequestMessage.Headers.Add("x-ms-date", now.ToString("R", CultureInfo.InvariantCulture));
httpRequestMessage.Headers.Add("x-ms-version", "2017-04-17");
httpRequestMessage.Headers.Authorization = AzureStorageAuthenticationHelper.GetAuthorizationHeader(
storageAccountName, storageAccountKey, now, httpRequestMessage);
using (HttpResponseMessage httpResponseMessage = await new HttpClient().SendAsync(httpRequestMessage, cancellationToken))
{
if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
{
string content = await httpResponseMessage.Content.ReadAsStringAsync();
Console.Write(content);
}
}
}
}
}
For more details, you could refer to this storage rest api with auth sample.

enrollment error in using microsoft azure api during speaker enrollment

I am trying to use MS Azure Speaker recognition API (java) as per https://westus.dev.cognitive.microsoft.com/docs/services/563309b6778daf02acc0a508/operations/5645c3271984551c84ec6797 . I am able to get a identificationProfileId. The error occues when I try to enroll. Here is how I am enrolling
- get a wav file of the enrollment audio
- convert to base64 (thru online service)
- attach the base64 it as content to the call for enrollment along with identificationProfileId. I am doubtful about the b64 part
I am getting "Invalid Audio Format: Not a WAVE file - no RIFF header"
I am aware that the service needs the audio in PCM encoding as per doc.
Can someone pls let me know how to convert a wav audio to the required format that can be passed to the enrollment REST endpoint.
public class azureApiTest
{
public static String getID()
{
HttpClient httpclient = HttpClients.createDefault();
String ret = null;
try
{
URIBuilder builder = new URIBuilder("https://westus.api.cognitive.microsoft.com/spid/v1.0/identificationProfiles");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/json");
request.setHeader("Ocp-Apim-Subscription-Key", "fad541725xxxxxxx3362125790411");
// Request body
JsonObject locale = new JsonObject();
locale.addProperty("locale", "en-us");
StringEntity reqEntity = new StringEntity(locale.toString());
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
JsonParser parser = new JsonParser();
JsonObject o = parser.parse(EntityUtils.toString(entity)).getAsJsonObject();
ret = o.get("identificationProfileId").getAsString();
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
finally
{
return ret;
}
}
public static void main(String[] args)
{
HttpClient httpclient = HttpClients.createDefault();
try
{
String id = azureApiTest.getID();
System.out.println("ID created = "+id);
String enrollURL = "https://westus.api.cognitive.microsoft.com/spid/v1.0/identificationProfiles/" +id + "/enroll";
System.out.println("enrollURL = "+enrollURL);
URIBuilder builder = new URIBuilder(enrollURL);
builder.setParameter("shortAudio", "true");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "multipart/form-data");
request.setHeader("Ocp-Apim-Subscription-Key", "fad5417xxxxxxx3362125790411");
// Request body
File voiceb64 = new File("/Users/premnair/Desktop/vp/voice1b64.txt");
String data = FileUtils.readFileToString(voiceb64, "utf-8");
StringEntity reqEntity = new StringEntity(data);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
If I pass the file like in the snippet below it works !
File file = new File("/Users/jdoe/Desktop/vp/v5.wav");
request.setEntity( new FileEntity(file, ContentType.APPLICATION_OCTET_STREAM) );
Don't use base 64, just raw byte array data will work.

How to create azure VM with Rest Api

Here is the code, but it prompts error:
The image o3lceiy3.ioa201305211013360129.vhd does not exist.
the subscriptionId and X509Certificate2 are valid
internal class Program
{
public static X509Certificate2 Certificate { get; set; }
private static void Main(string[] args)
{
const string subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
//#"https://management.core.windows.net/<subscription-id>/services/hostedservices/<cloudservice-name>/deployments";
var url = string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments",
subscriptionId, "edoc2cloudtest");
var myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Method = "POST";
myReq.Headers.Add("x-ms-version", "2012-03-01");
myReq.Proxy = null;
myReq.Timeout = 30000;
myReq.ContentType = "application/xml";
var postData = ReadConfig();
using (var reqStream = myReq.GetRequestStream())
{
var data = Encoding.UTF8.GetBytes(postData);
reqStream.Write(data, 0, data.Length);
reqStream.Flush();
}
Certificate = GetX509Certificate();
myReq.ClientCertificates.Add(Certificate);
try
{
var myRes = (HttpWebResponse) myReq.GetResponse();
}
catch (WebException exWeb)
{
// Parse the web response.
Stream responseStream = exWeb.Response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
XmlDocument xDocResp = new XmlDocument();
xDocResp.Load(reader);
HttpWebResponse responseStatus = (HttpWebResponse)exWeb.Response;
responseStream.Close();
reader.Close();
var result = NiceFormatXml(xDocResp);
Console.WriteLine(result);
}
}
private static string NiceFormatXml(XmlDocument xDoc)
{
StringBuilder niceString = new StringBuilder();
StringWriter strWriter = new StringWriter(niceString);
XmlTextWriter xmlWriter = new XmlTextWriter(strWriter);
xmlWriter.Formatting = Formatting.Indented;
xDoc.WriteTo(xmlWriter);
xmlWriter.Close();
strWriter.Close();
return niceString.ToString();
}
private static X509Certificate2 GetX509Certificate()
{
X509Certificate2 certificate2 = null;
var store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
var collection = store.Certificates;
var fcollection = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
const string certificateThumbprint = "‎‎‎‎7dfbc7369306ed096b7e5c7b4ba6e99f190240e9";
store.Close();
if (fcollection.Count > 0)
{
foreach (var variable in fcollection)
{
if (variable.Thumbprint != null &&
variable.Thumbprint.Equals(certificateThumbprint, StringComparison.InvariantCultureIgnoreCase))
{
certificate2 = variable;
}
}
}
return certificate2;
}
private static string ReadConfig()
{
string path = System.AppDomain.CurrentDomain.BaseDirectory + "Edoc2Cloud.xml";
//string path = System.AppDomain.CurrentDomain.BaseDirectory + "VM-CreateVM.xml";
string s;
using (var sr = new StreamReader(path, Encoding.GetEncoding("GB2312")))
{
s = sr.ReadToEnd();
}
return s;
}
}
Here is the XML:
<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>EDoc2Test</Name>
<DeploymentSlot>Staging</DeploymentSlot>
<Label>EDoc2Testlabe</Label>
<RoleList>
<Role>
<RoleName>EDoc2TestRoleName</RoleName>
<RoleType>PersistentVMRole</RoleType>
<ConfigurationSets>
<ConfigurationSet>
<ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType>
<ComputerName>computer-name</ComputerName>
<AdminPassword>APasswor_324d</AdminPassword>
<EnableAutomaticUpdates>true</EnableAutomaticUpdates>
</ConfigurationSet>
</ConfigurationSets>
<AvailabilitySetName>EDoc2TestSetName</AvailabilitySetName>
<OSVirtualHardDisk>
<HostCaching>ReadWrite</HostCaching>
<DiskName>SomeName-0-20121007173943</DiskName>
<MediaLink>http://portalvhdsx4flx9dhmjyt1.blob.core.windows.net/vhds/o3lceiy3.ioa201305211013360129.vhd</MediaLink>
<SourceImageName>o3lceiy3.ioa201305211013360129.vhd</SourceImageName>
</OSVirtualHardDisk>
<RoleSize>Medium</RoleSize>
</Role>
Based on the error you're receiving and the XML you've specified, can you please check if there is an image by the name o3lceiy3.ioa201305211013360129.vhd in your custom images? You could find that information by logging into the portal and going to Virtual Machines --> Images.
Documentation regarding <SourceImageName> parameter states that it is needed when you want to create a virtual machine either by using system or custom images.
You can read the complete documentation here: http://msdn.microsoft.com/en-us/library/windowsazure/jj157186.aspx#OSVirtualHardDisk.

Error: Couldnt connect with Foursquare webservice

I tried to connect to the Foursquare webservice to parse look for some locations, but my program couldn't connect with Foursquare webservice. Here is my code:
public class GetLocation
{
public static void main (String [] args ) throws IOException
{
//Set up for output locations in a .txt file
String fileNameOut = "locations.txt" ;
FileOutputStream fos = new FileOutputStream( fileNameOut );
PrintStream ps = new PrintStream(fos);
String client_id = "Y2LZCJTR4LJBXZOXAB3F22VOLAV3GXRS5TSXRXXXXXXXXXXX";
String client_secret = "PJY2QM4CLZITAUMGOQCM2QYTOKATTCH3VXXXXXXXXXXX";
double latitude = 33.823712;
double longtitude = -117.958931;
String restaurantName = "Cafe Casse Croute";
String V = "20121205";
String API_URL = "http://api.foursquare.com/v2/venues/search?ll=";
String queryStatement = latitude+","+longtitude+"&match="+restaurantName;
try {
String url = (API_URL+queryStatement+"&client_id="+client_id+"&client_secret="+client_secret + "&v="+V);
URL url = new URL(sURL);
URLConnection httpc = url.openConnection();
//HttpURLConnection httpc = (HttpURLConnection) url.openConnection();
httpc.setDoInput(true);
httpc.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(httpc.getInputStream()));
String inputLine = "";
String content="";
while ((inputLine = in.readLine()) != null){
content=content+inputLine;
}
in.close();
return content;
} catch (Exception e) {
return ("Exception: " + e.getMessage());
}
}
}
I also try to use URLConnection httpc = (URLConnection) url.openConnection();
but it does not connect to the FoureSquare Service.
Is there other way to connect to the FoureSquare Service ?

Resources