Accessing user properties in External network using Rest API - yammer

Does anybody know how user profiles are managed in external networks ? In particular, when we get Users using the REST API, Yammer respond with a user data where:
The user id in the external network is not the same as the user id in the principal network
Email address is replaced by something like username+externalnetwork#users.yammer.com"
Do you know if there is a way to find the user principal properties by requesting the external nerwork (or maybe find a way to match the user between its principal and external networks) ?
By the way is there any documentation somewhere about the External Networks and the REST API ?

User profiles in external networks are separate in that they have different user IDs and state (pending, active, deleted etc.) To avoid duplication you only edit name, job title etc. in the home network and that appears in the other profiles. This explains why the users have different IDs.
When you get a user profile for /domain.com/api/v1/users/current.json and /en-pemalink/api/v1/users/current.json you should get different results back. I don't know if there is a recommended way because this isn't documented, or generally recommended for third parties. Zapier published some information on the quirks of the API that may be helpful.

Related

Assign project-level user to multiple tenants

Cannot find anywhere on Google Identity Platform docs that clearly describe whether it's possible to assign a single user to multiple tenants. see https://cloud.google.com/identity-platform/docs/multi-tenancy-managing-tenants
My project needs the capability to have a single user be able to login to multiple, separate tenants. Currently, I have to create a new user on every tenant I want to be able to login to. This is not good because each new user I create has a different uid and separate password management. For a single user, I want to be able to maintain the same uid across tenants so the associated user data can be consistent as well.
I was thinking there would be some way to create a user at the project level (not tenant level) and then assign that user to specific tenants?
Some random thoughts: The docs say some things about migrating users between tenants, perhaps that is one way. Also was thinking that creating a tenant user with my existing project-level uid would somehow merge them so the uid and password management is the same?
Edit: I found this conceptual discussion to be helpful: https://softwareengineering.stackexchange.com/questions/403274/multitenancy-with-cross-tenant-users
what I gathered from that link is that SSO is separate from multi-tenancy. So I'm trying to figure out an SSO solution on top of multi-tenancy google idp. Any code solutions/suggestions for how to add SSO on top of multi-tenant google identity platform?
If you need the same user across tenants maybe you should instead rely on the user email, custom claims, federated ID (eg. user.providerData[0].uid). When you get an ID token for the user you have access to this same information regardless of the tenant or user.uid.

Google Assistant Smart Home : agentUserId definition may be incorrect

As per Google Assistant documentation for Smart Home, the agentUserId used in action.devices.QUERY is defined to 'Reflects the unique (and immutable) user ID on the agent's platform. The string is opaque to Google, so if there's an immutable form vs a mutable form on the agent side, use the immutable form (e.g. an account number rather than email)'
However there can be cases where the same device (with same agent user id) is attached to multiple Google Assistant accounts and in such cases a DISCONNECT request may result is ceasing report state for all accounts. The solution will be to add some unique ID corresponding to the Google Assistant account, however such information is not available in any request.
Has anyone seen similar issue and is my understanding incorrect?
The agentUserId is meant to be the user account on the smart home platform. SHP user '1234' may have a vacuum and two lights, but could be linked to multiple Google accounts.
During the account linking process, you would be expected to give a refresh and access tokens to allow for Google to have authorized control over these devices. If you assign unique access tokens for each Google account that signs in, you'd be able to determine which Google account the request is coming from.
At that point, once the user disconnects, you can use the access token in the request header to associate that with a specific Google account and only disable reporting for that account while not affecting other accounts.
So, yes the solution is to have a unique ID connecting to the account. While this is not passed in the agent ID, there is already a mechanism to make this association through the authorization system.
Alternatively, you could append a key in the agentUserId, ie. '1234-user#gmail.com'. However, this may have unintended impacts in the Home Graph. In a multi-user home, you may end up seeing the devices duplicated because Google doesn't have the right information to deduplicate.

How to uniquely identity a pipedrive account?

We are trying to integrate our platform with Pipedrive. As far as we have researched, in a pipedrive account, there is one admin and he can add multiple users. And the users later can login in their respective accounts.
What we are trying to make sure is that once a Pipedrive account is integrated with our platform, the same account should not be integrated twice. So, I need a unique identifier, that lets me know whether the account has already been integrated.
My initial approach was to check the api key. But it was not successful, since every users in an account have different API Keys.
After a bit of research, I found out that there is an identifier called company_id which is common for all the users in an account. But I could not find anything regarding it in documentation. So, I am not 100% confident to go ahead and implement it in our code.
Does anyone have an idea about this?
Pipedrive support rep here.
The most sure-fire way to ensure this is to make a GET request against http://api.pipedrive.com/v1/users?api_token=your_token_here.
You are correct in assuming the company_id in the additional_data object in the response is static and won't change across any users on the account.
Note that a Pipedrive account may have more than one admin, and that non-admins (regular users) might have visibility (and editing) restrictions in place, which may cause some of your GET, PUT and DELETE requests to fail.
In case you're not doing this already, I'd thus advise filtering the data array from the abovementioned endpoint for user.is_you to equal true and check whether the is_admin property is set to 1 during "registration" to ensure the user setting up the integration is an admin.
Hope this helps!
I'm not quite sure what you're asking for. Are you looking for a unique identifier for each user?
Each user has an id, you can get all users by calling
https://api.pipedrive.com/v1/users?api_token=____
This will return a JSON Object with data on your users, including their names and associated IDs. Admins are just users with different privilege levels. All admins are users, but not all users are admins. All users are part of a company, the company is identified by the first part of the Pipedrive account url ie.
https://FooCompany.pipedrive.com
Are you trying to see if a certain company has been integrated already?

