Creating a New User in Azure DevOps using Rest API - azure-devops

I am trying to create a new user in Azure DevOps using Rest API C# and by debugging the code I am not seeing any error and the user information were showing correct after I get result of the created new user. My issue is that the user is NOT saved after the application is completed and I do not see the user in Azure DevOps. When I check the status of the task it is WaitingForActivation.
Here is the code I am using and please advise what is wrong:
VssConnection connection = new VssConnection(new Uri(uri), new VssBasicCredential(string.Empty, personalAccessToken));
GraphHttpClient graphClient = connection.GetClient<GraphHttpClient>();
GraphUserMailAddressCreationContext usr = new GraphUserMailAddressCreationContext();
usr.MailAddress = "someuser#somedomain.com";
GraphUser u = graphClient.CreateUserAsync(usr).Result;

Creating a New User in Azure DevOps using Rest API
According to your code segment, it seems you are adding a user via Graph. But add a user via Graph does not give them access to the account, the user has to be materialized and added to the appropriate projects, groups etc.
To add a user, I suggest you can use another API User Entitlements - Update User Entitlement with following request body:
[
{"from":"",
"op":0,
"path":"/projectEntitlements",
"value":{"projectRef":{"id":"<MyProjectID>"},"group":{"groupType":3}}
}
]
You can check my another thread for some more details.
Hope this helps.

Related

How to interact with html response from http request in Flutter

I have a Flutter app where I am running a Google Apps Script through an http request. The purpose of the script is to create a Form and link the responses to a spreadsheetID that is passed in. The script is configured to only allow Google accounts access it and I've set up the flutter app to use a Service Account to access the script using the format:
getCredentials().then( (AuthClient client){
response = client.get(url, headers{"Authorization": "Bearer ${client.access_token}");
});
Issue: The issue is that the first time that the Service Account makes a request it will get an HTML response saying that it the account needs to give permission to the script to access its data and I'm not sure how to do that.
I'm fairly new to making http requests and using it with the GoogleAPI so I'm stuck. Any advice?
Goal
Create a web page which anyone can use to submit a Google sheet link and for the app to create a form and link the sheet to that.
Authorization
For this users will require a google account and they will be required to go through the OAuth process to authorize your app.
To create the form and link it from client-side JavaScript you would indeed need to call the Apps Script API, though you cannot do this with a service account.
From: https://developers.google.com/apps-script/api/how-tos/execute
Warning: The Apps Script API doesn't work with service accounts.
Luckily, you don't need a service account to do this.
Instructions
Create an Apps Script project with a function something like:
function createForm(ssID){
form = FormApp.create("Your New Form");
form.setDestination(FormApp.DestinationType.SPREADSHEET, ssID);
let formLink = form.getPublishedUrl();
return formLink;
}
Save and take a note of the ID of the script project.
Set up a GCP project (sounds like you already have one).
Make sure the Apps Script API is enabled in your GCP.
Configure the OAuth consent screen and add the scope - https://www.googleapis.com/auth/forms.
Create an API key and a Client ID - add http://localhost:8000 or whatever port you are testing on to the "Authorized JavaScript Origins"
Create OAuth credentials "web browser (JavaScript)".
Link your Apps Script project to the same GCP project - Instructions
Deploy the Apps Script project as an API executable - take not of the deployment ID, although the documentation says that you need the script ID, it is wrong, at least with the new Apps Script IDE.
Write the client-side JavaScript in your app like what is found in the quickstart. Which will enable users to authorize the app. You need to add in the scopes and keys there too. I recommend just following the quick start steps first to get a feel for it. You can use the authorization parts without modification.
Then add in the function that will call your Apps Script, something like this:
function appsScriptCreateForm(ssId) {
var scriptId = "<DEPLOYMENT_ID>";
// Run your Apps Script function
gapi.client.script.scripts
.run({
scriptId: scriptId,
resource: {
function: "createForm",
parameters: [ssId],
},
})
.then(function (resp) {
var result = resp.result;
// ERROR HANDLING
if (result.error && result.error.status) {
appendPre("Error calling API:");
appendPre(JSON.stringify(result, null, 2));
} else if (result.error) {
var error = result.error.details[0];
appendPre("Script error message: " + error.errorMessage);
if (error.scriptStackTraceElements) {
appendPre("Script error stacktrace:");
for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
var trace = error.scriptStackTraceElements[i];
appendPre("\t" + trace.function + ":" + trace.lineNumber);
}
}
// IF SUCCESSFUL
} else {
console.log("success", resp);
}
});
}
Write your HTML with the buttons and inputs necessary.
Add event listeners where appropriate.
Profit!
Please note
This set up is your project running with the authorization of other accounts.
The API requests count against your quota.
You can see details of all the executions in your GCP Project Dashboard.
Users require a Google account and need to authorize the app.
In the Apps Script function above, you just need to pass in the Spreadsheet ID. Not the whole link. You could ask for the whole link and then use Regex to extract the ID if you wanted.
This can be quite tricky and easy to miss a step or make a mistake, so double check your work.
If, after successful authorization, when trying to run the script you get a 404 error, the request has been built wrong, check your IDs. If you get a 500 error, that can mean that the Apps Script function has successfully been called, but, there was an error within Apps Script and failed, check the executions page of the Apps Script editor.
References
Apps Script How to Execute
Apps Script JS Quickstart - Highly recommended you follow these steps first and get that working!
How to link your Apps Script to GCP

Running Google Apps Script through https request with Service Account credentials

