user without MFA in google workspace - google-api

I want to know if we can pull out any data from the users in google workspace who don't have multi factor authentication, also can we pull anything from admin API in Google Workspace like the list of users or anything for the users without MFA?

Yes it is possible. You can use the Directory API to do this with the users.list method and with a simple query checking the value from the isEnrolledIn2Sv parameter you can list all the users that have not set up MFA in their accounts.
As an example you can use the following script from Google Apps Script using the Directory API and the suggested methods:
function usersNotEnrolled() {
let request = {
"customer": "my_customer",
"query": "isEnrolledIn2Sv=false"
};
let userList = AdminDirectory.Users.list(request);
for(let i=0; i<userList.users.length; i++)
{
Logger.log(userList.users[i].primaryEmail);
}
}
References:
Method: users.list
Query parameter: isEnrolledIn2Sv

Related

Plaid Api wont let me authenticate account with account/routing number

Using Plaid version "2020-09-14". I am following these instructions https://plaid.com/docs/auth/coverage/same-day/
I'm using node js to generate a link token and i successfully do:
var plaid = require('plaid');
const client = new plaid.Client({
clientID: process.env.PLAID_CLIENT_ID,
secret: process.env.PLAID_SECRET,
env: process.env.PLAID_ENV
});
console.log('client is ',client)
app.post('/api/create_link_token', async function (req, res) {
try{
const response = await client.createLinkToken({
user: {
client_user_id: '123-test-user-id',
},
client_name: 'Plaid Test App',
products: ['auth'],
country_codes: ['US'],
webhook: 'https://webhook.example.com',
language: 'en'
})
return res.send({link_token: response.link_token})
} catch (error) {
// handle error
console.log('error',error)
return res.send({err: error.message})
}
});
I get a link token everytime I run this. Then, i use said link token to try to authenticate the user's bank by using same day micro deposits (my company is setup for this through Plaid).
What keeps happening is the screen pops up that asks you to search for your bank and I do not want that. I want the screen to popup just like the one at the top of the page in the link I listed above. It asks the user for their name first, then routing, then account numbers.
How do I make the Plaid api show me the screen that prompts the user for their accounting/routing numbers without trying to authenticate them automatically with their bank username and password?
Thanks
You can't, at least right now, using publicly released Plaid APIs. (You're not the first person to ask for this, and we're working on some stuff that should help, but it isn't yet available to the developer general public.)

Call cloud code without logged in user Parse Server JS SDK

Is it possible to call a cloud function that returns objects without having a current user? The iOS and Android SDKs support anonymous users but I'm asking specifically for JavaScript.
I'd like to allow it so that anyone who visits my web app can read objects without having to sign in. I'm using Back4App.
Yes. You can call a cloud code function no matter the user is logged in or not. Inside the cloud function you can check the user property of the request object to check if the user is either logged in or not. In the case that your user is not logged in and you want to query a class which requires user permission, you can use the useMasterKey option.
Parse.Cloud.define('myFunction', async req => {
const { user, isMaster } = req;
if (isMater) {
// the cloud code function was called using master key
} else if (user) {
// the cloud code function was called by an authenticated user
} else {
// the cloud code function was called without passing master key nor session token - not authenticated user
}
const obj = new Parse.Object('MyClass');
await obj.save(null, { useMasterKey: true }); // No matter if the user is authenticated or not, it bypasses all required permissions - you need to know what you are doing since anyone can fire this function
const query = new Parse.Query('MyClass');
return query.find({ useMasterKey: true }) // No matter if the user is authenticated or not, it bypasses all required permissions - you need to know what you are doing since anyone can fire this function
});

Migrating User to Cognito on Sign In

