How to upload/download a file with Microsoft graph API in Unity3d - c#

I was able to make a oauth 2 login with Unity3d on Microsoft graph, I requested this permission for my app:
https://graph.microsoft.com/files.readwrite.appfolder
After the usual code flow (redirect to url, permission from user, auth code exchanged for token code and token for bearer auth code) I was able to log in.
Problem is that the upload of small files does not work:
https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content
I think this is the best I can do:
string myData = File.ReadAllText(Application.persistentDataPath + "/" + "provaupload.json");
using (UnityWebRequest www = UnityWebRequest.Post("https://graph.microsoft.com/v1.0/me/drive/root:/AppTry/provaupload.json:/createUploadSession", myData)) {
www.SetRequestHeader("Authorization", "Bearer <code>");
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError) {
Debug.Log(www.error + " " + www.downloadHandler.text);
} else {
Debug.Log("Upload complete! " + www.downloadHandler.text);
}
}
and I get this error:
Generic/unknown HTTP error {
"error": {
"code": "BadRequest",
"message": "Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.",
"innerError": {
"request-id": "id",
"date": "2018-07-20T06:24:30"
}
}
I also tried the WWW class or Put instead of Post but I get "invalid API".
Maybe my problem is in the base url:
https://graph.microsoft.com/v1.0/me
or maybe it's in the path
root:/AppTry/provaupload.json
or maybe in the permission.
I don't really know.
If you know how to make a Rest call with Microsoft Graph and One drive (even not in unity3d and even if you don't know how to solve my specific problem) it would be great to get some example.

To upload file, use the UploadHandler. You must also encode the string as UTF8. As you mentioned in the comment section, it looks like you have to use PUT instead of POST and the url should be changed to something else.
Something more like this:
string myData = File.ReadAllText(Application.persistentDataPath + "/" + "provaupload.json");
string url = "https://graph.microsoft.com/v1.0/me/drive/root:/AppTry/provaupload.json:/content";
using (UnityWebRequest www = new UnityWebRequest(url, "PUT"))
{
byte[] dataToSend = new System.Text.UTF8Encoding().GetBytes(myData);
www.uploadHandler = (UploadHandler)new UploadHandlerRaw(dataToSend);
www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
www.SetRequestHeader("Authorization", "Bearer <code>");
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error + " " + www.downloadHandler.text);
}
else
{
Debug.Log("Upload complete! " + www.downloadHandler.text);
}
}

Related

How can I login with OAuth2.0 in DevOps API in C#?

I tried many API Calls with Postman and It works fine but I only get it to work with PAT.
Below you can find my API Call with my PAT. How can I change it to OAuth2.0?
By the way, I'm using the DataVerse API with OAuth2.0 but rewrite doesnt work.
EDIT:
I used the OAuthWebSample but there is another Error:
When I click on "Authorize" it says "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."
What I need to do to get it to work is to copy the website-url given in the publish section in visual studio and switch it.
So I got PUBLISHEDNAME.azurewebsites.net instead of APPNAME.azurewebsites.net
When I'm switching the CallbackUrl in web.config to PUBLISHEDNAME.azurewebsites.net I'll get a 400.
How can I fix it?
private const string URL = "DEV LINK";
string testToken = "PAT";
public TextMesh APIText;
public TextMeshProUGUI Text;
// Start is called before the first frame update
void Start()
{
}
public void GenerateDevOps()
{
StartCoroutine(ProcessDevOps(URL));
}
public IEnumerator ProcessDevOps(string uri)
{
using (UnityWebRequest request = UnityWebRequest.Get(uri))
{
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Authorization", "Basic" + " " + testToken);
yield return request.SendWebRequest();
if (request.isNetworkError)
{
Debug.Log(request.error);
}
else
{
Debug.Log(request.downloadHandler.text);
Text.text = request.downloadHandler.text;
/* var data = JsonConvert.DeserializeObject<Root>(request.downloadHandler.text);
var dataInhalt = data.value.ToArray();
Debug.Log(dataInhalt);
foreach (Value content in dataInhalt)
{
string name = content.firstname;
string lastname = content.lastname;
//textapi.text = name + " " + lastname;
names = names + name + lastname + Environment.NewLine;
}
APIHeader.text = URL;
m_Object.text = names;
*/
}
}
}
The 404 error code means that the resource doesn't exist, or the authenticated user doesn't have permission to see that it exists. So here are two troubleshooting advices:
Check your REST API using PAT to see whether the error is about the API.
Configure OAuth 2.0 exactly as this document. In particular, make sure you have configured permissions correctly, which means that you can use the access token to read data and send it back.