I'm working on a Flutter app. And I've been trying to run my web-app Google Apps Script through http request since I'm required to use a Service Account and that access isn't supported in the Apps Script API. But I keep getting a 403/Forbidden response to the requests. I have the credentials for the Service Account and I am using its access token in my request but it still doesn't work.
I'm a novice at http requests and new to Google's authentication protocols so I'd appreciate some insight.
Thanks in advance.
Code:
return await driveUtils.getCreds(context).then((creds) async {
final drive_scopes = [drive.DriveApi.DriveReadonlyScope, "https://www.googleapis.com/auth/drive.file"];
final script_scopes = [app_scripts.ScriptApi.ScriptDeploymentsScope];
return await clientViaServiceAccount(creds, script_scopes+drive_scopes).then((AuthClient client) async {
debugPrint("url = " + url);
debugPrint("token = " + client.credentials.accessToken.data);
return await client.get(url,
headers: {
"Authorization": "Bearer ${client.credentials.accessToken.data}"
}
);
}, onError: onClientError);
}, onError: onCredsError);
Background: The script creates a Form and sets it Destination to a Spreadsheet's ID. Hence, the app requires that anyone who runs it to have a Google account to become the owner of the new Form and obtain access to the Sheet.
Update: It seems that Service Accounts can only access scripts that are within the same Google Cloud Project. This is a big issue since the point of the script is to create a central place for acquiring Form creation functionality for my app. And the app is intended to be used by anyone.
Does anyone have any ideas? Assuming a Service Account is the right Google Credentials for my app, I essentially need the ability to:
Create a Form that can be assigned to a user
Designate a user's spreadsheet as the forms response location
Retrieve the forms publishedURL
#Tanaike helped me figure out the issue. In order to make the script visible and able to run with a Service Account I had to change the Share setting for viewing the script. Simple solution

How to set hireDate property of guest user as soon as invitation is sent via Azure AD B2B api?

I am trying to invite guest user in my Office 365 tenant using Azure AD B2B api and the intent is to set hireDate property of the guest user as soon as invitation is sent. For me its not necessary that guest should redeem the invitation.
The problem is, code fails (with error message: Unable to check user existence in AD) when I am trying to patch user to update hireDate property irrespective of guest redeem the invitation or not. The problem does not occur if i wait for a minute or so after sending the invitation and then try to patch the user. How can I set this property without waiting?
To resolve this, i already tried implementing retry logic but this is not reliable.
var token = extranetHelper.GetAuthToken(); //Custom class to get token
var guestEmail = "abc#abc.com";
var siteURL = "https://tenant.sharepoint.com/sites/abc";
var displayName = "";
Invitation guestInvitation =
GraphUtility.InviteGuestUser(token.AccessToken, guestEmail, siteURL, "", displayName);
var guestUserId = guestInvitation.InvitedUser.Id;
var graphUrl = "https://graph.microsoft.com/beta/users/" + guestUserId;
var body = "{\"hireDate\" : \"" + DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ") + "\"}";
var response = GraphHttpClient.MakePatchRequestForString(graphUrl, JsonConvert.DeserializeObject(body), "application/json", token.AccessToken);
hireDate property should be set for the newly created guest user in Azure AD.
To my knowledge there currently is no way to avoid this delay since it can sometimes take 30 minutes to an hour for the state to change.
Since Graph API currently cannot check for this, we can use the the Azure AD reporting API to check the this status. We can get the Update user event and check the UserState to see if it is invited to achieve the goal. For more details about the Azure AD reporting API, you can this link.
You can leave feedback for Azure to cut back on this delay here.

From where get subscription key for api.ai chatbot to be deployed on Microsoft Cortana

I'm trying to build a chatbot using api.ai. I want to integrate this bot with Microsoft Cortana. I followed every step given at this link: https://docs.api.ai/docs/cortana-integration but then to initialize api.ai instance, I have written following code. Client access token is available to me. My question here is from where to get the subscription key?
var config = new AIConfiguration("String subscription key",
"String client_access_token",
SupportedLanguage.English);
apiAi = new ApiAi(config);
apiAi.DataService.PersistSessionId();
Are you sure about the code that you have because at the URL mentioned : https://docs.api.ai/docs/cortana-integration, the code is something like this:
var config = new AIConfiguration("YOUR_CLIENT_ACCESS_TOKEN", SupportedLanguage.English);
So, all you will need is just the Client Access Token, which is available from the Agent Settings page in API.AI

Trying to update a Facebook event using the Graph API (Facebook C# SDK)

I am trying to update the description of a Facebook event using the Facebook C# SDK. I have granted the following permission to my application:
'publish_stream,email,manage_pages,user_events,create_event,rsvp_event'
The event I am trying to update is one of my own events, so I believe I should be able to update it.
In the code below "9999" is the event id of the event I created, and the event I am trying to amend:
Authorizer authorizer = new Authorizer();
FacebookClient fbapp = new FacebookClient(authorizer.Session.AccessToken);
Console.Write(fbapp.Get("9999"));
dynamic parameters = new ExpandoObject();
parameters.description = "the new description";
fbapp.Post("9999", parameters);
The fbapp.Get works fine and returns the details of the event.
The problem is with the Post method, this returns (OAuthException) (#200) Permissions error
Any ideas as to where I am going wrong?
This issue is in fact a bug in the Facebook Graph API, see here for the bug report
It appears to be the case that you can only use the Graph API to edit events created by your app, and not existing events created by users within Facebook.
Hopefully it will be fixed soon!
If you really have all permissions, I think you should include every mandatory field in the parameters (as I haven't done this, I can only guess!) and not only the field you wish to edit.
Hope this has helped you Andrew.