Is there a way to invite attendees outside the organization? - google-calendar-api

I have read the google calendar API docs but I couldn't find a way of inviting guest outside the account's organization, is this possible?
This is my code with the NodeJS client:
const auth = new google.auth.GoogleAuth({
keyFile: 'src/google-api/calendar-auth.json',
scopes: ['https://www.googleapis.com/auth/calendar'],
});
const calendar = google.calendar({ version: 'v3', auth });
calendar.events.insert({
calendarId: 'email-of-organization',
sendUpdates: 'all',
requestBody: {
start: {
dateTime: startDate.toISOString(),
timeZone: 'utc',
},
end: {
dateTime: endDate.toISOString(),
timeZone: 'utc',
},
summary: 'a summary',
description: 'a description',
attendees: [{ email: 'email#outside.org' }], // this email is outside my organization
},
});
The error:
Service accounts cannot invite attendees without Domain-Wide Delegation of Authority
Even if I setup Domain-Wide Delegation, the error persists.

Basically you authorizing your service account to access data on behalf of users in your domain when you delegate domain-wide authority to your service account. See Delegating domain-wide authority to the service account
Once you finished delegating domain-wide authority, your application now has the authority to make API calls as users in your domain (to "impersonate" users). When you prepare to make authorized API calls, you specify the user to impersonate.
It is possible to invite guests outside your domain (using your user account or a service account). You have the option to warn the users when inviting guests outside your domain. See Allow external invitations in Google Calendar events
I tried creating an event using my user account and add a guest from outside the domain with events.insert. It was successfully created. Therefore, if you let your service account to impersonate a user in your domain it should be able to create events and invite guests outside your domain as well

Related

Microsoft Identity AzureAD ASP.NET Core for Two Tenants only

We have an internal business Blazor Server app that is to be used by two Azure AD Tenants only. We have the following appsettings.json file. When the user authenticates we want to verify that the ID Token is from either of these two tenantid as a requirement to be Authorized. We can currently see the issuer in the initial ID Token context.User.Claims received after authenticating on either of the two Tenants. We tried to add the ValidIssuers list to the TokenValidationParameters. However, it remains authorization from any tenant is allowed, instead of just the two.
Now we are searching for a clue about where and how to include the issuer requirement for authentication. I have searched the Internet for a while now, and am unable to find an example specific enough to be confident about doing it correctly. I imagine this is simple for some people. Any direction is most appreciated. Best regards, Ranny
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxxxxxx",
"TenantId": "organizations",
"ClientId": "xxxxxxxxxxxxxxxx",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath": "/signout-callback-oidc"
},
"AllowedIssuers": "xxxxxxxxxxxxxxxxxxxxxxxxxx,yyyyyyyyyyyyyyyyyyyyyyyyyy",
"AllowedHosts": "*"
}
Startup.cs section:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.Configure<OpenIdConnectOptions>(options =>
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuers = new List<string>()
{
#"https://login.microsoftonline.com/xxxxxxxxxxxxxxxxxxxxxxxxxx/v2.0",
#"https://login.microsoftonline.com/yyyyyyyyyyyyyyyyyyyyyyyyyy/v2.0"
}
});
We can restrict the users to specific/multiple tenants in following ways.
1. Restrict Access by tenant location
While creating the user in an tenant, you can specify the region that he is not allowed to access any subscription and groups belongs to that tenant and region you selected by selecting "Yes" to Block Sign In option.
2) Restrict Access by user domain id
Go to [Azure Active directory portal] - The Azure Active Directory admin center dashboard appears.
In the left pane, select Azure Active Directory. The Azure Active Directory overview page appears.
On the Overview page, select Tenant Properties
There you can give/restrict access to all the resources in that tenant for the user based on user's domain id (for ex: user#mxxxxx.onmicrosoft.com)
After doing these operations on tenant restrictions to users, if user tries to access applications in which he/she doesn't have permissions then they will get this kind of
For more information, hope this Microsoft documentation for tenant restrictions to users will helps you.

google calendar api send as another user on our domain using service account

I have a service account, and I downloaded the credentials that look like:
{
"installed":{
"client_id":"abc123",
...
}
}
And I go through the procedure of running the node.js based code which attempts to create the token file with getNewAccessToken, and it gives me the prompt:
Authorize this app by visiting this url: https://accounts.google.com/o/oauth2/v2/auth?ac...
When I go to the link, it asks me to log in with my google account.
That sets the token and I can send google calendar events where the calendar id is set to primary (and it is set to be from me) but I can't set the calendar id to John.Smith#mycompany.com
It says
{
"domain": "calendar",
"reason": "requiredAccessLevel",
"message": "You need to have writer access to this calendar."
}
I am not sure how to make it so my service account can be used to send events on behalf of our staff members. Is it because when authorizing I logged in as my account instead of the service account, and if so, how do I authorize as the service account.
Update: I am using the code provided in the google calendar api quickstart guide

AWS amplify - Can't synchronize via DataStore if I use an API Key; but Cognito User Pools work

