Retrieving authenticated users email - desire2learn

I have two questions both relating the the User data sets.
1.
Is UniqueName in WhoAmI the same value as UserName in UserData
User.WhoAmIUser
{
"Identifier": "<string:D2LID>",
"FirstName": "<string>",
"LastName": "<string>",
"UniqueName": "<string>",
"ProfileIdentifier": "<string:D2LID>"
}
User.UserData
{
"OrgId": "<number:D2LID>",
"UserId": "<number:D2LID>",
"FirstName": "<string>",
"MiddleName": "<string>",
"LastName": "<string>",
"UserName": "<string>",
"ExternalEmail": "<string>",
"OrgDefinedId": "<string>",
"UniqueIdentifier": "<string>",
"Activation": "{composite:User.UserActivationData}"
}
2.
How can I retrieve the current authenticated users email address? I've tried to connect to various Users API's but all return "Not Authorized". Even the "/d2l/api/lp/(D2LVERSION: version)/users/(D2LID: userId)" with my userId authorized as myself throws Not Authorized.
I have tried both with Student and Instructor Roles. I can retrieve the WhoAmI service, just not any other User services.
Thanks.

1) The UniqueName property in the User.WhoAmIUser structure will (should) present the same value as the UserName property in User.UserData: this is the user's "log in name" within the LMS. In the back-end service, these two properties might be maintained separately, but for all intents and purposes, to the calling client, they should contain the same value (in that if you change the UserName value in a user record through the web UI, and then make a WhoAmI call, you'll see that change show up in the UniqueName property in the WhoAmI results).
2) Retrieving a user's email address may not be a simple feat: the ExternalEmail property in the UserData record should contain the same value that appears in the Email field in the user record in the Web UI. This is the email address that the LMS will use if it needs to send password-reset messages to a user.
This property is subject to User Information Privacy role-permissions, and some organizations may choose to tightly restrict who can see that value.
Additionally, the /d2l/api/lp/{ver}/users/ route itself is often subject to restrictive role permissions with some organizations. In general, if you're making a call with a user role that would have access to the functionality of the Users tool in the LMS' web UI, that role should also be able to have access to this API route.
If you do not have permission to use that API call (and you may not), then you can't use it to look for user details.
The User.User and Enrollment.ClasslistUser structures also contain a property to house that Email value from the user record, and if you can make a call to retrieve those structures (enrollment API calls, for example, or the classlist API call), then you might have access to the email value there, contingent on the User Information Privacy permissions the calling user has in place.
The upshot of all this is that many users at many organizations won't have the permission to retrieve their own external email address from their own user record, as they may not have permission to make the calls that would retrieve it, and it's not contained in the WhoAmIUser structure.

Related

Create calendar Permissions in Microsoft graph API not removable by end users

We would like to create calendar permissions on all users calendar in organization which allow a service (user mailbox) to read/write on users calendars.
There is no problem to do that by using Microsoft Graph endpoint : Create calendarPermission
But we would like this permission was not removable by end users. That's why we tried to use isRemovable property set to true. For example :
POST https://graph.microsoft.com/v1.0/users/UPN_OF_USER/calendar/calendarPermissions
Request Body
{
"emailAddress": {
"name": "VALID_USER_NAME",
"address": "VALID_USER_EMAIL_IN_TENANT#TENANT_DOMAIN"
},
"isInsideOrganization": true,
"isRemovable": false,
"role": "read"
}
But each time we add this permission, isRemovable property is set to true.
It doesn't seems isRemovable property is readonly in documentation
I tested the API in my environment and it came up with the same result. I tested couple of Scenarios and found that isInsideOrganization is decided by the My Organization user and isRemovable is default set to true for all users as they can be removed/deleted from the Sharee and Delegate list except for My Organization User as its the deciding authority of which permissions are assigned to what user.
It is also mentioned in calendar permission resource type Microsoft Documentation as shown below :
Scenarios:
Create a Permission for User inside the Organization by providing the two parameters and not providing the parameters as well:
With Parameters:
Without Parameters:
Create a Permission for User present outside the Organization by providing the two parameters and not providing the parameters as
well:
With Parameters:
Without Parameters:
Note : IsRemovable is set to false only for My Organization User as can be seen below:

User unique identity in microsoft graph api

