I am developing a python program which uses the gmail api to access the email data.
I have successfully developed the tutorial program and I am able to access the gmail data and do a lot of interesting things.
At the moment, I have to get the .json file from the gmail account, modify the code, run it, and then ask the user to get a verification code from the web browser, to finally authenticate the app so it can start running.
Now, my question is: how can I make the authentication process easier for the end-user?
It seems to me like this process is during the development of the software, but what if I have finished my development process and I want to make the app commercially/freely available to other users so they can start poking around with it?
Isn't there a way to quickly modify my software to make that process easier for the end user?
Any kind of help is well received, sorry if this had been asked before.
Related
Im creating a server in Python that receives POST requests, process the information in the request using some scripts (sometimes using a database) and send back a answer in JSON format. Im searching for a way to run this server and code in the cloud, in a way that i dont need my PC turned on for it to work, because my connection is very unstable.
There are a lot of web hosting companies out there, you just need to find the one that is right for you.
My personal favorite for python apps is heroku, but there are many out there. AWS is another popular one.
In future when asking questions, try to do more research before hand, and try to be more specific with questions. It would have been useful to know what kind of database you are using, or whether you're using flask or django.
TLDR: I have a slack app for managing private channels in its development workspace and tokens for it that inherit my user privileges. How can someone else in the same workspace obtain tokens for this app that inherit their user privileges instead?
Ok, so the background of this is: i need to manage the membership of a bunch of private channels based on some more or less complicated ldap-related conditions. For this, i wanted to write a simple Python program that got the membership of the channels in question, did its ldap magic to figure out who should be where, and then make it so.
I have implemented this and all works fine so far. The issue now is that i (that is my slack user) cannot be in all of these channels for privacy reasons. The API and Bot tokens i have obtained inherit all of my own user privileges. That means i can neither see nor administrate the channels that i'm not a part of.
Based on what i've read in the documentation of the Slack API, there's a way to have another user go through the OAuth process for the app that i created to get the tokens, get their own tokens, and use them with the Python program that i wrote. That would be fine, but i can't figure out how to do this.
Noone else has access to the app directly. The documentation makes it seem like i need to give people a specially formatted link (the "Add to Slack Button") that they can click on to get taken through the process. But that seems to require a "redirect URL". I'm not sure what this is and the documentation isn't very clear on it, but it seems they are assuming that the app is running on a server somewhere and will need to answer requests from Slack or something. That's not the case. It's a fairly simple Python script, not some always-up cloud app that will be responding to Slack Events.
So it feels like i'm missing something. Either i have some fundamental misconception about how this is supposed to work, or there is a simple way for someone else to get a token like that and i'm not seeing it.
Yes. If you want other users to authenticate your app (e.g. generate tokens so your app can perform tasks on the users behalf) you need to create an installation routine using Ouath 2.0. That installation routine is a small web app that has the "Add to Slack" button, a HTML interface and is able to run through the Oauth 2.0 process. That web app needs to run on a public web server.
For development purpose that web server can also run on your local dev machine with a VPN tunnel to the public Internet. Slack recommends using the VPN service ngrok for that purpose.
I created a Flask-Webservice with Python that runs independently inside a docker container. I then uploaded the docker image to an Azure Container Registry. From there I can create a WebService (for Containers) with some few clicks in the Azure Portal, that runs this container. So far so good. It behaves just as I want it to.
But of course I don't want anyone to access the service. So I need some kind if authentication. Luckily (or so I thought) there is a built-in authentication-mechanism (I think it is based on OAuth ... I am not that well versed in security issues). Its documentation is a bit sparse on what actually happens and also concentrates on solutions in C#.
I first created a project with Google as described here and then configured the WebApp-Authentication with the Client-Id and Secret. I of course gave Google a java script source and callback-url, too.
When I now log off my Google account and try a GET-Request to my Webservice in the Browser (the GET should just return a "hello world"-String), I am greeted with a Login Screen ... just as I expected.
When I now login to Google again, I am redirected to the callback-url in the browser with some kind of information in the parameters.
a token perhaps? It looks something like this:
https://myapp.azurewebsites.net/.auth/login/google/callback?state=redirxxx&code=xxx&authuser=xxx&session_state=xxx&prompt=xxx).
Here something goes wrong, because an error appears.
An error occurred.
Sorry, the page you are looking for is currently unavailable.
Please try again later.
If you are the system administrator of this resource then you should check the error log for details.
Faithfully yours, nginx.
As far as I now, nginx is a server software that hosts my code. I can imagine that it also should handle the authentication process. It obviously lets all requests through to my code when authentication is turned off, but blocks un-authenticated accesses otherwise and redirects to the google login. Google then checks if your account is authorized for the application and redirects you to the callback with the access token along with it. This then returns a cookie which should grant my browser access to the app. (I am just reproducing the documentation here).
So my question is: What goes wrong. Does my Browser not accept the cookie. Did I something wrong when configuring Google+ or the Authentication in the WebApp. Do I have to use a certain development stack to use the authentication. Is it not supported for any of the technologies I use (Python, Flask...).
EDIT
#miknik:
In Microsofts documentation of the authentication/authorization it says
The authentication and authorization module runs in the same sandbox
as your application code. When it's enabled, every incoming HTTP
request passes through it before being handled by your application
code.
...
The module runs separately from your application code and is
configured using app settings. No SDKs, specific languages, or changes
to your application code are required.
So while you are probably right that the information in the callback-redirect is the authorization grant/code and that after that this code should now be used to get an access token from Google, I don't quite understand how this would work in my situation.
As far as I can see it Microsofts WebApp for Container-Resource on Azure should take care of getting the token automatically and return it as part of the response to the callback-request. The documentation states 4 steps:
Sign user in: Redirects client to /.auth/login/.
Post-authentication: Provider redirects client to /.auth/login//callback.
Establish authenticated session: App Service adds authenticated cookie to response.
Serve authenticated content: Client includes authentication cookie in subsequent requests (automatically handled by browser).
It seems to me that step 2 fails and that that would be exactly what you wrote: that the authorization grant is to be used by the server to get the access token but isn't.
But I also don't have any control over that. Perhaps someone could clear things up by correcting me on some other things:
First I can't quite figure out which parts of my problem represent which role in the OAuth-scheme.
I think I am the Owner, and by adding users to the list in the Google+-Project I authorize them to use my service.
Google is obviously the authorization server
my WebService (or better yet my WebApp for Containers) is the resource server
and finally an application or postman that does the requests is the Client
In the descriptions of OAuth I read the problematic step boils down to: the resource server gets the access token from the authorization server and passes it along to the client. And Azures WebApps Resource is prompted (and enabled) to do so by being called with the callback-url. Am I right somewhere in this?
Alas, I agree that I don't quite understand the whole protocol. But I find most descriptions on the net less than helpful because they are not specific to Azure. If anyone knows a good explanation, general or Azure-specific, please make a comment.
I found a way to make it work and I try to explain what went wrong as good as I can. Please correct me if I go wrong or use the wrong words.
As I suspected the problem wasn't so much that I didn't understand OAuth (or at least how Azure manages it) but the inner workings of the Azure WebApp Service (plus some bad programming on my part). Azure runs an own Server and is not using the built-in server of flask. The actual problem was that my flask-program didn't implement a WSGI-Interface. As I could gather this is another standard for python scripts to interact with any server. So while rudimentary calls from the server (I think Azure uses nginx) were possible, more elaborate calls, like the redirect to the callback url went to dev/null.
I build a new app following this tutorial and then secured it by following the authentication/authorization-tutorial and everything worked fine. The code in the tutorial implements WSGI and is probably more conform to what Azure expects. My docker solution was too simple.
My conclusion: read up on this WSGI-standard that flask always warned me about and I didn't listen and implement it in any code that goes beyond fiddeling around in development.
I'm new to OAuth and API's but have been trying to figure out the upload_video.py script that is provided by Google (https://developers.google.com/youtube/v3/guides/uploading_a_video) to upload videos to my channel via Python.
My problem is I can't figure the OAuth, so I'm calling the script with the necessary arguments, but then getting re-directed to an authentication page in my browser.
This script needs to be run completely invisibly from command line and so, that doesn't work for me.
Can anybody point me in the right direction for not having to authenticate the script manually each time it's running?
I was hoping there would be an option for this in the Google dev console, to allow this kind of thing, but it doesn't appear so.
Your program will have to at some point use a browser to complete the OAuth2 flow - it's unavoidable. The script google provides on that page does store the token in a local file, so that your program won't need to go through the process again every time it runs, as long as the token is still valid. You can also get your program to ask for a new token when the one it has expires, though I'm not sure if that script actually does that or not.
See: https://developers.google.com/accounts/docs/OAuth2ForDevices for information about the OAuth2 flow on devices that aren't capable of launching a browser themselves.
I'm looking for a bit of web development advice. I'm fairly new to the area but I'm sure there are some gurus out there willing to part with some wisdom.
Objective: I'm interested in controlling a Python application on my computer from my personal web hosted site. I know, this question has been asked several times before but in each case the requirements were a bit different from my own. To reduce the length of this post I'll summarize my objective in a few bullet points:
Personal site is hosted by a web hosting company
Site uses HTML, PHP, MySQL, Python and JavaScript, the majority of everything is coded by me from the ground up
An application that is coded in Python will run on a PC within my home and will communicate with an Arduino board
The app will receive commands from the internet to control actuation via the Arduino, and will transmit sensor data back to the site (such as temperature)
Looking for the communication to be bi-directional, fast and secure
Securing the connection between site and Python app would be most ideal
I'm not looking to connect to the Python application directly, the web server must serve as the 'middle man'
So far I've considered HTTP Post and HTML forms, using sockets (Python app would run as a web server), an IRC bot and reading/writing to a text file stored on the web server.
I was also hoping to have a way to communicate with the Python app without needing to refresh the webpage, perhaps using AJAX or JavaScipt? Maybe with Flash?
Is there something I'm not considering? I feel like I'm missing something. Thanks in advance for the advice!
Just thinking out loud for how I would start out with this. First, regarding the website itself, you can just use what's easiest to you, or to the environment you're in. For example, a basic PHP page will do just fine, but if you can get a site running in Python as well, I'd prefer using the same language all over.
That said, I'm not sure why you would need to use a hosted website? Given that you're already forced to have a externally accessible PC at home for the communication, why not run a webserver on that directly (Apache, Nginx, or even something like CherryPy should do)? That webserver can then communicate with the python process that is running to control your Arduino (by using e.g. Python's xmlrpclib). If you would run things via the hosting company, you would still need some process that can handle external requests securely... something a webserver is quite good at. Just running it yourself gives you all the freedom you want, and simplifies things by lessening the number of components in your solution.
The updates on your site I'd keep quite basic: commands you want to run can be handled in the request handlers of the webserver by just calling the relevant (xmlrpclib) calls. Dynamically updating the page is best done by some AJAX calls I reckon. Based on your story, these updates are easily put in a JSON object, suitable for periodically updating only the relevant segments of your page.