I've setup an amplify project for react.js, which should allow authorized and unauthorized access to my application.
Therefore, I've configured two authentication methods: Cognito User Pools and API key. The first one is my default.
My application runs fine, if I sign in via the Cognito User Pool. All data is beeing synchronized via the DataStore.
But if I switch to the API Key as unauthenticated user, I only get unauthorized errors under the hood. E.g. for one of my custom types:
errorType: "Unauthorized"
message: "Not Authorized to access onCreateMyCustomType on type Subscription"
The API key is sent correctly as "x-api-key".
If I manually query the Graph-API (e.g. via the amplify.js-API in my application or the third party tool GraphiQL), I can get the results. Just the synchronization isn't working as it does for authenticated users.
In my schema, I control the access via #auth. E.g.:
#auth(rules: [
# Owner access
{ allow: owner },
# System access
{ allow: private, provider: iam },
# Admin access
{ allow: groups, groups: ["Admin"] },
# Default user access
{ allow: groups, groups: ["User"], operations: [read] },
# Everyone
{ allow: public, operations: [read] }
])
I'm switching the authentication method via:
Amplify.configure({
...awsconfig,
aws_appsync_authenticationType: isAuthenticated ? 'AMAZON_COGNITO_USER_POOLS' : 'API_KEY',
});
I could solve the issue.
There wasn't a public access defined for some custom types, so the whole synchronization failed. After uncommenting these in my scheme and pushing the changes, all data could be synchronized. A better approach could be selective sync to disable the synchronization for the affected types, if the user isn't signed in. But I haven't tried that yet.
In aws-exports.js try changing
"aws_appsync_authenticationType": "AWS_IAM",
to whatever authentication type you are using like. For example,
"aws_appsync_authenticationType": "API_KEY",
https://docs.amplify.aws/lib/graphqlapi/authz/q/platform/js/
If this works you can make it permanent by running
amplify update api
then select graphql and update authorization modes.
Otherwise add additional authorization types in the AppSync schema:
https://aws.amazon.com/blogs/mobile/using-multiple-authorization-types-with-aws-appsync-graphql-apis/

Creating Google Calendar events with a GCP Service Account

I would like to rig things so that my GCP service account can invite users to calendar events. So for example my-service-account#myproject.iam.gserviceaccount.com would invite user#myCorporation.com to an event. It seems to me that this should be possible simply by giving my-service-account#myproject.iam.gserviceaccount.com permission to use the Calendar API, without having user#myCorporation.com grant any additional permissions.
I tried to implement this example, but replaced the compute scope and the compute API calls with the calendar scope and calendar API calls. My code is returning the error
Insufficient Permission: Request had insufficient authentication scopes.
I've poked around on the internet a bunch, and I cannot tell if the problem is that I did something wrong or if the problem is that Google does not support what I'm trying to do.
Here is my code:
const {google} = require('googleapis');
const compute = google.compute('v1');
const {GoogleAuth} = require('google-auth-library');
async function main() {
const auth = new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/compute']
});
//keeping the compute stuff in as a sanity check
//to ensure that the problem is with calendar, not something more general
const authClient = await auth.getClient();
const project = await auth.getProjectId();
const res = await compute.zones.list({project, auth: authClient});
console.log(res.data);
createEvent(auth);
}
/**
* Lists the next 10 events on the user's primary calendar.
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function createEvent(auth) {
const calendar = google.calendar({version: 'v3', auth});
calendar.events.insert({
calendarId: 'primary',
event: {
"description": "my test event",
"start": {
"date": "2020-05-20",
},
attendees: [{email: "myGuest#mailinator.com"}]
}
}
);
}
main().catch(console.error);
Answer:
You need to enable the APIs and provide scopes in three places: in your auth code, in the GCP console, and the Google Admin console.
More Information:
As I explained in the comments, the code you have provided should run without issue. The Insufficient Permission: Request had insufficient authentication scopes. error is a result of the service account not being given access to the required scopes somewhere on Google's side.
Make sure you have completed the following steps:
Provided the scopes in the application as an auth object (which you have already done):
const auth = new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/compute']
});
Enabled the Calendar API in the GCP console for your Service Account GCP Project.
Provided the required scopes for your service account in the OAuth consent screen settings in GCP.
Added the required scopes to the service account in the Google Admin console. This is done by following the Security > Advanced Settings > Manage API client access UI elements, and assigning all scopes the service account needs to the service account client ID.
Note: This final step must be done by a domain admin and can not be done by anyone who is not.
In this case, you will need to contact your domain admin to give your project API access.
References:
Google API Console
Google Admin Console
Related Answers:
Google Calendar API. Adding an event to someone calendar throws error “Error 401: invalid_client” just when authenticating

Using an external OpenID Connect Identity Provider for WSO2 Store access

I am setting up an instance of WSO2 API manager, and want to give developers access to the API "store" pages by linking it to my existing OpenID Connect identity server (OpenAM). I've added the OIDC configuration into the store configuration file (wso2am-2.6.0/repository/deployment/server/jaggeryapps/store/site/conf/site.json) with all the details of the authorise, token, userinfo endpoints, etc.
When users click login in the store, it is correctly redirecting them to OpenAM to login, and passing an access token back to the store app. I've also ensured some of the required claims are returned from the userinfo endpoint (like preferred_username). I'm also returning a "groups" claim listing the groups the user should be in "subscriber" for example.
The claims I'm returning from userinfo are:
{
"address":{
"formatted":"My House"
},
"given_name":"Danny",
"family_name":"Developer",
"name":"Danny Developer",
"preferred_username":"Danny Developer",
"groups":[
"subscriber"
],
"email":"adam.hatherly#nhs.net",
"sub":"developer1"
}
However, whatever I try with claims and group names, the store still gives the error message "User is not permitted to log in to the Store.". I assume there's something else I need to add in either the access token or userinfo endpoint
claims list to make the store app accept the user, or some other config in the store or carbon console?
The reason for the user login issue is that the user does not have relevant permissions to log in to the store. User needs to have internal/subscriber role assigned to it. Since the user is coming from OpenAM and APIM does not have any information to authorize it, login fails.
For this either you should share the user OpenAM user store with APIM (say a shared LDAP) and assign users with internal/subscriber role or use a custom code to add the user to the APIM user store and assign the role.
Another easiest option is to create a user in APIM side (add a dummy password) with subscriber role. but this is not a suitable solution if you do not know all the users

Resources