I'm using the next endpoint for getting
"https://graph.microsoft.com/v1.0/users/?$select=id, displayName, mail, userPrincipalName"
According to docs:
https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0
there is no any info about unique mail property for user resource type.
mail String The SMTP address for the user, for example, "jeff#contoso.onmicrosoft.com". Supports $filter.
Question: is it possible to get two or more users (with different ids) and the same mail property?
The User mail property should be unique.
You will get the following error message when you try to create a new user with the same mail property.
"error": {
"code": "Request_BadRequest",
"message": "Another object with the same value for property proxyAddresses already exists.",

Create SharePoint list item with lookup field with Microsoft Graph

I am trying to create list items with Microsoft Graph's new SharePoint endpoint. My URL is as follows:
https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items
Calling this URL with POST, and a body like this:
{
"fields": {
"Title": "test",
}
}
.. works! But if I include a lookup field, the lookup field is always empty. I have tried with
"{columnName}": "id",
"{columnName}": "id;#value",
"{columnName}": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference", //and others like this
"Id": "id",
"Value": "value",
}
"{columnName}": "value",
"{columnName}Id": "id",
None of these seems to work. Some give an error like "The request is malformed or incorrect.", others go through, but doesn't include the lookup field.
The documentation for this is scarce (if any), and I have found very little information on google (apart from someone asking the same question with no answers). Anyone that got this to work yet? Is it even possible?
I have got this to work with people fields where the multiple selection option was DISABLED. So if you have a person field which allows one person only, the following works.
"{columnName}LookupId": id
Additionally, the id still needs to be the SP ID and not the graph user GUID. This ID changes from site to site.
You need to add a lookup column in the following format
"Office": "London",
"OfficeLookupId", "16"
Where Office is the name of the column

Zapier multi step triggers and passing variables

I am getting stuck creating my own app to use within Zapier. It is for an unsupported CRM
https://www.brightpearl.com/developer/latest/
I have been able to authenticate and create a test trigger - a simple call to retrive information about one product ID where the ID is provided in the request URL manually.
Example Use Case
Using an Email sent to a GMail account, search for a customerand add the body of the email as a note to the customer.
I can search using Zapier->Searches to retrieve a result.
The Brightpearl API search returns an ID for any matched contacts.
https://www.brightpearl.com/support/documentation/resource-search
The ID can be accessed in the json response
{
response: {
results: [
[
4,
"admin#email.com",
"Primary",
"Admin"
]
]
},
reference: {}
}
The ID is required to add the note later
How do I store the ID to use in the Action later?
How do I chain the events together so that the Action is called after the ID is captured?
I have gone through the Zapier documentation and cannot find example code which does this.
The trigger that exposes the ID in the API response (in this case, the Brightpearl search result) can be mapped to a subsequent action. You don't store data in Zapier - you just pass it between actions.
Zapier's multi-step interface lets you append actions which can accept any data returned from the previous step.

Persistent login implementaion in ASP.NET MVC application

I want to implement the type of authentication that is explained here in an ASP.NET MVC application.
http://jaspan.com/improved_persistent_login_cookie_best_practice
My current implementation is having a Users and UserLoginTokens tables:
CREATE TABLE [Users].[Users]
(
Id int NOT NULL,
UserName nvarchar(30) NULL, -- Not unique. Login by Email.
Email nvarchar(100) NOT NULL,
PasswordHash nvarchar(512) NOT NULL,
PasswordSalt nvarchar(512) NOT NULL,
)
CREATE TABLE [Users].[UserLoginTokens]
(
Id int NOT NULL,
UserId int NOT NULL,
Token varchar(16) NOT NULL,
Series varchar(16) NOT NULL,
)
After the user is log in, he issued a User cookie with the content: t=#Token&s=#Series.
Now, I have PersistentLoginModule that search for this cookie each request, validate that the Token and Series are valid build the user from it.
My questions:
In order to implement this, is it good idea to implement my own authentication module and don't use the FormsAuthentication at all?
Should I validate the token against the DB in each request?
When should I discard the old Token and issued to user a new one?
Regarding the implementation of the DB, if I understand it correctly the Series is always the same, for a given user. If so, maybe I should move it to the User table?
Thanks, any help will be very appreciate!
If you're going to build your own Authentication Module, I would recommend still using the FormsAuthentication ticket.
The FormsAuthenticationTicket class has a UserData property that you can use to store additional data.
You can use the static FormsAuthentication.Encrypt(ticket) and FormsAuthentication.Decrypt(ticket) methods to store and retrieve the data set in the cookie.
NO. You don't want to go to the database on every request. You might want to store something like the HASH of the provided evidence in some kind of session variable (after you've verified it against the database). You could then later just recompute the HASH and compare it to the value you've already verified during the current session (to verify that it hasn't been tampered with).
You should definitely do your research on best practices and authentication hacking. The article you linked to is from 2006. There has been lots of changes in web security since then.
Check the source code to the FormsAuthenticationModule to see how the Microsoft implementation works (using something like reflector). You should also make sure that this KB patch is installed http://support.microsoft.com/kb/2416472

Resources