Initialize sdk in Cloud Run - google-cloud-run

Per documentation Initialize the SDK I will need to generate New Private Key and feed that to the init process at the service.
var admin = require("firebase-admin");
var serviceAccount = require("New Private Key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://blah.firebaseio.com"
});
Is there way at IAM level add trust to Cloud Run so it will allowed to access Firebase services? I would like to use admin.credential.applicationDefault() when I run in the Cloud Run.
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
Just need a clarification may be I am misreading and it is already doing that.

By implementing the Firebase Authentication you can achieve what you want to do:
First you will need to setup Firebase Authentication in your project and service.
Enable in the Cloud IAM API for your project.
Authorize the Cloud Run credentials to sign tokens. (This can be done by visiting the IAM & admin page in the Google Cloud console, and granting the Service Account Token Creator role to the Default compute service account.)
But in theory it is included in Cloud Functions, but just to be sure you can make the second step, but depending on the needs of your application it might or not be an overkill if you just want a simple authentication.

Tested instance and it seems running from Cloud Run env SDK was able pull admin.credential.applicationDefault()! Amazing how it was simplified! Rolling all my apps to Cloud Run!!! Having experience with Azure/AWS, GCP by far too friendly! Kuddos to GCP!

Related

How to distinguish each Slack app installation?

I'm using Slack Bolt JS api. Can successfully install apps into slack workspaces following the http://example.com/slack/install URL. I'm trying to integrate this into a SaaS. The question is how to distinguish Slack app installations and how to determine which Slack app installation belongs to which of the SaaS user? My guess is that some information should be injected during the OAuth flow, but now sure how to do that using Slack Bolt SDK.
const app = new App({
installerOptions: {
installPath: '/slack/install',
redirectUriPath: '/slack/oauth_redirect'
},
// token, etc
});
seems like you need to implement authentication with OAuth and your own installationStorage. Take a look this doc
The basic steps that you need to cover are:
You need to start you app with SLACK_CLIENT_ID, SLACK_SECRET_ID and SLACK_SIGNING_SECRET
Include your custom callbacks to handle app installation (installationStore option).
In the above example, you will need to replace database.set and database.get by your own database query, server API or something else. Here you can see a full example.
After this setup, slack will call your app from many different workspace and the correct token will be recovered thowth installationStore.fetchInstallation. This will happen before call the event or message handler.
PS: You should not include token in the initialization of the app. It will be set later.

How to create a gitlab login button to allow the client app create repositories, make commits and pull request for the user?

