LinkedIn Manage Organization users' role API issue - linkedin

While trying to update an organization user's role using LinkedIn API:organization access control following error occured:
LinkedIn page error response
API request:
const encodedUrl = encodeURIComponent(accountId);
const { data } = await axios.put(
`https://api.linkedin.com/v2/organizationAcls/(organization:${encodedUrl},role:DIRECT_SPONSORED_CONTENT_POSTER,roleAssignee:${userId})`,
{
state: 'REQUESTED',
role: 'DIRECT_SPONSORED_CONTENT_POSTER',
roleAssignee: userId,
organization: accountId,
},
setAccessToken(accessToken)
);
Encountered similar issue with LinkedIn Ads manage organization user's update API:
LinkedIn Ads error response
Postman collection for LinkedIn Ads: postman collection
How can I resolve this issue and update a user role?

Related

How can I solve create account problem with different providers?

I have a sign in with Google:example#gmail.com
then create an account with the same email:example#gmail.com
There is a problem with two different providers
Sign in with Google (same Gmail)
Sign in with Email (same Gmail)
How Can I handle these two (When I delete the google sign-in account from Firebase Console. I can create an account with that email) Otherwise I can't create an account with that email and also can't sign in.
I learning Firebase Auth with https://github.com/gladly-team/next-firebase-auth
If you first sign in with Google using "example#gmail.com", it means a user will be created using this particular email address. If you try to sign in with any other provider or with an email and password using the same email address, you'll get an error message that says that the user already exists. And it makes sense since you have already used that email for a user before.
There are two ways in which you can solve this problem. When you get such an error, you can check the provider used to create the account, and notify the user to use it. For example, if the user signs in with Google and tries to authenticate with email and password right after that, display a message to the user in which you should say that the user already exists, and should use the authentication provider which was selected to create the account in the first place, in this case, Google.
The second option would be to allow the user to have multiple accounts using the same email address with different authentication providers. This option can be enabled directly in the Firebase Console, in the Authentication section.
So it's up to you to decide which option works better for your project.
The simple Solution is to enable multiple account an email.
Or ----------------
You Link the account.
This is an example when there is a facebook account with a certain email
and you want to use that same email to sign in with Email and password or gmail, if those two emails are not linked different provider error will be thrown. check here for more
export function linkFaceBookAccount(authContext?: AuthContextType, notificationContext?: NotificationContextType, history?: History.History) {
const provider = new FacebookAuthProvider(); // create a provider
linkWithPopup(auth.currentUser as User, provider).then((result) => {
// This gives you a Google Access Token. You can use it to access the Google API.
// const credential = FacebookAuthProvider.credentialFromResult(result);
// const token = credential?.accessToken;
// The signed-in user info.
const user = result.user;
saveUserToLocalStorage(user);
authContext?.loadUserToState(user);
notificationContext?.addNotification({
message: `This email's (${auth.currentUser?.email}) account has been successful linked with your facebook account`,
title: "Link successful",
notificationType: "SUCCESS",
positiveActionText: "continue",
positiveAction: () => {
history?.push("/")
}
})
}).catch((error) => {
const email = error.customData?.email;
const errorCode = error.code;
const duplicateAccount = errorCode === "auth/account-exists-with-different-credential";
notificationContext?.addNotification({
message: errorFirebase(error, email),
title: "Linking Error",
notificationType: "WARNING",
positiveActionText: duplicateAccount ? "Link" : "ok",
negativeActionText: duplicateAccount ? "cancel" : undefined,
code: errorCode,
positiveAction: () => {
if (duplicateAccount) {
duplicateAccountLinking(email, "FACEBOOK", history);
}
}
})
});}

Custom provider claims in `additionalUserInfo.profile` are not available via firebase admin?

I'm following firebase/identity toolkit docs for a SAML identity provider. Upon successful login, the redirect result contains attributes derived from the provider:
provider = new firebase.auth.SAMLAuthProvider('saml.test-provider');
firebase.auth().signInWithRedirect(provider);
...
firebase.auth().getRedirectResult().then(function(result) {
if (result.credential) {
console.log(result.additionalUserInfo.profile) // Custom provider claims, e.g., {"provider-foo":"bar"}
}
}
From the docs, the same values are also available via
result.user.getIdTokenResult().idTokenResult.claims.firebase.sign_in_attributes
firebase.sign_in_attributes
These same attributes don't seem to be stored anywhere accessible in the firebase_admin SDK:
from firebase_admin import auth
user = auth.get_user(uid)
print(user.custom_claims) # => None ... *provider* claims aren't here
print(user.provider_data[0]) # => has `federatedId` and some others, but still no custom provider claims
Is there any way to get this info in the admin SDK? Any way to tell if it's even saved by Firebase? Do I need to capture it in firestore (and wouldn't that be risky since the user could fake claims coming from the provider?)
Thanks!
the additional SAML attributes are only persisted in the token claims accessible via:
result.user.getIdTokenResult().idTokenResult.claims.firebase.sign_in_attributes
They are not stored on the user record. Identity Platform/Firebase Auth does not persist additional user info in storage for privacy reasons.
However, you can always store the claims you need on the record via the Admin SDK.
You would send the ID token to your server, verify it, parse the claims you need and set them on the user record.
Here is sample via the Node.js Admin SDK.
app.post('/saveUserClaims', (req, res) => {
// Get the ID token passed.
const idToken = req.body.idToken;
admin.auth().verifyIdToken(idToken)
.then(function(decodedToken) {
const uid = decodedToken.uid;
// ...
const samlClaims = decodedToken.firebase.sign_in_attributes;
// You would filter the claims as there could be too many.
// You can also save these claims in your database, etc.
return admin.auth().setCustomUserClaims(uid, samlClaims)
.then(() => {
res.status(200).end();
});
}).catch(function(error) {
// Handle error
});
});
That said, in general there is no need to save these claims as they will always be available in the ID token and you can access them from your security rules or when you pass the ID token to your server for validation. This is a better way to do this as you don't run into synchronization issue where your DB is out of sync with the user's attributes.

