My webservice with oauth2client don't work on remote server, - django

The django app runs on the local server, but does not work on the remote.
The server does not have a GUI and does not provide the user with a link to authorization. The server outputs link to the console.
from __future__ import print_function
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
import datetime
import os
import json
SCOPES = 'https://www.googleapis.com/auth/calendar'
from .models import Aim
try:
import argparse
flags = tools.argparser.parse_args([])
except ImportError:
flags = None
def calendar_authorization(username):
store = open('app/static/secret_data/' + username +'.json', 'w')
store.close()
store = file.Storage('app/static/secret_data/' + username +'.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('app/client_secret.json', SCOPES)
flags.noauth_local_webserver = True
print("________flow_______")
print(flow.__dict__)
creds = tools.run_flow(flow, store, flags)
print("________creds_______")
print(creds.__dict__)
In the local version, I use client_secret.json, obtained from OAuth 2.0 client IDs. I suspect that I may have the wrong settings for this.
I found the information to use the Service account keys(I don't use it now). But I didn’t find a good setup guide for this.
How to set it up and paste in the code for authorization(
I did not understand how the access service key is used in the code?)?
What could be wrong?

Related

Problem connecting Cloud Run Flask app with Cloud SQL Postgress

I'm very new on GCP and I've tried everything around to achieve this connection, my app connects to any other postgress service but not to Cloud SQL.
I've started to think that is a problem with my code in flask.
So far I have followed this guide:
https://cloud.google.com/sql/docs/postgres/connect-run#public-ip-default
and watched some Youtube Tutorials.
Maybe my problem is in the Cloud Proxy Auth.
MyCode looks like this:
import os
from os.path import join, dirname
from flask import Flask
from flask_cors import CORS
from flask_restful import Api
from flask_jwt_extended import JWTManager
from flask_bcrypt import Bcrypt
from flask_migrate import Migrate
from constants import ACTIVE_SCHEDULER
from db import db
from ma import ma
from resources.routes import initialize_routes, initialize_errors, initialize_cli
from sched import init_scheduler
app = Flask(__name__)
db_user = os.environ.get("DB_USER")
db_pass = os.environ.get("DB_PASS")
db_name = os.environ.get("DB_NAME")
unix_socket_path = os.environ.get("INSTANCE_UNIX_SOCKET")
db_url = 'postgresql+pg8000://{user}:{pw}#/{db}?unix_sock={path}/.s.PGSQL.5432'.format(user=db_user,pw=db_pass,db=db_name, path=unix_socket_path)
app.config["SQLALCHEMY_DATABASE_URI"] = db_url
app.config["SECRET_KEY"] = os.environ.get('JWT_SECRET_KEY', '')
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["PROPAGATE_EXCEPTIONS"] = True
and the error that I always get is:
"error": "(pg8000.exceptions.InterfaceError) Can't create a connection to host 172.17.0.1 and port 5432 (timeout is None and source_address is None). (Background on this error at: https://sqlalche.me/e/14/rvf5)"
I'm out of ideas, I hope anyone knows any guide or solution to my problem, Maybe I'm missing some access to the service account, but I think I follow correctly the instructions I even try to connect Privately with the TCP instructions and is almost the same.

Django Rest Framework with Firebase Firestore - API endpoint returns NoneType due to initialize_app runs more than once

I'm trying to build a read-only API that fetches its data from Firebase, Firestore. I'm having an issue when I request any endpoint in my API, multiple times, I get an error.
I won't include Django related files and classes. So, here are the code pieces you need to know.
firebase_initilizer.py
import firebase_admin
from firebase_admin import credentials, firestore
if not firebase_admin._apps:
cred = credentials.Certificate('./FILE_PATH.json')
firebase_admin.initialize_app(cred)
db = firestore.client()
collection_ref = db.collection(u"collection-name")
docs = collection_ref.stream()
views.py [A simplified version of what I use in one of my API endpoints]
class Contact(APIView):
"""
Returns the user's contact details.
"""
def get(self, request, uid, format="json"):
for doc in docs:
if uid == doc.id:
return Response(data=doc.to_dict()["contact"], status=status.HTTP_200_OK)
Again, the issue is that I get an error saying "NoneType" whenever I request any endpoint more than once. At this point, I can run my API only once.
The error:
AssertionError at /api/v1/contact/
Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'NoneType'>`
"GET /api/v1/contact/ HTTP/1.1" 500 78864
From what I know, I need to initialize Firebase only once. Then, I only need to request whatever I want by using the variable I assigned the Firebase reference. However, I don't know how to do it
I solved my problem by inserting my firebase initializer code piece into manage.py. Plus, it also works in settings.py.
For example, the manage.py file can be rearranged as follows:
import os, sys
import firebase_admin
from firebase_admin import credentials, firestore
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings')
try:
from django.core.management import execute_from_command_line
if not firebase_admin._apps:
cred = credentials.Certificate('./FILE_PATH.json')
firebase_admin.initialize_app(cred)
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
or you can simply add the following lines to anywhere in settings.py:
import firebase_admin
from firebase_admin import credentials
if not firebase_admin._apps:
cred = credentials.Certificate('./FILE_PATH.json')
firebase_admin.initialize_app(cred)
I hope this answer helps others.

flask-security: how to use in blueprint/extension app pattern?

I want to use flask-security.
I'm using a template flask app which creates global objects for extensions, and then initialises them when the app is created.
e.g. in extensions.py there is code like this:
from flask_bcrypt import Bcrypt
from flask_caching import Cache ...
from flask_security import Security ...
bcrypt = Bcrypt() ...
security = Security()
and then in app.py a call to register_extensions(app) which uses init_app(app) methods like so:
bcrypt.init_app(app)
security.init_app(app)
and indeed flask-security has an init_app() method. But the documentation says that the Security object needs a DataStore object which needs the User and Role model. It doesn't feel right to import the User and Role model in app.py when so far no other extension needs that.
What is the best practice for using Flask-Security when using the 'large Flask app' model ... I don't find the documentation helpful. It is a simple case when all objects are defined in one place.
Below is what I have.
extensions.py
from flask_sqlalchemy import SQLAlchemy
from flask_security import Security
db = SQLAlchemy()
security = Security()
__init__.py
from .extensions import db, security
from .models import User, Role
def create_app(config_name):
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security.init_app(app, user_datastore)

setting up aws credential in flask

I have been thinking of this, is there anyway to put my credential into
settings.py.
My generator.py is as following
import os
import sys
import collections
import boto
from boto.s3.key import Key
from flask import Flask, render_template, url_for, abort, request
from flask.ext.frozen import Freezer
from werkzeug import cached_property
from werkzeug.contrib.atom import AtomFeed
import markdown
import yaml
from string import strip
...
class Blog(object):
def __init__(self, app, root_dir='',file_ext=None):
self.root_dir = root_dir
self.file_ext = file_ext if file_ext is not None else app.config['POSTS_FILE_EXTENSION']
self._app =app #_ for private and internal
self._cache = SortedDict(key = lambda p: p.date, reverse= True)
self._initialize_cache()
...
app = Flask(__name__)
app.config.from_envvar('SETTINGS_FILE') #configuration file
blog = Blog(app, root_dir= 'posts')
freezer = Freezer(app)
DOMAIN = 'cuboid.example.net'
AWS_ACCESS_KEY_ID = 'ABCDEFGHIJK'
AWS_SECRET_ACCESS_KEY = 'HUIHUGERUGHIUHSIUHH'
currently I cant put the credential in it as the boto does not settings.py Can you tell me if there is a way to work AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY into settings.py?
Create a file called settings.py, place your keys inside of it, load it with import settings and then reference them as settings.AWS_ACCESS_KEY_ID.
However, from a security perspective you should really use IAM Roles instead. They automatically provide temporary keys to each EC2 instance.
http://docs.aws.amazon.com/IAM/latest/UserGuide/roles-usingrole-ec2instance.html

run_flow complains about getting its minimum three arguments

I'm working on a simple script to send emails via the GMail API, and an old script I found to access their SMTP interface wasn't working.
So I used the following script from their quickstart page to start first with reading:
#! /usr/bin/env python
#
import httplib2
from apiclient.discovery import build
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run
CLIENT_SECRET = '.client.json'
OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.readonly'
STORAGE = Storage('gmail.storage')
flow = flow_from_clientsecrets(CLIENT_SECRET, scope=OAUTH_SCOPE)
http = httplib2.Http()
credentials = STORAGE.get()
if credentials is None or credentials.invalid:
credentials = run(flow, STORAGE, http=http)
http = credentials.authorize(http)
gmail_service = build('gmail', 'v1', http=http)
threads = gmail_service.users().threads().list(userId='me').execute()
if threads['threads']:
for thread in threads['threads']:
print 'Thread ID: %s' % (thread['id'])
Running this gives a NotImplementedError as shown in this question.
So I imported and called run_flow instead of run, as I did not install gflags to continue. However, I get the following error:
TypeError: run_flow() takes at least 3 arguments (3 given)
I understand from the linked question that argparse should help. I could add the call to parser that that question uses, but I would have no idea what arguments to pass on the command line.
Anyone successfully implemented something with this who could give some help?
You don't need to pass extra arguments to the command line when using run_flow python.
import argparse
...
from oauth2client import tools
...
from oauth2client.tools import run_flow
...
parser = argparse.ArgumentParser(parents=[tools.argparser])
flags = parser.parse_args()
....
credentials = run_flow(flow, STORAGE, flags, http=http)
Then you can run
python quickstart.py