Updating Skills property of User through MS Graph API fails - azure-active-directory

I'm trying to update the "Skills" property of a user (note: NOT using the Me endpoint). This returns an exception. I'm using the .NET SDK GraphServiceClient to do so, using the latest 3.6.0 version.
To Reproduce
Steps to reproduce the behavior, use the following sample code:
var user = new User()
{
Skills = skills
};
await graphClient.Users[userId].Request().UpdateAsync(user);
Expected behavior
I'd expect this code to send a POST request to the Graph API endpoint and that request should update the Skills property of the given used, provided that the authenticated service has been granted the User.ReadWrite.All permission in Azure AD (which it has).
Instead, the following error is being returned by the Graph endpoint:
"error": {
"code": "-1, Microsoft.SharePoint.Client.InvalidClientQueryException",
"message": "A type named 'Microsoft.SharePoint.user' could not be resolved by the model. When a model is available, each type name must resolve to a valid type.",
"innerError": {
"request-id": "1948a4ec-60fd-4212-873f-3d34f62f5601",
"date": "2020-05-25T09:35:33"
}
}
}
Not sure why this would not work. I followed the samples although those do not specifically mention updating the Skills property, you'd expect that to work equally for all properties. When I omit the property from the updated User object, I do not get an error in return (but obviously there's nothing updated in that case).

Till it is fixed in v1 as mentioned by baywet you can also use the following as work around for your scenario.
Graph client by default adds odata.type as microsoft.graph.user and sharepoint doesn't expect that value. You could change the oDataType to "https://graph.microsoft.com/v1.0/$metadata#users/$entity" or "Microsoft.SharePoint.user" or null, so that sharepoint can understand the type.
You can set the oDatatype by
var user = new User()
{
Skills = skills
};
user.ODataType = "https://graph.microsoft.com/v1.0/$metadata#users/$entity";
await graphClient.Users[userId].Request().UpdateAsync(user);

This is an ongoing issue that is being addressed in the service. The beta version should already be fixed and the v1 is in progress.
As a workaround you can either use the beta version or craft the request manually without an odata type.

Related

Error using '/directoryObjects/validateProperties' API: Invalid entity type provided

When using the directoryObjects/validateProperties API for creating/validating AD Group properties, a 400 error is returned indicating 'Invalid entity provided. Supported entities include: Group'. I have confirmed that the only entityType I am providing in the request is 'Group' or 'group'.
{ code: 'Request_BadRequest',
message:
'Invalid entity type provided. Supported entities include: Group.',
innerError:
{ 'request-id': '4949163f-43c4-42e8-b016-436af61e4eb5',
date: '2020-06-11T10:29:08' } } }
The error occurs in both /v1.0 and /beta versions of the MS Azure AD API, with the body/payload stringified or not.
Not exactly sure what is expected. Can someone please provide assistance on this? Thanks.
I have validated the properties by using the same JSON Data from the document in the Graph explorer and it worked for me.
This is the below data which I have given
{
"entityType": "Group",
"displayName": "Myprefix_test_mysuffix",
"mailNickname": "Myprefix_test_mysuffix",
"onBehalfOfUserId": "1ab4e79f-5f52-44b8-8c72-7d03c05e6ff4"
}
And I am hitting the V1.0 endpoint
https://graph.microsoft.com/v1.0/directoryObjects/validateProperties
Try with my sample copying it change the onBehalfOfUserID to your userID and hit the same Http call in Graph Explorer.

How to update the users birthday