Using o-auth to authentify users on my API

I've got a project made of two websites:
The front : A Laravel website without database and logic (just showing static pages and my javascript)
The API : A project using Lumen/Dingo API with my endpoints, my database, my logic and my models
I want to allow my front to ask data to my API depending the user.
Ex. I want to log the user, retrieve his friends, add some post to his
account, etc. (from the Javascript)
What is the best solution?
Using an identification per user (using o-auth or JWT)
Allow my front project to ask to my API then each javascript call needs to use my front without knowing my API) (In this solution I need to create routes similars to my API's routes)
Identification per user is always a better solution as the claims can be decided per user, also in future when it is required to provide permissions to access API based on claims or roles, it becomes easy to give information using the claims and amount of access you can give to a specific user.
So the way it will work is:
There will be identity server which will be containing the list of users in the system, and also the clams and scopes per user.
The API project will trust the identity server, that means any token provided by the identity server can get verified.
Based on the token per user your API app can decide how much information you want to give to the user.
That way in future you can have methods based on roles, claims and users will be provided with only the information that they have access to.

How to expose CardDAV address books / CalDAV calendars with arbitrary filters?

I want to provide access to address books and calendars that may have search filters (e.g. tags, user, groups) applied.
They should not be auto-discoverable because there may be billions of combinations but must nonetheless be compatible with common clients (e.g. iOS / OS X, Windows Phones), i.e. it should be possible to add the URL with filters to the client.
One issue seems to be that some clients rely on discovery features rather than the URL you give them, e.g. iOS (you try to add one address book by exact URL and it adds all discoverable ones instead).
Another thing is structuring the optional filters.
What about using paths?
What is considered best practice here?
Are the calendars readonly or readwrite? If they are readonly, you can use webcal URLs for calendars (aka 'subscribed calendar' or iCalendar-over-HTTP).
For Cal/CardDAV calendars the Apple devices (and most other DAV clients) configure a full account (using the regular account discovery mechanisms), not just 'a URL'. I don't think there is a way around this.
Assuming you are building a web service which provides a registry/search-engine or which is an aggregator of such calendar or address data, this service could then provide Cal/CardDAV accounts (which implements the discovery).
On your web-service you would then have two options:
proxy (and potentially cache) the remote data
create a 'CalDAV subscribed calendar' (a special WebDAV resource which points to a CalDAV calendar (resource type {http://calendarserver.org/ns/}subscribed)).
For contacts you only have choice 1. And as an extra complication you might want to expose the stored queries as vCard groups instead of CardDAV collections. This is because some clients (i.e. some MacOS Contacts apps) only support one CardDAV collection (and only use groups to structure the data).
Sample: Lets say you invented a service called 'Caloogle.com'. The user needs to get some account on that service (could be auto-created, etc). The user adds a CalDAV account to his iOS device (e.g. using a preconfigured profile, so that he doesn't have to enter all the data), which then connects to Caloogle to fetch data into the iOS EventKit database.
Now in your Caloogle app (or on the website), you let the user search for calendar data. If the user found a set he likes, he saves that as a calendar into Caloogle, say 'Dividend Release Dates BP, Apple and AlwaysRightInstitute'. iOS will ping the account eventually and pick up the saved calendar. User is amazed and happy.
How you actually implement the web service (proxy or name-to-url map) depends a lot on where your data is coming from ...
Makes sense?
P.S.: Be careful when storing queries in URLs, some HTTP infrastructure components have limits on the length of a URL, and advanced queries can quickly overflow this.
Like hnh said in his answer, smart clients will try to discover the DAV services you are offering when you configure CardDAV or CalDAV from a URL rather than just use that very URL, so there seems to be no clean way to provide multiple virtual collections filtered by tags, users, groups etc.
The simplest solution that could work is to provide one virtual DAV server for each filter URL, with full service discovery within the constraints of that filter URL.
Virtual endpoints are provided with the help of URL rewriting, a feature found in common web servers, and will all point to the same DAV server code base and supply it with the filter criteria.
If for example, you want CalDAV / CardDAV collections of items that have the tags PR and Spain, you could expose them under https://dav.server/tag:PR/tag:Spain/, while items with a tag China can be exposed under https://dav.server/tag:China/.
Note that each URL provides full DAV functionality with discoverability.
As discovery is relative to the respective roots https://dav.server/tag:PR/tag:Spain/ and https://dav.server/tag:China/, there will be no interference.
Additionally, you could expose a simple URL https://server for a well-defined set of CalDAV / CardDAV collections, e.g. a default calendar / address book or some "bookmarked" collections defined by the user in some way, e.g. "PR Spain".
The simple URL would then provide these HTTP redirects, as per RFC 5785:
https://server/.well-known/caldav => https://dav.server/default
https://server/.well-known/carddav => https://dav.server/default
iOS clients and those supporting well-known URIs could then be configured by just setting the host to server and supplying login credentials.
They would then try to connect via HTTPS, check for the well-known URIs and thus discover the DAV endpoint at https://dav.server/default.
Those without well-known URI support nor discovery would require the exact URL, e.g. https://dav.server/default/calendars/jane/main or https://dav.server/tag:China/calendars/jane/main.

Resources