I am trying to migrate users to Cognito when they sign in the first time. For this I wrote a lambda function that does call an API to check if the users exist in db or not ? if the user exists, it will be created in cognito but I am not sure how do I tell the application that user is created and it should allow the user to login .
Here is the code in c#:
public async Task<Stream> FunctionHandlerAsync(Stream stream, ILambdaContext context)
{
RootObject rootObj = DeserializeStream(stream);
User user = new User(rootObj.userName, rootObj.request.password);
ApiResponse apiResponse = await MobileAuthenticateAsync(user.UserName, user.Password);
// Considering apiResponse returns "user authenticated", we create the user in //cognito. This is working.
// How do I send response back to Application so it knows that user is // //created and authenticated and should be allowed to login.
//Before returning stream, I am setting following 2 status.
rootObj.response.finalUserStatus = "CONFIRMED"; // is this correct ?
rootObj.response.messageAction = "SUPPRESS";
return SerializeToStream(rootObj);;
}
You're pretty close.
You can see the full documentation on the Migrate User Lambda Trigger page, however in short you need your response to look like:
{
response: {
userAttributes: {
email: 'user#example.com',
email_verified: true,
custom:myAttribute: 123,
},
finalUserStatus: 'CONFIRMED',
messageAction: 'SUPPRESS',
forceAliasCreation: false,
}
}
Where:
userAttribute: this is a dictionary/map of the user's attributes keys in cognito (note that any custom attributes need to be prefixed with custom:), to the values from the system you're migrating from. You do not need to provide all of these, although if you're using an email alias you may want to set email_verified: true to prevent the user having to re-verify their e-mail address.
finalUserStatus: if you set this to CONFIRMED then the user will not have to re-confirm their email address/phone number, which is probably a sensible default. If you are concerned that the password is given as plain-text to cognito this first-time, you can instead use RESET_REQUIRED to force them to change their password on first sign-in.
messageAction: should probably be SUPPRESS unless you want to send them a welcome email on migration.
forceAliasCreation: is important only if you're using email aliases, as it stops users who manage to sign-up into cognito being replaced on migration.
If you respond with this (keeping the rest of the original rootObj is convenient but not required then the user will migrated with attributes as specified.
If you throw (or fail to respond with the correct event shape) then the migration lambda fails and the user is told that they couldn't migrated. For example, because they do not exist in your old user database, or they haven't provided the right credentials.

Update viewer fields and connection on Store

I'm trying to update the values and connections on my current viewer within the Relay store.
So without calling the mutation signIn if I print:
console.log(viewer.name) // "Visitor"
console.log(viewer.is_anonymous) // true
on Mutations we got the method updater which gives us the store, so in my mutation I'm doing something like this:
mutation SignInMutation($input: SignInInput!){
signIn(input: $input){
user {
id
name
email
is_anonymous
notifications{
edges{
node {
id
...NotificationItem_notification
}
}
}
}
token
}
}
So my updater method has:
const viewer = store.get(viewer_id);
const signIn = store.getRootField('signIn');
viewer.copyFieldsFrom(signIn.getLinkedRecord('user'))
After this I updated the store I got the name email is_anonymous fields updated with the data that just came from the graphql endpoint (I mean now name is "Erick", is_anonymous is now false, which is great), but If I try to do viewer.notifications and render it, the length of the viewer.connections seem to be 0 even when it has notifications.
How can I update my current viewer and add the notifications from the MutationPayload into the store without the need to force fetch?
Im using the latest relay-modern and graphql.
PS: Sorry for the bad formation, but is just impossible to format the code the way OF wants me to, i formated it to 4 spaces and still gave me errors.
With some reorganisation of your GraphQL schema it might be possible to remove the need to interact directly with the Relay store after your sign-in mutation. Consider:
viewer {
id
currentUser {
name
email
}
}
When a user that is not logged in, currentUser would return null.
You could then modify your login mutation to be:
mutation SignInMutation($input: SignInInput!){
signIn(input: $input){
viewer {
id
currentUser {
name
email
token
}
}
}
}
Knowing the 'nullability' of the currentUser field provides an elegant way of determining if the user is logged in or not.
Based on the presence of the token field implies that you are using JWT or similar to track login status. You would need to store this token in local storage and attach it to the headers of the outgoing Relay requests to your GraphQL endpoint if it is present.
Storing the token itself would have to be done in the onCompleted callback of where you make the mutation request (you will have access to the payload returned by the server in the arguments of the callback function).
As an alternative to the token, you could also explore using cookies which would provide the same user experience but likely require less work to implement then JWT tokens.

How to call web API under specific user permission?

I have a function that allows the end user to execute a Workflow (containing many APIs) or schedule it to run as a background job.
Example: User1 creates Workflow1, which contains 3 APIs (Api1, Api2, Api3), and configures it to run at 9AM every day.
I use HttpClient to call each API like this:
var client = new HttpClient { BaseAddress = new Uri("http://localhost/") };
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.PostAsJsonAsync("/api/services/myApp/workflow/Api1?input=something", "").Result;
How do I add the credentials of User1 to the request while the user is not logged in to the application (because it will run automatically as a scheduled job)?
Update 1
I decided to use reflection to call an API by string name.
In the case of executing an API directly, how do I run it under a specific permission?
Update 2
I have put my code inside a using block, but all APIs were fired successfully:
using (_session.Use(1, 3)) // 3 is the Id of User1, who has no permissions
{
// Execute operator
switch (input.Operator.Type)
{
case "api":
executeApiResult = await ExecuteApi(input);
break;
case "procedure":
executeApiResult = await ExecuteProcedure(input);
break;
default:
return new ExecuteOperatorOutput
{
Result = new ExecuteOperatorResult { Status = false, Message = $"Wrong operator type: {input.Operator.Type}" },
WorkflowStatus = false
};
}
}
In the case of executing an API directly, how do I run it under a specific permission?
You can override current session values and call your method inside the using block.
I have put my code inside a using block, but all APIs were fired successfully
Declare your API methods as public virtual as there are some restrictions for AbpAuthorize.
You have two options.
1- You can make those Application Services anonymously accessible. And if you want it to be secure, send an encrypted security token.
2- You didn't mention if your project is MVC or Angular. I assume you have Angular version. You need a bearer token to make authenticated requests. First you have to authenticate user and get a token. Then add this bearer token to every request.
You have to research for using bearer tokens in asp.net core...

Resources