I want to update the birthday of a user using the patch request.
Updating other properties works as expected but the moment the birthday property is included, the following error returned:
The request is currently not supported on the targeted entity set
I already tried to update the user to be sure the permissions are fine.
Application permissions are used.
This PATCH request to /V1.0/users/{id} works:
{
"givenName": "Fridas"
}
Passing this request body however:
{
"givenName":"Fridas",
"birthday" : "2014-01-01T00:00:00Z
}
throws an error
{
"error":
{
"code":"BadRequest",
"message":"The request is currently not supported on the targeted entity set",
"innerError":
{
"request-id":"5f0d36d1-0bff-437b-9dc8-5579a7ec6e72",
"date":"2019-08-13T15:27:40"
}
}
}
When I update the birthday separately, I get a 500 error. Print screens below. Updating the user id works fine, birthday does not.
Same user id is used in the request.
I'm not sure why this happens, but a workaround, albeit an annoying one, is to update birthday separately from other attributes.
E.g.
PATCH https://graph.microsoft.com/v1.0/users/userid
{
"birthday" : "2014-01-01T00:00:00Z"
}
Here is a screenshot from MS Graph Explorer:
In fact, this is a limitation in the current system.
User is a composite type. Under the covers some properties in user are mastered by different services, and we currently don't support updates across multiple services.
"birthday" is not mastered by Azure AD. So we can't update it with other properties mastered by Azure AD in the same call.
It is strongly recommended that you update this property separately. I can update it from my side. So you need a backend engineer to track this request for you.
This seems to affect more than Birthday.
Skills[] and Responsibilities[] are also returning 500 Internal Server Error when using PATCH request via REST API with:
{"skills": ["TESTING", "ANOTHER SKILL"]}
Same happens via the GraphServiceClient - except the result is:
Failed to call the Web Api: InternalServerError
Content: {
"error": {"code": "-1, Microsoft.Office.Server.Directory.DirectoryObjectUnauthorizedAccessException",
"message": "Attempted to perform an unauthorized operation.",
"innerError": {
"request-id": "1c2ccc54-0a0c-468f-a18c-6bdfbad4077d",
"date": "2019-08-28T13:23:55"
}}}
These requests work on the Graph Explorer page, but not via calls to the API.

Google PubSub not working to create a new topic

i'm using the v1-master branch of the PHP API Client library from here:
https://github.com/google/google-api-php-client/blob/v1-master/src/Google/Service/Pubsub.php
i'm sure i have all the OAuth stuff right, so assume the $client is already created correctly... also {my-app-id} is replaced with my real application id
$pubsub = new Google_Service_Pubsub($client);
$new_topic = new Google_Service_Pubsub_Topic();
$new_topic->setName('projects/{my-app-id}/topics/mytopic');
$topic = $pubsub->topics->create($new_topic);
this throws an exception:
exception: Google_Service_Exception Object
(
[errors:protected] => Array
(
[0] => Array
(
[domain] => global
[reason] => invalidArgument
[message] => Invalid resource name given (name=projects/{my-app-id}/topics/mytopic). Refer to https://cloud.google.com/pubsub/overview#names for more information.
)
)
{my-app-id} is just letters a-z, so it is valid and meets all the criteria on the pubsub overview, and i do have rights to the project because if i change the {my-app-id} value, i get a permission denied message.
i've also gone through the API Explorer and got similar broken results:
REQUEST:
PUT https://pubsub.googleapis.com/v1/projects/{my-app-id}/topics/mytopic?key={YOUR_API_KEY}
{
}
RESPONSE:
404 OK
- Show headers -
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND"
}
}
i've also tried using the master branch of the API client and changing the endpoints to the pubsub.googleapis.com/v1 endpoints rather than www.googleapis.com/pubsub/v1beta1... i even tried v1beta2. nothing is working.
the PubSub API is enabled for my project, but i can't get any topics created.
does anyone have any PHP sample code of a working app to use the PubSub service? any ideas what i'm doing wrong?
If the API Explorer is also not working, that would indicate that the project id you are specifying in place of {my-app-id} is not correct. It should be a project that has already been created. Visit https://console.developers.google.com/home/dashboard?project={my-app-id} and ensure that you get a dashboard for your project. If not, then that would confirm that the project id is incorrect.

How do I use the Google API Explorer to test my own App Engine Endpoints using OAuth?