unityWebRequest form post to node.js

I am trying to send login data to server from unity through node.js and node.js will return id of login user. but post does not work. C# Code
form.AddField("usernamePost" , username);
form.AddField("passwordPost" , password);
print(username + " " + inputPassword);
UnityWebRequest www = UnityWebRequest.Post(LoginURL,form);
yield return www.SendWebRequest();
//spinner.Dismiss();
string value= www.downloadHandler.text;
And this is nodejs code
app.use('/ownerLogin', (req,res) =>{
let username=req.query.ownerIdPost;
let userPassword=req.query.passwordPost;
console.log(username);
console.log(userPassword);
I have tried
req.param
req.params
req.body
It gives empty and undefined I also change request method to
app.get('/ownerLogin', (req,res) =>{.....
and
app.post('/ownerLogin', (req,res) =>{....
But nothing worked for me . Kindly help me
It worked on me using
NodeJS:
app.post(`/letlogin`, (req, res) => {
console.log(req.body.username);
});
Unity:
WWWForm formData = new WWWForm () ;
formData.AddField("username", "Barodar");
UnityWebRequest www = UnityWebRequest.Post("http://localhost:3001/letlogin/", formData);
yield return www.SendWebRequest();

Firebase REST API - authenticating request with id token doesn't work

I'm working on a Unity C# project and trying to authenticate a request to Realtime Database using the id token Firebase returns after a user signs in, but it says the request is unauthorized. Here's my sign-in code (AuthResponse wraps the response body):
WWWForm form = new WWWForm();
form.AddField("email", email);
form.AddField("password", password);
using (UnityWebRequest www = UnityWebRequest.Post("https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" + API_KEY, form))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log($"Login failed: {www.error}");
callback(false);
}
else
{
AuthResponse data = www.downloadHandler.text.FromJson<AuthResponse>();
ID_TOKEN = data.idToken;
}
}
And my read request:
string url = $"{DATABASE_URL}{path}.json";
if (auth) url += $"?auth={ID_TOKEN}";
using (UnityWebRequest www = UnityWebRequest.Get(url))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log($"Read failed: {www.error}");
}
}
My database has public rules and everything works without the auth parameter. What am I missing?
Edit: This is the token response:
{
"kind": "identitytoolkit#SignInWithPasswordResponse",
"localId": <LOCAL_ID>,
"email": <EMAIL>,
"displayName": "",
"idToken": <ID_TOKEN>,
"registered": true
}
This is the full read request url: https://<PROJECT_ID>.firebaseio.com/testing/flatString.json?auth=<ID_TOKEN>
instead of doing your own httppost use Firebase Unity SDK
Before you can use Firebase Authentication, you need to:
Register your Unity project and configure it to use Firebase.
If your Unity project already uses Firebase, then it's already registered and configured for Firebase.
If you don't have a Unity project, you can download a sample app.
Add the Firebase Unity SDK (specifically, FirebaseAuth.unitypackage) to your Unity project.

Unable to get authorization code with Unity and OAuth2.0

I'm working in an Unity app that needs to connect to a Microsoft Dynamics 365 which uses OAuth2.0. I was trying using UnityWebRequest to retrieve an access token by calling:
https://login.microsoftonline.com/[TENANT_ID]/oauth2/v2.0/token
using something similar to this thread:
OAuth2 Authentication and Operations in Unity
And it works, I'm able to get and access_token, however, when I try to consume the service with the Bearer token, I always get "401 unauthorized".
I then tried to call instead:
https://login.microsoftonline.com/[TENANT_ID]/oauth2/v2.0/authorize
But when I do that, the response is the actual HTML code of the Microsoft login screen. As far I know, getting an auth code requires a user interaction right? but I've been able to get this done by using Microsoft.IdentityModel.Clients.ActiveDirectory package from NuGet in a console C# app without user interaction, so there must be a way right?
I would really appreciate your help on this! thank you!
UPDATE 1 - My code
Get access token
private IEnumerator GetAccessToken(Action<string> result)
{
Dictionary<string, string> content = new Dictionary<string, string>();
//Fill key and value
content.Add("scope", "https://graph.microsoft.com/.default");
content.Add("grant_type", "client_credentials");
content.Add("client_id", "xxxxx");
content.Add("client_secret", "xxxx");
UnityWebRequest www = UnityWebRequest.Post("https://login.microsoftonline.com/[TENANTID]/oauth2/v2.0/token", content);
//Send request
yield return www.Send();
if (!www.isError)
{
string resultContent = www.downloadHandler.text;
TokenClassName json = JsonUtility.FromJson<TokenClassName>(resultContent);
//Return result
result(json.access_token);
}
else
{
//Return null
result("");
}
}
Call API
private IEnumerator GetData(Action<string> result)
{
Dictionary<string, string> content = new Dictionary<string, string>();
//Fill key and value
content.Add("CustomerGroupId", "10");
UnityWebRequest www = UnityWebRequest.Post("https://[ENVIRONMENT].cloudax.dynamics.com/data/TestEntity", content);
string token = null;
yield return GetAccessToken((tokenResult) => { token = tokenResult; });
result(token);
www.SetRequestHeader("Authorization", "Bearer " + token);
www.Send();
if (!www.isError)
{
string resultContent = www.downloadHandler.text;
// Perform additional operations...
}
}
The resource is different for the token and the API call. In the token request, the resource is https://graph.microsoft.com, it's not your destination API. You should request the token for your destination API.

Exception when downloading Asset Bundle on Android

I'm getting the following exception when I build my game for android
WWW download had an error: java.lang.IllegalArgumentException: uri ==
null
Now I haven o idea why this is happening because it works fine in the editor. Here is the relevant code :
assetLoader.BundleURL = "ftp://user:pass#81.161.248.122/Unity-Uri/AssetBundles/seasonalcontent/christmas";
assetLoader.version = 1;
assetLoader.StartDownload();
and the actual download code :
IEnumerator DownloadAndCache()
{
// Wait for the Caching system to be ready
while (!Caching.ready)
yield return null;
// Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
using (WWW www = WWW.LoadFromCacheOrDownload(BundleURL, version))
{
yield return www;
if (www.error != null)
throw new Exception("WWW download had an error:" + www.error);
AssetBundle bundle = www.assetBundle;
SeasonManager.assets = bundle.LoadAllAssets();
Debug.Log("Stop");
OnContentLoaded();
} // memory is freed from the web stream (www.Dispose() gets called implicitly)
}
Edit: I got this from the documentation : ftp:// protocol support is limited to anonymous downloads only. Is ftp not supported on android ?
Edit 2: As suggest in the comments I tried this and it results in a Login failed error :
IEnumerator makeRequest()
{
string authorization = authenticate("username", "pass");
string url = "ftp://ipgoeshere";
UnityWebRequest www = UnityWebRequest.Get(url);
www.SetRequestHeader("AUTHORIZATION", authorization);
yield return www.Send();
if (www.isError)
{
Debug.Log(www.error);
}
else
{
AssetBundle bundle = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle;
SeasonManager.assets = bundle.LoadAllAssets();
}
}
string authenticate(string username, string password)
{
string auth = username + ":" + password;
auth = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
auth = "Basic " + auth;
return auth;
}
To clarify I've made sure that the username password and the server address are correct. I have simply removed them from the code here for obvious reasons.

Categories

Resources