I have an Airflow DAG that scrapes some data from an external website. The site authenticates first with username and password, then challenges with a 2fa token. Is there a way to have an Airflow DAG pause in the middle and wait for user input for the 2fa token value?
I've thought that maybe using a Sensor might work, either a Task or File Sensor, but I haven't been able to get that to work so far (sorry, new to Airflow!). It feels like that should work in theory, but I'm not sure if there is an easier approach.
Thanks!
Related
I'm trying to find a way to retrieve my company updates feed. The question is, is it possible without user login/ interaction?
When searching the docs I found https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api to retrieve this information. But if I'm correct, you can't do this without first logging in (r_organization_social requires 3-legged).
Is there another endpoint that could do this with only a key/secret? Or is the only way for this to work, login and make a cronjob that automatically refreshes the token. With the downside that I need to login again if the cronjob fails.
Some other relevant info, when trying to generate an application token I get the following error "This application is not allowed to create application tokens". But I think this is normal because a 2-legged OAuth is not available for Marketing APIs.
to summarize:
I want company updates feed without user interaction
Maybe using the wrong endpoint
Maybe something wrong with the app creation
Maybe something wrong with generating Application key
Credential docs used: https://learn.microsoft.com/en-us/linkedin/shared/authentication/client-credentials-flow
Since I have noticed that once a user signs in with email and password, on reopening the application the session will not have expired and there is no need for a new authentication, I wish to avoid this.
I want to automatically .signOut() a user when .onDisconnect is triggered. How can I achieve this? I have tried with the following code, but unsuccessfully:
firebase.auth().onDisconnect().signOut();
When you say "onDisconnect", I'm assuming that you mean Realtime Database onDisconnect triggers.
The first thing to know about onDisconnect is that it triggers when the socket connection between Realtime Database and the client app is closed. This could happen for any number of reasons, and it can happen at any time, even if the app seemingly has a good internet connection. So, be careful about what you're trying to do here.
Also, onDisconnect triggers can only affect data in the database directly, and nothing else. So, this limits what you can effectively accomplish. You can't perform any action in the client app in response on an onDisconnect.
Between these two facts, what you're trying to do isn't really possible, and, I don't think it's desirable. You could end up logging out the user just because their train went underground momentarily, or if they simply switched out of the application for some time. This would be massively inconvenient to the user.
If you want to automatically log out the user, I strongly suggesting finding some other way to do this, such as writing some code to remember how long it's been since the user used your app, and forcing the logout on the on the client app based on your preferred logic.
The onDisconnect() is related to the database connection, and has little to do with your authenticated user. As in: onDisconnect() may fire when your user is signed in, simply because the connection to the database drops temporarily.
But more importantly: onDisconnect handlers run server-side, once the server detects that the client has disappeared. When this is because if a dirty disconnect (e.g. the app crashes), there is no way for the client to detect this anymore.
The most likely approach you'll want is to simply sign the user out when they close the app.
Alternative you might want to attach a listener to .info/connected in your client. This is a client-side listener that fires when the client detects that it is connected or disconnected.
The following quote is taken from Google Developer Blog. https://developers.googleblog.com/2017/08/hamilton-app-takes-stage.html
For example, when someone enters the lottery, the app first writes
data to specific nodes in Realtime Database and the database's
security rules help to ensure that the data is valid. The write
triggers a Cloud Function, which runs business logic and stores its
result to a new node in the Realtime Database. The newly written
result data is then pushed automatically to the app.
I understand that instead of making a request and expecting a request, they followed the following pattern:
Write to real-time database
The write trigger an action
The action triggers some logic and function
The function writes data back to the database
The listener on the app gets a notification about the data written on 4.
App updates UI or takes whatever action.
Hamilton app followed this pattern when someone enters the competition for a ticket. My main concern with the pattern is that if the connection is offline, we won't get results and at the same time we won't get an error. The changes will be updated locally and firebase will update the next time there is a connection, which will make things messy, as the user is expecting a result.
I was wondering if there is an easy way or a pattern to follow, so we will get an error and display it.
The first solution that comes to my mind is to somehow add a time on the save operation. If the save is not done on the live database within x seconds then we display an error. At the same time, we will also need a timeout on the reply. So if we do not get a reply within x seconds we display something to the user.
I hope I am not confused as I did not understand the pattern well. I struggled with the title, so if anyone can improve it, please be my guest.
Even building an offline capable app, if an operations chain relies on a Cloud Function, I'd make it impossible to execute while offline, telling user to retry when he's online.
However this might lead to bad situations as well because you need to check connection every time the user tries to execute the ops, which might be painful.
Update: Due to code refactor, the need for testing that has gone away, and as Ron pointed out in the accepted answer, onAuthStateChange() will fire eventually, and the app can rely on that. I wasn't originally seeing that, which is what motivated my question.
Original Question: I've been using window.localStorage and searching for a key that starts with 'firebase:authUser' as a way to determine if my app can expect a firebase authentication event any time soon. Whether it succeeds or fails, firebase.auth().onAuthStateChanged() is triggered, and I can deal with the result there. The reason for wanting to know is that if I have some local credentials which are being processed, my app can display a 'Please wait...' type message. But if there are none, it can redirect immediately to the login page. Since firebase moved to indexedDB, this code no longer works, and I couldn't find any equivalent hack to look for locally persisted credentials (maybe it's not possible now?).
I'd also be happy to switch to SESSION persistence rather than LOCAL, but I'm not sure if this changes the scenario at all—I'd still need a way to test if there was anything happening to avoid the user being stuck at the 'Please wait...' message forever if there were no local credentials to validate.
Or am I doing this wrong? I know I could show the login page until firebase.auth().onAuthStateChanged() fires, but by then the user might have clicked, and the experience isn't that great either if they already signed in and then refresh the page, where they see the login page again until everything is loaded.
I couldn't find anything in the auth() API to tell if it was in the process of dealing with locally persisted credentials, and up until now, the window.localStorage hack has been working very well. What's the best way to manage the user experience now?
You could grey out inputs and disable submit button until .onAuthStateChanged resolves which happens very quickly, usually in under 1 second. Maybe put a linear progress indicator on the login form?
Relying on underlying implementation is never a good idea instead of provided public API. Firebase has the right to change that at any time. They could have even persisted the user with a different format and that would break your implementation.
That said, you can easily bypass this, by setting your own flag in localStorage when a user logs in and remove it when they sign out. This is better than relying on the hack you had. In this case, you have full control over that flag. You set it anytime a user is signed in after onAuthStateChanged is triggered and remove it on sign out. When a page is loaded you read that value directly to know whether to display the progress bar or not.
I have an e2e test for a rather large application. It offers multiple ways of authenticating an user, one of which is using a google account by aquiring a OAuth2 token. Today it runs naively by manipulating the logon page that pops up and enters the logon details.
As expected, at some point google decided to throw this in my face:
How can I skip the manual logon procedure, grab an Oauth token and procede to my redirect url, and verify that I indeed arrive at the correct place in my application with selenium?
Offline authentication seems to be what I am looking for, however webdriver cannot do POST requests. I am able to acquire the token manually, but there's no way to pass it on to webdriver in any meaningful way as it still can't do anything with it.
If possible I would prefer to not touch the application codebase.
I am using webdriverio as my webdriver implementation, running as a nodejs task. Interestingly the robot filter appears rarely on my local machine, but seems to always trigger on the circleci instance it's run on.
I'm simply using my app endpoint to get a token from google, then using the JavaScript executor I set the token in the local storage.
Something like this.
driver.manage().deleteAllCookies();
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("window.localStorage.setItem('token', ' " + apiRequest.getToken() + "');");
I hope this is what are you looking for.