I have an Endpoints API deployed on App Engine. I have no problem using the Google API Explorer to make requests to API methods that do NOT require being logged in. The URL I'm using for that is:
https://developers.google.com/apis-explorer/?base=https://[MY_APP_ID].appspot.com/_ah/api
Where I am stuck is calling API methods that require the user to be logged in, such as this one:
#ApiMethod(name = "config.get",
clientIds = {"[MY_CLIENT_ID].apps.googleusercontent.com", "com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID"},
audiences = {"[MY_APP_ID].appspot.com"},
scopes = {"https://www.googleapis.com/auth/userinfo.email"})
public Config getConfig(User user) throws OAuthRequestException {
log.fine("user: " + user);
if (user == null) {
throw new OAuthRequestException("You must be logged in in order to get config.");
}
if (!userService.isUserAdmin()) {
throw new OAuthRequestException("You must be an App Engine admin in order to get config.");
}
...
On the API Explorer there's a switch top right that, when clicked, allows me to specify scopes and authorise. I'm doing that with just the userinfo.email scope checked. It makes no difference. The response I get from my call is:
503 Service Unavailable
- Show headers -
{
"error": {
"errors": [
{
"domain": "global",
"reason": "backendError",
"message": "java.lang.IllegalStateException: The current user is not logged in."
}
],
"code": 503,
"message": "java.lang.IllegalStateException: The current user is not logged in."
}
}
Back when Endpoints was in Trusted Tester phase, I remember there being a manual step in the OAuth2 Playground to get an ID token instead of an access token or some such thing. If that is still required, any mention of that seems to have disappeared from the Endpoints docs now and I see now way to swap out tokens in the API Explorer either.
I see you've got "com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID" in quotes. If that's not a typo in your transcription to Stack Overflow, that's a problem. The value is already a string, so you're just passing in the text com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID (not the actual client ID) as the whitelisted scope. That won't work. Try this instead:
#ApiMethod(name = "config.get",
clientIds = {"[MY_CLIENT_ID].apps.googleusercontent.com", com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID},
audiences = {"[MY_APP_ID].appspot.com"},
scopes = {"https://www.googleapis.com/auth/userinfo.email"})
Edit: isUserAdmin is unsupported within Endpoints, and is likely a secondary cause of error. I'd suggest filing a feature request for supporting this method on the provided User object (we likely won't provide support for the user service itself, so it's separate from OAuth login.)
I don't know when this was introduced, but if you use OAuth2, instead of UserService.isUserAdmin() you can use OAuthServiceFactory.getOAuthService().isUserAdmin(EMAIL_SCOPE) where EMAIL_SCOPE is "https://www.googleapis.com/auth/userinfo.email".
This makes it easy to use the old OpenId or OAUth2:
boolean isAdmin = false;
try {
isAdmin = userService.isUserAdmin());
} catch (IllegalStateException e1) {
try {
isAdmin = OAuthServiceFactory.getOAuthService().isUserAdmin(EMAIL_SCOPE);
} catch (Exception e2) {}
}
The original question was asked several years ago, but maybe this will help others.

ACAccount Facebook: An active access token must be used to query information about the current user

I am using iOS 6 Social framework for accessing user's Facebook data. I am trying to get likes of the current user within my app using ACAccount and SLRequest. I have a valid Facebook account reference of type ACAccount named facebook, and I'm trying to get user's likes this way:
SLRequest *req = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:url parameters:nil];
req.account = facebook;
[req performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
//my handler code.
}
where url is #"https://graph.facebook.com/me/likes?fields=name"; In my handler, I'm getting this response:
{
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
}
Shouldn't access tokens be handled by the framework? I've found a similar post Querying Facebook user data through new iOS6 social framework but it doesn't make sense to hard-code an access token parameter into the URL, as logically the access token/login checking should be handled automatically by the framework. In all examples that I've seen around no one plays with an access token manually:
http://damir.me/posts/facebook-authentication-in-ios-6
iOS 6 Facebook posting procedure ends up with "remote_app_id does not match stored id" error
etc.
I am using the iOS6-only approach with the built in Social framework, and I'm not using the Facebook SDK. Am I missing something?
Thanks,
Can.
You need to keep a strong reference to the ACAccountStore that the account comes from. If the store gets deallocated, it looks like it causes this problem.
Try running on an actual device instead of a simulator. This worked for me.
Ensure that your bundle id is input into your Facebook app's configuration. You might have a different bundle id for your dev/debug build.

Resources