I would like that the users of my app can login through the gitlab without the user need configurate nothing, like many apps of the web, you only click in allow and is logged. Because I need use the gitlab api to create repositories, make commits, and pull requests in their accounts. I read this:
https://docs.gitlab.com/ee/api/oauth2.html#implicit-grant-flow
I need that be "implicit-grant-flow", because I don't want send nothing for the server, all thing should happen in the client app. I think that is it because I read:
"Implicit grant flow: This flow is designed for user-agent only apps (e.g., single page web application running on GitLab Pages)."
But I also read:
https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=token&state=YOUR_UNIQUE_STATE_HASH&scope=public+write
APP_ID? So, the client need register the app in the gitlab account settings, ins't? But I don't want that the user have the work, I already login in the some web app using github by example, without need configurate nothing in my github account, I need the same here.
YOUR_UNIQUE_STATE_HASH? what?
I already created the gitlab application in:
https://gitlab.com/oauth/applications/
But I can't see nothing about "YOUR_UNIQUE_STATE_HASH" there.
I don't understand how this can be a login button that allow me to use the gitlab API to make a commit in name of the user for example.
Note: off course, I'll search about what should be "YOUR_UNIQUE_STATE_HASH" now.
1 - Register one app in:
https://gitlab.com/oauth/applications/
2 - Login the gitlab with:
https://gitlab.com/oauth/authorize?client_id=CLIENT_ID_THAT_YOU_REGISTRED_IN_THE_STEP_1&redirect_uri=YOUR_APP_URL_HERE&response_type=token&state=YOUR_UNIQUE_STATE_HASH
The "YOUR_UNIQUE_STATE_HASH" you can can leave with this.
3 - If you got success, you'll be redirect and the access_token is in the url.
4 - Test the gitlab API:
https://gitlab.com/api/v4/projects?access_token=THE_ACCESS_TOKEN_THAT_IS_IN_THE_URL
You also can get the token and clean the url like:
function getToken() {
const url = new URL(window.location.href.replace(/#/g,"?"))
const token = url.searchParams.get("access_token")
const urlWithoutParams = url.href.split('?')[0]
window.history.replaceState({}, null, urlWithoutParams)
console.log(token)
}
To create a button is simple, you can create a login button like this:
<button onclick="window.location.href='https://gitlab.com/oauth/authorize?client_id=CLIENT_ID_THAT_YOU_REGISTRED_IN_THE_STEP_1&redirect_uri=YOUR_APP_URL_HERE&response_type=token&state=YOUR_UNIQUE_STATE_HASH'">Gitlab Login</button>
Warning, with GitLab 13.11 (April 2021)
GitLab OAuth implicit grant deprecation
GitLab is deprecating the OAuth 2 implicit grant flow as it has been removed for OAuth 2.1.
Beginning in 14.0, new applications will be unable to be created with the OAuth 2 implicit grant flow.
Existing OAuth implicit grant flows will no longer be supported in 14.4. Please migrate existing applications to other supported OAuth2 flows before release 14.4.
Deprecation date: June 22, 202

AWS web and mobile hub application

On AWS, I wish to create an application that allows a user to sign in via mobile, web or both.
I created a system using API Gateway, Lambdas and DynamoDB for the back end. I have sign in working for web using JavaScript but was having issues finding a Swift example for iOS of the same code (objective C only available). So I created a mobile hub application, imported my existing API and have a working iOS sign in.
The issue is that the iOS side uses the Mobile Hub so I now have 2 different User Pools so you can't sign up on web and log in on mobile (or vice versa).
I tried to change the settings in the iOS app to point to my web app Cognito User Pool settings and remove the secret but it errors as it can not be null or empty.
Why does the mobile hub require a client secret? The JavaScript documentation suggested was bad practice since code can be de-compiled and the secret extracted.
There doesn't seem to be any consistent documentation that explains, what I would guess, as the most common use case of a mobile and web app!
The other issue is that I can download my API client SDK for my API Gateway for use with web app and iOS app. But, the generated mobile hub app includes a REST based call? Am I going crazy here or does the official web approach not link to the official mobile approach?
So the key questions are:
Can or should I change the mobile apps to point at the original
Cognito?
if so should I remove the client secret?
can I effectively ignore the Mobile Hub after set up and use it purely for code generation? Assuming it was then working can I just use the generated client SDK for my API Gateway?
Is there a better way of setting up an iOS (later Android too) and web app?
I've spent considerable time and effort, and tried many approaches.
The "Mobile Hub" nicely sets up the user pool, identity pool, IAM roles etc.
The keys etc are mostly provided in the Info.plist file, although ( unwisely ) the developers of the user pool AWSSignInProvider made it have hardcoded keys in a configuration file.
SO:
If you don't intend to use the "Mobile Hub" console application for making changes to your mobile app configuration, then you won't need any more downloads. In that case, you don't have to worry about changes to Info.plist or the configuration file, and you can edit what you want.
It is unclear if you are going to use the mobile hub created identity pool and just want to insert your user pool, or if you want to change both pools. Obviously if you are using the same identity pool then some of the changes below will not be needed (they will be obvious because you will be changing them to be exactly the same).
So all you have to do is change the ID's to get everything hooked up correctly.
In general you need to fix all the downloaded keys and ID's in Info.plist and the configuration file, and then you need to update the server configuration. In more detail, here are the places you need to change it:
in the app:
update all the keys in Info.plist to be the keys you want. (specifically credentials provider and identity manager keys for google) But if you are using other mobile hub services, check the keys there too.
If you are using s3, and some of the other services the directory names/database names are also stored in the code... I leave it as an activity to find them.
in the file MySampleApp->AmazonAWS->AWSConfiguration.swift edit the keys provided by Mobile hub to match your user pool (do this while quietly swearing under your breath because they are not in Info.plist)
in the console:
put your app name in your user pool APP's list if it is not there, and record the user pool id, app id, and app secret.
click on federated identities and the identity pool created by mobile hub and update the authentication provider to use your cognito user pool id and app id.
if you are changing the identity pool too, then you will need to look at the IAM Roles for your auth and unauth users and specifically edit the policy that is named: .....yourapp....signin_MOBILEHUB_xxxxxxx, and change the identity pool id in that policy to be the one you want to use. Do this for both auth and unauth.
( you can change the id if you only use one pool, or add another to a list of id's like this if you will have multiple identity pools (for test...etc))
"Resource": [
"arn:aws:cognito-identity:*:*:identityPool/us-east-1:8s8df8f8-sd9fosd9f0sdf-999sd99fd",
"arn:aws:cognito-identity:*:*:identityPool/us-east-1:dfsf9099-sd9fosd9f0sdf-sd9f0sdf09f9s"
]
similarly, in the trust relationship associated with the roles, you need to fix the id's, (or handle multiple ID's if you want the role to serve multiple identity pools). Here is how to specify multiple id's there.
"Condition": {
"ForAllValues:StringLike": {
"cognito-identity.amazonaws.com:aud": [
"us-east-1:8s8df8f8-sd9fosd9f0sdf-999sd99fsdfdd",
"us-east-1:dfsf9099-sd9fosd9f0sdf-sd9f0sdf09f9s"
]
},
if you are using google too... you need to make sure that you have an identityProvider in the IAM configuration for google (mobile hub did that for you) and if you are using your own identity pool , in your federated identity pool authorization providers configuration you will need to select google open id provider (and put google in the authorized providers too (but I don't think this part is strictly needed))
facebook doesnt use OpenID Connect, it has a proprietary way of configuring into the authentication providers section, so enter those keys if needed in the identity pool authentication providers section.
And that should be enough to make it work.
And no you are not going crazy... the documentation does not match the current IOS SDK. Mobile hub uses the aws-mobilehub-helper-ios (github) which is built on TOP of the sdk, so the documentation does not apply to that either! Mobile Hub Helper has a nice design, so I recommend you use it, rather than the raw SDK.
(and lastly... and I am out of my depth here because I don't use API gateway, but my understanding was that the API Gateway is a way to get credentials to use AWS Services, and with the mobile hub app you will be using Cognito to get those credentials, so I am not sure you will need to bring the API Gateway into it...at all)
UPDATE
You may want to use no client secret for users of your javascript app, and use a IOS Mobile App on the same pool too. This can be done in two ways:
1) The better way is that you create two different client's in the user pool. For one you will generate a client secret, for the other you will UNCHECK the "generate client secret" box.
Then in your Federated Identity Pool you go to Authentication Providers, and click on Cognito, and specify TWO DIFFERENT PROVIDERS USING THE SAME USER POOL ID. (This is not really two different providers, but that is how the console makes you specify it). And you put the two different client ids in those providers.
Now both the IOS app and the Javascript app can access the pool and get authentication and credentials from the identityProvider and credentialsProvider.
2) A not so good way. The reason this way is worse is because I don't know the impact (if any) it has on the security of your mobile app. And at AWS there is nobody to ask the question to without buying a support contract. But the other way exists.
What you do is use the same client id in both apps, and you don't generate a client secret. To do this you put "nil" in the clientSecret. This works fine with some caveats.
First, the AWS Mobile Hub has a bug in it's AWSCognitoUserPoolsSignInProvider. That class requires that the clientSecret is non-null. But in the SDK, the only way to tell the SDK that you want no client secret is to pass nil! However there are workarounds.
(What I did was use the AWSCUPIdPSignInProvider.swift (that I wrote), which will work fine and I have a version that will take a nil for the secret. I did that because it was faster for me to test this out. you can find that signin provider on github if you want to use it)
But a better (more future proof) solution is probably to use the AWSCognitoUserPoolsSignInProvider that the mobile hub delivers, but change the code in AWSMobileClient to configure and register your own pool rather than letting AWSCognitoUserPoolsSignInProvider do it for you.
I haven't bothered to try this, (because we only have to do it because AWS has not gotten around to updating the github aws-mobilehub-helper-ios yet). But basically in AWSMobileClient instead of this code:
func setupUserPool() {
// register your user pool configuration
AWSCognitoUserPoolsSignInProvider.setupUserPoolWithId(AWSCognitoUserPoolId, cognitoIdentityUserPoolAppClientId: AWSCognitoUserPoolAppClientId, cognitoIdentityUserPoolAppClientSecret: AWSCognitoUserPoolClientSecret, region: AWSCognitoUserPoolRegion)
AWSSignInProviderFactory.sharedInstance().registerAWSSignInProvider(AWSCognitoUserPoolsSignInProvider.sharedInstance(), forKey:AWSCognitoUserPoolsSignInProviderKey)
}
you would have something like this code
func setupUserPool() {
// register your user pool configuration
// find the service configuration (we don't know if they set it as default)
let credentialProvider = AWSCognitoCredentialsProvider(regionType: .USEast1 (or your region), identityPoolId: "YourIdentityPoolId")
let configuration = AWSServiceConfiguration(region: .USWest2 (or your region), credentialsProvider: credentialProvider)
// configure and put your own user pool in the service configuration
let userPoolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: AWSCognitoUserPoolAppClientId, clientSecret: nil, poolId:AWSCognitoUserPoolId)
// now we register that pool with the service configuration using the key they use
AWSCognitoIdentityUserPool.register(with: configuration, userPoolConfiguration: userPoolConfiguration, forKey: AWSCognitoUserPoolsSignInProviderKey)
AWSSignInProviderFactory.sharedInstance().registerAWSSignInProvider(AWSCognitoUserPoolsSignInProvider.sharedInstance(), forKey:AWSCognitoUserPoolsSignInProviderKey)
}
But as I said above, solution 1, use two different clients and specify two different providers is preferred.

Non-interactive login (cached credentials) against Azure Graph API on iOS

I am creating an app on iOS that will run in a "kiosk" mode. Part of the application requires users to be able to search an organisation's directory. I would like to support Azure AD via the Azure Graph API to provide this function.
I don't want to require an interactive login when the app starts and I don't want to have to use an additional web service; I would like for the iOS app to simply access the Azure Graph API via REST.
I am aware of the risks associated with cached credentials, however the use of "service accounts" for non-interactive logins is fairly well established, the access is read-only and the credentials can be secured in the iOS keychain.
I have looked through numerous Azure samples and read the documentation and it seems that the method that provides what I need acquireToken(resource, credential) isn't available in the iOS ADAL library (and either is the ClientCredential class).
To clarify, this is how I would like my app to work:
User installs the app from the app store and runs it the first time
As part of the setup they authenticate to Azure AD by providing their tenant, application client ID and an application key. If they can't authenticate with an application key, a user id/password is acceptable as long as:
They never get prompted to authenticate again
Is there a solution here or do I just give up on Azure AD?
This can be done, but not with the ADALiOS framework as it doesn't expose the client_credentials grant that is required to make it work.
I was able to build a working demonstration using p2/OAuth. The sample app is here
The steps to build a working solution are:
Login to the legacy Azure Management portal and select your Azure AD Instance
Create a new application in that AD instance
Select "Add an application my organisation is developing"
Give it a name and select "Web application and/or Web API" not "Native Client Application"
Enter values for sign on url and app id url. These need to be well-formed URLs but do not need to be reachable
Once the application has been created select "Configure". Note the Client ID - you will need this
In the "Keys" selection, select 1 or 2 years from the drop down, then click "Save"
Once the key is displayed, copy this and save it somewhere; it can't be displayed again.
Set the required "Permissions to other applications" to allow your app the access it needs
Finally, at the bottom of the screen click "view endpoints" - You need to copy the OAuth 2.0 Token Endpoint and the OAuth 2.0 Authorization Endpoint
Download the demo code from GitHub
Run pod install
Plug the values into the Settings.plist file
Run the app
The meat of the authentication process is to set up an instance of OAuth2ClientCredentials -
let settings = [
"client_id": appData.clientId!,
"client_secret": appData.secret!,
"authorize_uri": appData.authString!,
"token_uri": appData.tokenString!,
"keychain": true,
"secret_in_body": true
] as OAuth2JSON
self.oauth2 = OAuth2ClientCredentials(settings: settings)
Then you can call doAuthorize() to get a token
self.oauth2.doAuthorize()

Creating Admin Accounts for Domains Created from Reseller API

I am trying to automate the entire process of creating a google apps account through my company's reseller account with google, without any human having to manually enable anything.
Here's a quick scenario of what I am doing.
Create Customer (Domain) with Reseller API
Create Subscription with Reseller API
Create Admin Account for the Sold Domain
I am having trouble automating step 3.
There are 2 different APIs that can accomplish this tast, Provisioning (depricated) and Directory.
I have already successfully created user accounts with the Directory API, but this step requires you to enable API access for that domain, and that can only be done manually by a human - So thats a break in automation flow, and wont work for what I am trying to accomplish.
I was instructed by google tech support to use the Provisioning API, wich is deprecated, because it supposedly allows you to create an admin user without the need to enable the API access manually per domain. When I attempt to do this, I face this error:
Uncaught exception 'Zend_Gdata_App_HttpException' with message 'Expected response code 200, got 403 <HTML> <HEAD> <TITLE>You are not authorized to perform operations on the domain mydomain.com</TITLE>
Here's the code im attempting to run:
// .....
$customerid = "somedomain.com";
$client = Zend_Gdata_ClientLogin::getHttpClient("mylogin#foo.com", "mypassword",Zend_Gdata_Gapps::AUTH_SERVICE_NAME);
$gdata = new Zend_Gdata_Gapps($client, $customerid);
$gdata->createUser('Admin', 'Firstname', 'Lastname', 'somerandompassword', TRUE);
//......
When I consulted google tech support, they told me I needed to enable the provisioning api following the same instruction I posted earlier (enable api access per domain). I have done this on both my reseller domain, and the customer domain Im trying to provision on (just to test, becasue the entire point is to be able to make an admin account WITHOUT enabling it on the customer domain.) - But it still returns this error.
Here's my settings -- as you can see, its enabled.
In google's docs, under "Enabling the Provisioning API", it has some instructions, but they appear to be out of date and dont really reflect sections available in the current google apps admin panel.
Im at a loss. Am I missing something obvious, or is it just not possible to do at this time?
Just for reference, I have found a few other people asking a similar question, but with less detail:
Google Reseller Customer Admin User Creation Admin SDK How
How to create the domain administrator of a Google Apps domain purchased via the reseller API
EDIT: Added image showing settings, and code sample.
try to delete "TRUE" parameter in createUser , it's works for me.
$customerid = "sampledomain.com";
$client = Zend_Gdata_ClientLogin::getHttpClient($email, $password, Zend_Gdata_Gapps::AUTH_SERVICE_NAME);
$gdata = new Zend_Gdata_Gapps($client, $customerid);
var_dump($gdata->createUser('trial', 'Firstname', 'Lastname', 'somerandompassword'));
in Google app console
domain settings ->user settings
check the box "enable API access"
in Google app console --> advanced tools --> Manage third party OAuth Client access
Add the scope :
https://apps-apis.google.com/a/feeds/user

Resources