Not enough permissions to access: POST /dmpSegments

I tried - POST https://api.linkedin.com/v2/dmpSegments
but got error -
{"serviceErrorCode":100,"message":"Not enough permissions to access:
POST /dmpSegments","status":403}
My app does have permission of rw_ads. I can successfully call some ads api endpoints, e.g.
- POST https://api.linkedin.com/v2/adSegmentsV2
- POST https://api.linkedin.com/v2/adCampaignGroupsV2
- POST https://api.linkedin.com/v2/adCampaignsV2
- POST https://api.linkedin.com/v2/adCreativesV2
public string CreateDmpSegment(string token, DmpSegmentsCreateRequest dmpSegmentsCreateRequest, ILogMessages messages)
{
NameValueCollection data = System.Web.HttpUtility.ParseQueryString("");
string url = $#"{LinkedInApiUrl}dmpSegments";
Tuple<NameValueCollection, dynamic> results = RestHelper.JsonApiPOST(url, token, dmpSegmentsCreateRequest);
if (string.Equals(results.Item1["valid"], true.ToString(), StringComparison.InvariantCultureIgnoreCase))
{
return results.Item2["X-LinkedIn-Id"];
}
UpdateErrors(LinkedInErrors.CreateDmpSegmentError, results, messages);
return null;
}
expected return results.Item2["X-LinkedIn-Id"];
but got error -
{"serviceErrorCode":100,"message":"Not enough permissions to access: POST /dmpSegments","status":403}
From what I read here you must have the access token generated with rw_dmp_segments scope. The rw_ads scope is not enough.
To be able to request access tokens with rw_dmp_segments scope, you have to obtain a further permission from LinkedIn as written here:
"..you must initiate a Technical Sign Off request by contacting your LinkedIn POC on the Business Development team."
Hope this helps.

Is email authentication using id token possible?

I'm creating a POC for an iOS application that uses extension. The extension has to know if a user is authenticated. Unfortunately a containing app and an extension are separate application which means I have to keep auth state somewhere.
I don't want to store user email and password but instead a token and use it to authenticate. However trying to authenticate with the issued token and providerId (Firebase) does seems to work.
Both apps under the same Firebase project.
Main Application (Firebase ios App1):
let userDefatuls = UserDefaults(suiteName: "group.test")
userDefatuls?.set(providerId!, forKey: "providerId")
userDefatuls?.set(value!, forKey: "token")
print("Saved value to user defaults \(value!)")
userDefatuls?.synchronize()
Extension Application (Firebase ios App2):
let userDefaults = UserDefaults(suiteName: "group.test")
let token = userDefaults?.string(forKey: "token")
let providerId = userDefaults?.string(forKey: "providerId")
print("What is the provider id \(providerId)")
let credential = OAuthProvider.credential(withProviderID: providerId!, accessToken: token!)
Auth.auth().signIn(with: credential) { (user, error) in
print("********* What is the user \(user) what is the error \(error)")
}
The above renders:
What is the user nil what is the error:
Optional(Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={error_name=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information., NSUnderlyingError=0x600000447290 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={
code = 400;
errors = (
{
domain = global;
message = "INVALID_PROVIDER_ID : Provider Id is not supported.";
reason = invalid;
}
);
message = "INVALID_PROVIDER_ID : Provider Id is not supported.";
}}}})
Do you know if the support and works? Is there something what I'm doing wrong?
You can't sign in with a Firebase ID token. What you can do is:
Create an endpoint that takes an ID token, verifies it:
https://firebase.google.com/docs/auth/admin/verify-id-tokens
and returns a custom token:
https://firebase.google.com/docs/auth/admin/create-custom-tokens
You then signInWithCustomToken in the extension.
However, this could open a vulnerability as if a short lived ID token is leaked, the attacker can exchange it for a permanent session via that endpoint.
You can only return the custom token if the auth_time on the ID token is recent. This ensure that a recently signed in user can sync their app to with the extension.

How to get user access token using LinkedIn Javascript API like in Facebook?

I am developing a native Mobile App and what i need is to pass a users's access token and get user details for doing mobile based operations. I was able to achieve the same in Facebook. But how can i get the access token of user via LinkedIn JavaScript API.
Facebook API way:
function statusChangeCallback(response) {
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected') {
// Logged into your app and Facebook.
console.log(response); ===> GOT USER ACCESS TOKEN FROM THIS RESPONSE
testAPI();
} else if (response.status === 'not_authorized') {
// The person is logged into Facebook, but not your app.
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
document.getElementById('status').innerHTML = 'Please log ' +
'into Facebook.';
}
}
Any help to get the same in LinkedIn will be very much appreciated.
Check out the LinkedIn's Documentation on Exchanging JSAPI tokens for OAuth tokens.

Resources