def test_oauth2(app, user, oauth2_client):
    client_id, client_secret = oauth2_client
    client = WebApplicationClient(client_id)
    host = "https://localhost"
    state = "randomly_text"

    with app.test_client() as provider:
        # login forcefully.
        with provider.session_transaction() as sess:
            sess["user_id"] = user
            sess["_fresh"] = True
        uri = client.prepare_request_uri(host + "/oauth2/authorize", redirect_uri=redirect_uri, state=state)
        uri = uri[len(host) :]
        # step 1: redirect to provider
        response = provider.get(uri, follow_redirects=True)
        assert response.status_code == 200
        # step 2: redirect to client
        response = provider.post(uri, data={"scope": "user", "confirm": "yes"})
        assert response.location.startswith(redirect_uri)
        data = client.parse_request_uri_response(response.location, state=state)
        assert "code" in data
        # step 3: get the token
        body = client.prepare_request_body(code=data["code"], redirect_uri=redirect_uri)
        response = provider.post("/oauth2/token", content_type="application/x-www-form-urlencoded", data=body)
        assert response.status_code == 200
        data = client.parse_request_body_response(response.data)
        assert "access_token" in data
        assert data["token_type"] == "Bearer"
        assert data["scope"] == ["user"]
        # step 4: using token
        pass
    def test_parse_token_response(self):
        client = WebApplicationClient(self.client_id)

        # Parse code and state
        response = client.parse_request_body_response(self.token_json, scope=self.scope)
        self.assertEqual(response, self.token)
        self.assertEqual(client.access_token, response.get("access_token"))
        self.assertEqual(client.refresh_token, response.get("refresh_token"))
        self.assertEqual(client.token_type, response.get("token_type"))

        # Mismatching state
        self.assertRaises(Warning, client.parse_request_body_response, self.token_json, scope="invalid")
        os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
        token = client.parse_request_body_response(self.token_json, scope="invalid")
        self.assertTrue(token.scope_changed)

        scope_changes_recorded = []
        def record_scope_change(sender, message, old, new):
            scope_changes_recorded.append((message, old, new))

        signals.scope_changed.connect(record_scope_change)
        try:
            client.parse_request_body_response(self.token_json, scope="invalid")
            self.assertEqual(len(scope_changes_recorded), 1)
            message, old, new = scope_changes_recorded[0]
            self.assertEqual(message, 'Scope has changed from "invalid" to "/profile".')
            self.assertEqual(old, ['invalid'])
            self.assertEqual(new, ['/profile'])
        finally:
            signals.scope_changed.disconnect(record_scope_change)
        del os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE']
示例#3
0
文件: idan_oauthlib.py 项目: EE/doac
class TestOauthlib(ApprovalTestCase):
    
    def setUp(self):
        super(TestOauthlib, self).setUp()
        
        self.libclient = WebApplicationClient(self.oauth_client.id)
        
        self.authorization_code.response_type = "code"
        self.authorization_code.save()
    
    def test_flow(self):
        self.client.login(username="******", password="******")
        
        request_uri = self.libclient.prepare_request_uri(
            "https://localhost" + reverse("oauth2_authorize"),
            redirect_uri=self.redirect_uri.url,
            scope=["test", ],
            state="test_state",
        )
        
        response = self.client.get(request_uri[17:])
        
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, "doac/authorize.html")
        
        approval_url = reverse("oauth2_approval") + "?code=" + self.authorization_code.token
        
        response = self.client.post(approval_url, {
            "code": self.authorization_code.token,
            "code_state": "test_state",
            "approve_access": None,
        })
        
        response_uri = response.get("location", None)
        
        if not response_uri:
            response_uri = response.META["HTTP_LOCATION"]
        
        response_uri = response_uri.replace("http://", "https://")
        
        data = self.libclient.parse_request_uri_response(response_uri, state="test_state")
        
        authorization_token = data["code"]
        
        request_body = self.libclient.prepare_request_body(
            client_secret=self.oauth_client.secret,
            code=authorization_token,
        )
        
        post_dict = {}
        
        for pair in request_body.split('&'):
            key, val = pair.split('=')
            
            post_dict[key] = val
        
        response = self.client.post(reverse("oauth2_token"), post_dict)
        
        data = self.libclient.parse_request_body_response(response.content)
示例#4
0
    def test_prepare_authorization_requeset(self):
        client = WebApplicationClient(self.client_id)

        url, header, body = client.prepare_authorization_request(
            self.uri, redirect_url=self.redirect_uri, state=self.state, scope=self.scope)
        self.assertURLEqual(url, self.uri_authorize_code)
        # verify default header and body only
        self.assertEqual(header, {'Content-Type': 'application/x-www-form-urlencoded'})
        self.assertEqual(body, '')
    def test_parse_token_response(self):
        client = WebApplicationClient(self.client_id)

        # Parse code and state
        response = client.parse_request_body_response(self.token_json, scope=self.scope)
        self.assertEqual(response, self.token)
        self.assertEqual(client.access_token, response.get("access_token"))
        self.assertEqual(client.refresh_token, response.get("refresh_token"))
        self.assertEqual(client.token_type, response.get("token_type"))

        # Mismatching state
        self.assertRaises(Warning, client.parse_request_body_response, self.token_json, scope="invalid")
示例#6
0
 def authorize(self):
     scope = [
         'https://www.googleapis.com/auth/youtube.upload',
         'https://www.googleapis.com/auth/youtube',
         'https://www.googleapis.com/auth/youtubepartner'
     ]
     client = WebApplicationClient(self.registry['google_oauth_id'])
     self.req.response.redirect(client.prepare_request_uri(
         'https://accounts.google.com/o/oauth2/auth', scope=scope,
         redirect_uri='%s/authorize-google' % self.site.absolute_url(),
         approval_prompt='force', access_type='offline',
         include_granted_scopes='true'))
    def test_parse_grant_uri_response(self):
        client = WebApplicationClient(self.client_id)

        # Parse code and state
        response = client.parse_request_uri_response(self.response_uri, state=self.state)
        self.assertEqual(response, self.response)
        self.assertEqual(client.code, self.code)

        # Mismatching state
        self.assertRaises(errors.MismatchingStateError,
                client.parse_request_uri_response,
                self.response_uri,
                state="invalid")
示例#8
0
文件: idan_oauthlib.py 项目: EE/doac
 def setUp(self):
     super(TestOauthlib, self).setUp()
     
     self.libclient = WebApplicationClient(self.oauth_client.id)
     
     self.authorization_code.response_type = "code"
     self.authorization_code.save()
示例#9
0
def stripe_authorize(request, forening_id):
    # In order to keep the current forening_id in the callback URL, we'll have
    # to save it in the session
    request.session['admin.foreninger.stripe-connect.active-forening'] = forening_id
    forening = Forening.objects.get(id=forening_id)

    # Only admin are allowed to connect a Stripe account
    if not request.user.is_admin_in_forening(forening):
        raise PermissionDenied

    # Prepare Stripe OAuth 2.0 request URI using our oauth client library
    client = WebApplicationClient(settings.STRIPE_TOKEN['client_id'])

    params = {
        'scope': 'read_write',
        'stripe_landing': 'register',
        'redirect_uri': 'https://%s%s' % (
            request.site.domain,
            reverse('admin:foreninger.stripe_callback')),

        'stripe_user[url]': forening.get_active_url(),
        'stripe_user[phone_number]': forening.phone,
        'stripe_user[business_name]': forening.name,
        'stripe_user[business_type]': 'non_profit',

        'stripe_user[physical_product]': 'false',
        'stripe_user[product_category]': 'tourism_and_travel',
        'stripe_user[product_description]': 'Trekking, lodging, outdoor activities',
        'stripe_user[currency]': 'nok',

        'stripe_user[country]': 'NO',
        'stripe_user[street_address]': forening.post_address,
        'stripe_user[zip]': forening.zipcode.zipcode if forening.zipcode is not None else '',
        'stripe_user[city]': forening.zipcode.area if forening.zipcode is not None else '',

        'stripe_user[email]': request.user.get_sherpa_email(),
        'stripe_user[first_name]': request.user.get_first_name(),
        'stripe_user[last_name]': request.user.get_last_name(),
        'stripe_user[dob_day]': request.user.get_birth_date().day,
        'stripe_user[dob_month]': request.user.get_birth_date().month,
        'stripe_user[dob_year]': request.user.get_birth_date().year,
    }

    stripe_request_uri = client.prepare_request_uri(
        settings.STRIPE['endpoints']['authorize'],
        **params)
    return redirect(stripe_request_uri)
示例#10
0
    def test_populate_attributes(self):

        client = WebApplicationClient(self.client_id)

        response_uri = (self.response_uri +
                        "&access_token=EVIL-TOKEN"
                        "&refresh_token=EVIL-TOKEN"
                        "&mac_key=EVIL-KEY")

        client.parse_request_uri_response(response_uri, self.state)

        self.assertEqual(client.code, self.code)

        # We must not accidentally pick up any further security
        # credentials at this point.
        self.assertIsNone(client.access_token)
        self.assertIsNone(client.refresh_token)
        self.assertIsNone(client.mac_key)
示例#11
0
文件: views.py 项目: Andertaker/tvevt
def login_view(request):
    client = WebApplicationClient(VK_APP_ID)
    vk_uri = client.prepare_request_uri('https://oauth.vk.com/authorize',
                           scope=['notify'],
                           redirect_uri='http://localhost/vk_register',
                           v='5.17')

    context = {'vk_uri': vk_uri}
    
    '''
    На FaceBook времени не хватило вообщем
    
    client = WebApplicationClient(FACEBOOK_APP_ID)
    fb_uri = client.prepare_request_uri('https://www.facebook.com/dialog/oauth',
                           redirect_uri='http://localhost/fb_register')

    '''

    context = {'vk_uri': vk_uri, 'fb_uri': '#'}
    return render(request, 'tvevt/login.html', context)
示例#12
0
def index(request):
    client = WebApplicationClient(settings.GITHUB_CLIENT_ID)

    if not request.GET.has_key('code'):
        # todo - also setup hook for repo
        # todo - check http referrer = 'https://github.com/'
        uri = client.prepare_request_uri(AUTHORIZATION_URL, redirect_uri=request.build_absolute_uri(reverse('index')),
                                   scope=['repo'])
        context = {'uri': uri}
    else:
        code = request.GET['code']
        body = client.prepare_request_body(code=code, client_secret=settings.GITHUB_CLIENT_SECRET)
        headers = {'Accept': 'application/json'}
        response = requests.post(REQUEST_TOKEN_URL, body, headers=headers)
        response = response.json()
        owner = Github(response['access_token']).get_user()
        # todo - check if user already exists => show repo settings
        token = GithubToken(owner=owner.login, access_token=response['access_token'], scope=response['scope'])
        token.save()
        context = {'owner': owner.name}
    return render(request, 'benchmarks/index.html', context)
    def test_request_body(self):
        client = WebApplicationClient(self.client_id, code=self.code)

        # Basic, no extra arguments
        body = client.prepare_request_body(body=self.body)
        self.assertFormBodyEqual(body, self.body_code)

        rclient = WebApplicationClient(self.client_id)
        body = rclient.prepare_request_body(code=self.code, body=self.body)
        self.assertFormBodyEqual(body, self.body_code)

        # With redirection uri
        body = client.prepare_request_body(body=self.body, redirect_uri=self.redirect_uri)
        self.assertFormBodyEqual(body, self.body_redirect)

        # With extra parameters
        body = client.prepare_request_body(body=self.body, **self.kwargs)
        self.assertFormBodyEqual(body, self.body_kwargs)
    def test_auth_grant_uri(self):
        client = WebApplicationClient(self.client_id)

        # Basic, no extra arguments
        uri = client.prepare_request_uri(self.uri)
        self.assertURLEqual(uri, self.uri_id)

        # With redirection uri
        uri = client.prepare_request_uri(self.uri, redirect_uri=self.redirect_uri)
        self.assertURLEqual(uri, self.uri_redirect)

        # With scope
        uri = client.prepare_request_uri(self.uri, scope=self.scope)
        self.assertURLEqual(uri, self.uri_scope)

        # With state
        uri = client.prepare_request_uri(self.uri, state=self.state)
        self.assertURLEqual(uri, self.uri_state)

        # With extra parameters through kwargs
        uri = client.prepare_request_uri(self.uri, **self.kwargs)
        self.assertURLEqual(uri, self.uri_kwargs)
示例#15
0
def create_app():
    """
    Create the todo app

    Returns:
        app: The flask application.
    """
    app = Flask(__name__)
    app.config.from_object('todo_app.flask_config.Config')
    app.config['LOGIN_DISABLED'] = os.getenv('LOGIN_DISABLED') == 'True'

    login_manager = LoginManager()
    oauth_client_id = os.environ['OAUTH_CLIENT_ID']
    oauth_client_secret = os.environ['OAUTH_CLIENT_SECRET']
    client = WebApplicationClient(oauth_client_id)

    @login_manager.unauthorized_handler
    def unauthenticated():
        oauth_get_uri = client.prepare_request_uri(
            uri="https://github.com/login/oauth/authorize", state="todoapp")
        return redirect(oauth_get_uri, code=302)

    @login_manager.user_loader
    def load_user(user_id):
        return User(id=user_id,
                    role=user_id_to_role.get(str(user_id), Role.READER))

    login_manager.init_app(app)

    @app.route('/')
    @authorised_role(role=Role.READER)
    @login_required
    def index():
        items = get_items()
        items_view_model = ItemsViewModel(items)
        return render_template('index.html',
                               view_model=items_view_model,
                               user=current_user,
                               login_disabled=app.config['LOGIN_DISABLED'])

    @app.route('/login/callback')
    def login_callback():
        code = request.args.get("code")
        post_token_request = client.prepare_token_request(
            "https://github.com/login/oauth/access_token",
            state="todoapp",
            client_id=oauth_client_id,
            client_secret=oauth_client_secret,
            code=code)
        (post_token_url, post_token_headers,
         post_token_body) = post_token_request
        post_token_headers["Accept"] = "application/json"
        token_response = requests.post(post_token_url,
                                       data=post_token_body,
                                       headers=post_token_headers)
        client.parse_request_body_response(token_response.text)
        (get_user_url, get_user_headers,
         _) = client.add_token("https://api.github.com/user")
        user_response = requests.get(get_user_url,
                                     headers=get_user_headers).json()
        user_id = user_response["id"]
        user = User(id=user_response["id"],
                    role=user_id_to_role.get(user_id, Role.READER))
        login_user(user)
        return redirect('/')

    @app.route('/todos', methods=['POST'])
    @authorised_role(role=Role.WRITER)
    @login_required
    def add_todo():
        title = request.form.get('title')
        add_item(title)
        return redirect('/')

    @app.route('/todos/<id>', methods=['POST'])
    @authorised_role(role=Role.WRITER)
    @login_required
    def update_todo(id):
        status = request.form.get('status')
        item = get_item(id)
        item.status = ItemStatus.COMPLETE if status == 'COMPLETE' else ItemStatus.NOT_STARTED
        save_item(item)
        return redirect('/')

    @app.route('/todos/<id>/delete', methods=['POST'])
    @authorised_role(role=Role.WRITER)
    @login_required
    def remove_todo(id):
        delete_item(id)
        return redirect('/')

    return app
 def test_code_in_uri(self):
     """Tests whether the value of code is retained in the uri"""
     client = WebApplicationClient('*****@*****.**')
     uri = "https://gCallback/?state=dummy_state&code=dummy_code"
     self.assertTrue('dummy_code' in client.parse_request_uri_response(uri, state='dummy_state').values())
示例#17
0

@login_manager.unauthorized_handler
def unauthorized():
    return "You must be logged in to access this content.", 403


# Naive database setup
try:
    init_db_command()
except sqlite3.OperationalError:
    # Assume it's already been created
    pass

# OAuth2 client setup
client = WebApplicationClient(GOOGLE_CLIENT_ID)


# Flask-Login helper to retrieve a user from our db
@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id)


@app.route("/")
def index():
    if current_user.is_authenticated:
        return ("<p>Hello, {}! You're logged in! Email: {}</p>"
                "<div><p>Google Profile Picture:</p>"
                '<img src="{}" alt="Google profile pic"></img></div>'
                '<a class="button" href="/logout">Logout</a>'.format(
示例#18
0
#Not sure why it's not in its own function
@login_manager.unauthorized_handler
def unauthorized():
    return ('You must be logged in to access this content.', 403)


# Naive database setup
try:
    init_db_command()
except sqlite3.OperationalError:
    # Assume it's already been created
    pass

# OAuth 2 client setup
client = WebApplicationClient(client_id) if (set_up) else WebApplicationClient(
    custom_id_getter(True))
# Don't want to needlessly open files
############################################


# Flask-Login helper to retrieve a user from our db
@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id)


def fix_location(l1):  #fixes GPS coordinates as stored on DB
    l1 = l1.replace('D', ', ')
    return l1
示例#19
0
# Creating the Flask app instance
printColoured(" * Initialising Flask application")
app = Flask(__name__)
CORS(app)

# ===== App Configuration =====

SECRET_KEY = os.getenv("SECRET_KEY")
app.secret_key = SECRET_KEY

GOOGLE_API_CLIENT_SECRET = os.getenv("GOOGLE_API_CLIENT_SECRET")
GOOGLE_API_CLIENT_ID = os.getenv("GOOGLE_API_CLIENT_ID")
GOOGLE_DISCOVERY_URL = (
    "https://accounts.google.com/.well-known/openid-configuration")
google_client = WebApplicationClient(GOOGLE_API_CLIENT_ID)

# Registering the default error handler
app.register_error_handler(Exception, error_handler)

# Database connection parameters:
client = pymongo.MongoClient(
    "mongodb+srv://teamgalactic:[email protected]/galacticed?retryWrites=true&w=majority"
)

# Creating the database handler:
db = client["galacticed"]

# The routes must be imported after the Flask application object is created. See https://flask.palletsprojects.com/en/1.1.x/patterns/packages/
import GalacticEd.routes
示例#20
0
from flask import Flask, render_template, url_for, flash, redirect, jsonify, request
from FlaskApp import app, config
from FlaskApp.forms import LoginForm
from flask_login import current_user, logout_user,login_required
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import WebApplicationClient
import jwt, requests, json, datetime


client = WebApplicationClient(config.GOOGLE_CLIENT_ID)


@app.route("/about")
def about():
    return render_template('about.html', title='About')



@app.route("/", methods=['GET', 'POST'])
@app.route("/login_home", methods=['GET', 'POST'])
def login_home():
    form = LoginForm()
    if form.validate_on_submit():
        if form.email.data == '*****@*****.**' and form.password.data == 'password':
        	token = jwt.encode({'user' : form.email.data, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(seconds = 30)},app.config['SECRET_KEY'])
        	return jsonify({'token' : token.decode('UTF-8')}) 
        else:
            flash('Login Unsuccessful. Please check username and password', 'danger')
    return render_template('login.html', title='Login', form=form) 

示例#21
0

# User session management setup
# https://flask-login.readthedocs.io/en/latest
login_manager = LoginManager()
login_manager.init_app(app)

# Naive database setup
try:
    init_db_command()
except sqlite3.OperationalError:
    # Assume it's already been created
    pass

# OAuth 2 client setup
client = WebApplicationClient(WS1_CLIENT_ID)


def get_ws1_provider_cfg():
    return requests.get(WS1_DISCOVERY_URL).json()


# Flask-Login helper to retrieve a user from our db
@login_manager.unauthorized_handler
def unauthorized():
    # do stuff
    return redirect(url_for('login'))

@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id)
示例#22
0
def get_client():
    client = WebApplicationClient(mg_config['client_id'])
    return client
    def get(self, request, *args, **kwargs):

        # Retrieve these data from the URL
        data = self.request.GET
        code = data['code']
        state = data['state']
        print("code=%s, state=%s" % (code, state))

        # For security purposes, verify that the
        # state information is the same as was passed
        # to github_login()
        if self.request.session['state'] != state:
            messages.add_message(self.request, messages.ERROR,
                                 "State information mismatch!")
            return HttpResponseRedirect(reverse('github:welcome'))
        else:
            del self.request.session['state']

        # fetch the access token from GitHub's API at token_url
        token_url = 'https://github.com/login/oauth/access_token'
        client_id = settings.GITHUB_OAUTH_CLIENT_ID
        client_secret = settings.GITHUB_OAUTH_SECRET

        # Create a Web Applicantion Client from oauthlib
        client = WebApplicationClient(client_id)

        # Prepare body for request
        data = client.prepare_request_body(
            code=code,
            redirect_uri=settings.GITHUB_OAUTH_CALLBACK_URL,
            client_id=client_id,
            client_secret=client_secret)

        # Post a request at GitHub's token_url
        # Returns requests.Response object
        response = requests.post(token_url, data=data)
        """
    Parse the unicode content of the response object
    Returns a dictionary stored in client.token
    {
      'access_token': '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',
      'scope': ['read:user'],
      'token_type': 'bearer'
    }
    """
        client.parse_request_body_response(response.text)

        # Prepare an Authorization header for GET request using the 'access_token' value
        # using GitHub's official API format
        header = {
            'Authorization': 'token {}'.format(client.token['access_token'])
        }

        # Retrieve GitHub profile data
        # Send a GET request
        # Returns requests.Response object
        response = requests.get('https://api.github.com/user', headers=header)

        # Store profile data in JSON
        json_dict = response.json()
        '''
    Fields that are of interest:
      'login' => json_dict['login'],
      'name' => json_dict['name'],
      'bio' => json_dict['bio'],
      'blog' => json_dict['blog'],
      'email' => json_dict['email'],    # not public data
      'avatar_url' => json_dict['avatar_url'],
    '''

        # save the user profile in a session
        self.request.session['profile'] = json_dict

        # retrieve or create a Django User for this profile
        try:
            user = User.objects.get(username=json_dict['login'])

            messages.add_message(
                self.request, messages.DEBUG,
                "User %s already exists, Authenticated? %s" %
                (user.username, user.is_authenticated))

            print("User %s already exists, Authenticated %s" %
                  (user.username, user.is_authenticated))

            # remember to log the user into the system
            login(self.request, user)

        except:
            # create a Django User for this login
            user = User.objects.create_user(json_dict['login'],
                                            json_dict['email'])

            messages.add_message(
                self.request, messages.DEBUG,
                "User %s is created, Authenticated %s?" %
                (user.username, user.is_authenticated))

            print("User %s is created, Authenticated %s" %
                  (user.username, user.is_authenticated))

            # remember to log the user into the system
            login(self.request, user)

        # Redirect response to hide the callback url in browser
        return HttpResponseRedirect(reverse('github:welcome'))
示例#24
0
    def api_auth_callback(self):
        s = self._settings
        d = settings_defaults()

        code = flask.request.args.get("code")

        token_endpoint = s.get(['token_endpoint'])
        client_id = s.get(['client_id'])
        client_secret = s.get(['client_secret'])
        userinfo_endpoint = s.get(['userinfo_endpoint'])
        orguser_endpoint = s.get(['orguser_endpoint'])
        organization = s.get(['organization'])
        username_key = s.get(['username_key'])

        self._logger.info('token_endpoint: ' + str(token_endpoint))

        client = WebApplicationClient(client_id)

        token_url, headers, body = client.prepare_token_request(
            token_endpoint,
            # authorization_response=flask.request.url,
            # redirect_url=flask.request.base_url,
            code=code
        )

        headers['Accept'] = 'application/json'

        token_response = requests.post(
            token_url,
            headers=headers,
            data=body,
            auth=(client_id, client_secret),
        )

        client.parse_request_body_response(json.dumps(token_response.json()))

        uri, headers, body = client.add_token(userinfo_endpoint)
        headers['Accept'] = 'application/json'
        userinfo_response = requests.get(uri, headers=headers, data=body)

        userinfo = userinfo_response.json()
        username = userinfo[username_key]

        uri, headers, body = client.add_token(orguser_endpoint.format(organization, username))
        headers['Accept'] = 'application/json'
        orguser_response = requests.get(uri, headers=headers, data=body)

        if orguser_response.status_code == 204:
            # User is part of the specified organization, find user or create it if it doesn't exist
            user = self._user_manager.login_user(OAuth2PGCUser(username))
            flask.session["usersession.id"] = user.session
            flask.g.user = user

            self._logger.info("authenticated: " + str(user.is_authenticated))
            self._logger.info("user: "******"Actively logging in user {} from {}".format(user.get_id(), remote_addr))

            r = flask.redirect('/')
            r.delete_cookie("active_logout")

            eventManager().fire(Events.USER_LOGGED_IN, payload=dict(username=user.get_id()))

            return r

        return flask.redirect('/?error=unauthorized')
示例#25
0
from todo_app.trello_api_calls import fetch_all_cards, change_card_status, \
    TrelloCard

from todo_app.view_model import ViewModel
from todo_app.Authenticated_User import Authenticated_User
import os

from loggly.handlers import HTTPSHandler
from logging import Formatter

from flask_login import LoginManager, login_required, login_user, current_user
from oauthlib.oauth2 import WebApplicationClient

login_manager = LoginManager()
oauth_client_id = os.environ.get('OAUTH_CLIENT_ID')
oauth_client = WebApplicationClient(oauth_client_id)
oauth_client_secret = os.environ.get('OAUTH_CLIENT_SECRET')


def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    app.logger.setLevel(os.environ.get("LOG_LEVEL"))

    if os.environ.get("LOGGLY_TOKEN") is not None:
        args = "https://logs-01.loggly.com/inputs/" + os.environ.get(
            "LOGGLY_TOKEN") + "/tag/todo-app"
        handler = HTTPSHandler(args)
        handler.setFormatter(
            Formatter(
示例#26
0
    def test_prepare_request_body(self):
        """
        see issue #585
            https://github.com/oauthlib/oauthlib/issues/585

        `prepare_request_body` should support the following scenarios:
            1. Include client_id alone in the body (default)
            2. Include client_id and client_secret in auth and not include them in the body (RFC preferred solution)
            3. Include client_id and client_secret in the body (RFC alternative solution)
            4. Include client_id in the body and an empty string for client_secret.
        """
        client = WebApplicationClient(self.client_id)

        # scenario 1, default behavior to include `client_id`
        r1 = client.prepare_request_body()
        self.assertEqual(r1, 'grant_type=authorization_code&client_id=%s' % self.client_id)

        r1b = client.prepare_request_body(include_client_id=True)
        self.assertEqual(r1b, 'grant_type=authorization_code&client_id=%s' % self.client_id)

        # scenario 2, do not include `client_id` in the body, so it can be sent in auth.
        r2 = client.prepare_request_body(include_client_id=False)
        self.assertEqual(r2, 'grant_type=authorization_code')

        # scenario 3, Include client_id and client_secret in the body (RFC alternative solution)
        # the order of kwargs being appended is not guaranteed. for brevity, check the 2 permutations instead of sorting
        r3 = client.prepare_request_body(client_secret=self.client_secret)
        r3_params = dict(urlparse.parse_qsl(r3, keep_blank_values=True))
        self.assertEqual(len(r3_params.keys()), 3)
        self.assertEqual(r3_params['grant_type'], 'authorization_code')
        self.assertEqual(r3_params['client_id'], self.client_id)
        self.assertEqual(r3_params['client_secret'], self.client_secret)

        r3b = client.prepare_request_body(include_client_id=True, client_secret=self.client_secret)
        r3b_params = dict(urlparse.parse_qsl(r3b, keep_blank_values=True))
        self.assertEqual(len(r3b_params.keys()), 3)
        self.assertEqual(r3b_params['grant_type'], 'authorization_code')
        self.assertEqual(r3b_params['client_id'], self.client_id)
        self.assertEqual(r3b_params['client_secret'], self.client_secret)

        # scenario 4, `client_secret` is an empty string
        r4 = client.prepare_request_body(include_client_id=True, client_secret='')
        r4_params = dict(urlparse.parse_qsl(r4, keep_blank_values=True))
        self.assertEqual(len(r4_params.keys()), 3)
        self.assertEqual(r4_params['grant_type'], 'authorization_code')
        self.assertEqual(r4_params['client_id'], self.client_id)
        self.assertEqual(r4_params['client_secret'], '')

        # scenario 4b, `client_secret` is `None`
        r4b = client.prepare_request_body(include_client_id=True, client_secret=None)
        r4b_params = dict(urlparse.parse_qsl(r4b, keep_blank_values=True))
        self.assertEqual(len(r4b_params.keys()), 2)
        self.assertEqual(r4b_params['grant_type'], 'authorization_code')
        self.assertEqual(r4b_params['client_id'], self.client_id)

        # scenario Warnings
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")  # catch all

            # warning1 - raise a DeprecationWarning if a `client_id` is submitted
            rWarnings1 = client.prepare_request_body(client_id=self.client_id)
            self.assertEqual(len(w), 1)
            self.assertIsInstance(w[0].message, DeprecationWarning)

            # testing the exact warning message in Python2&Python3 is a pain

        # scenario Exceptions
        # exception1 - raise a ValueError if the a different `client_id` is submitted
        with self.assertRaises(ValueError) as cm:
            client.prepare_request_body(client_id='different_client_id')
 def unauthenticated():
     client = WebApplicationClient(os.getenv("CLIENT_ID"))
     client.state = client.state_generator()
     authredirect = client.prepare_request_uri(
         "https://github.com/login/oauth/authorize", state=client.state)
     return redirect(authredirect)
示例#28
0
class OAuthClient:
    """
    Helper class to handle the OAuth authentication flow
    the logic is divided in 2 steps:
    - open the browser on GitGuardian login screen and run a local server to wait for callback
    - handle the oauth callback to exchange an authorization code against a valid access token
    """
    def __init__(self, config: Config, instance: str) -> None:
        self.config = config
        self.instance = instance
        self._oauth_client = WebApplicationClient(CLIENT_ID)
        self._state = ""  # use the `state` property instead

        self._handler_wrapper = RequestHandlerWrapper(oauth_client=self)
        self._access_token: Optional[str] = None
        self._port = USABLE_PORT_RANGE[0]
        self.server: Optional[HTTPServer] = None

        self._generate_pkce_pair()

    def oauth_process(self,
                      token_name: Optional[str] = None,
                      lifetime: Optional[int] = None) -> None:
        """
        Handle the whole oauth process which includes
        - opening the user's webbrowser to GitGuardian login page
        - open a server and wait for the callback processing
        """
        # enable redirection to http://localhost
        os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = str(True)

        if token_name is None:
            token_name = "ggshield token " + datetime.today().strftime(
                "%Y-%m-%d")
        self._token_name = token_name

        if lifetime is None:
            lifetime = self.default_token_lifetime
        self._lifetime = lifetime

        self._prepare_server()
        self._redirect_to_login()
        self._wait_for_callback()

        message = f"Created Personal Access Token {self._token_name} "
        expire_at = self.instance_config.account.expire_at
        if expire_at is not None:
            message += "expiring on " + get_pretty_date(expire_at)
        else:
            message += "with no expiry"
        click.echo(message)

    def process_callback(self, callback_url: str) -> None:
        """
        This function runs within the request handler do_GET method.
        It takes the url of the callback request as argument and does
        - Extract the authorization code
        - Exchange the code against an access token with GitGuardian's api
        - Validate the new token against GitGuardian's api
        - Save the token in configuration
        Any error during this process will raise a OAuthError
        """
        authorization_code = self._get_code(callback_url)
        self._claim_token(authorization_code)
        token_data = self._validate_access_token()
        self._save_token(token_data)

    def _generate_pkce_pair(self) -> None:
        """
        Generate a code verifier (random string) and its sha encoded version to be used
        for the pkce checking process
        """
        self.code_verifier = self._oauth_client.create_code_verifier(
            128)  # type: ignore
        self.code_challenge = (urlsafe_b64encode(
            sha256(self.code_verifier.encode()).digest()).decode().rstrip("="))

    def _redirect_to_login(self) -> None:
        """
        Open the user's browser to the GitGuardian ggshield authentication page
        """
        static_params = {
            "auth_mode": "ggshield_login",
            "utm_source": "cli",
            "utm_medium": "login",
            "utm_campaign": "ggshield",
        }
        request_uri = self._oauth_client.prepare_request_uri(
            uri=urlparse.urljoin(self.dashboard_url, "auth/login"),
            redirect_uri=self.redirect_uri,
            scope=SCOPE,
            code_challenge=self.code_challenge,
            code_challenge_method="S256",
            state=self.state,
            **static_params,
        )
        click.echo(
            f"To complete the login process, follow the instructions from {request_uri}.\n"
            "Opening your web browser now...")
        webbrowser.open_new_tab(request_uri)

    def _prepare_server(self) -> None:
        for port in range(*USABLE_PORT_RANGE):
            try:
                self.server = HTTPServer(
                    # only consider requests from localhost on the predetermined port
                    ("127.0.0.1", port),
                    # attach the wrapped request handler
                    self._handler_wrapper.request_handler,
                )
                self._port = port
                break
            except OSError:
                continue
        else:
            raise click.ClickException("Could not find unoccupied port.")

    def _wait_for_callback(self) -> None:
        """
        Wait to receive and process the authorization callback on the local server.
        This actually catches HTTP requests made on the previously opened server.
        The callback processing logic is implementend in the request handler class
        and the `process_callback` method
        """
        try:
            while not self._handler_wrapper.complete:
                # Wait for callback on localserver including an authorization code
                # any matchin request will get processed by the request handler and
                # the `process_callback` function
                self.server.handle_request()  # type: ignore
        except KeyboardInterrupt:
            raise click.ClickException("Aborting")

        if self._handler_wrapper.error_message is not None:
            # if no error message is attached, the process is considered successful
            raise click.ClickException(self._handler_wrapper.error_message)

    def _get_code(self, uri: str) -> str:
        """
        Extract the authorization from the incoming request uri and verify that the state from
        the uri match the one stored internally.
        if no code can be extracted or the state is invalid, raise an OAuthError
        else return the extracted code
        """
        try:
            authorization_code = self._oauth_client.parse_request_uri_response(
                uri, self.state).get("code")
        except OAuth2Error:
            authorization_code = None
        if authorization_code is None:
            raise OAuthError(
                "Invalid code or state received from the callback.")
        return authorization_code  # type: ignore

    def _claim_token(self, authorization_code: str) -> None:
        """
        Exchange the authorization code with a valid access token using GitGuardian public api.
        If no valid token could be retrieved, exit the authentication process with an error message
        """

        request_params = {"name": self._token_name}
        if self._lifetime is not None:
            request_params["lifetime"] = str(self._lifetime)

        request_body = self._oauth_client.prepare_request_body(
            code=authorization_code,
            redirect_uri=self.redirect_uri,
            code_verifier=self.code_verifier,
            body=urlparse.urlencode(request_params),
        )

        response = requests.post(
            urlparse.urljoin(self.api_url, "oauth/token"),
            request_body,
            headers={"Content-Type": "application/x-www-form-urlencoded"},
        )

        if not response.ok:
            raise OAuthError("Cannot create a token.")

        self._access_token = response.json()["key"]
        self.config.auth_config.current_token = self._access_token

    def _validate_access_token(self) -> Dict[str, Any]:
        """
        Validate the token using GitGuardian public api.
        If the token is not valid, exit the authentication process with an error message.
        """
        response = retrieve_client(self.config).get(endpoint="token")
        if not response.ok:
            raise OAuthError("The created token is invalid.")
        return response.json()  # type: ignore

    def _save_token(self, api_token_data: Dict[str, Any]) -> None:
        """
        Save the new token in the configuration.
        """
        account_config = AccountConfig(
            account_id=api_token_data["account_id"],
            token=self._access_token,  # type: ignore
            expire_at=api_token_data.get("expire_at"),
            token_name=api_token_data.get("name", ""),
            type=api_token_data.get("type", ""),
        )
        self.instance_config.account = account_config
        self.config.save()

    @property
    def instance_config(self) -> InstanceConfig:
        return self.config.auth_config.instances[self.instance]

    @property
    def default_token_lifetime(self) -> Optional[int]:
        """
        return the default token lifetime saved in the instance config.
        if None, this will be interpreted as no expiry.
        """
        default_lifetime = self.instance_config.default_token_lifetime
        if default_lifetime is not None:
            return default_lifetime.days

        return None

    @property
    def redirect_uri(self) -> str:
        return f"http://localhost:{self._port}"

    @property
    def state(self) -> str:
        """
        Return the state used to verify the auth process.
        The state is included in the redirect_uri and is expected in the callback url.
        Then, if both states don't match, the process fails.
        The state is an url-encoded string dict containing the token name and lifetime
        It is cached to prevent from altering its value during the process
        """
        if not self._state:
            self._state = urlparse.quote(
                json.dumps({
                    "token_name": self._token_name,
                    "lifetime": self._lifetime
                }))
        return self._state

    @property
    def dashboard_url(self) -> str:
        return self.config.dashboard_url

    @property
    def api_url(self) -> str:
        return self.config.api_url
示例#29
0
def create_app():
    # Defining logger
    logger = logging.getLogger(__name__)
    logger.warning('Hello, World!')
    logging.basicConfig(level=os.getenv('LOG_LEVEL', 'INFO'))
    # Launch app
    app = Flask(__name__)
    app.config.from_object(Config())

    # Loggly
    if app.config['LOGGLY_TOKEN'] is not None:
        handler = HTTPSHandler(f'https://logs-01.loggly.com/inputs/{app.config["LOGGLY_TOKEN"]}/tag/todo-app')
        handler.setFormatter(
            jsonlogger.JsonFormatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")
        )
        app.logger.addHandler(handler)
        getLogger('werkzeug').addHandler(HTTPSHandler(f'https://logs-01.loggly.com/inputs/{app.config["LOGGLY_TOKEN"]}/tag/todoapp-requests'))
        
    # Connect to mongo
    si.connect_mongo()

    # All the routes and setup code etc
    # Index
    @app.route('/')
    @reader_required
    def index():
        items = si.get_items()
        item_view_model = ViewModel(items)
        return render_template('index.html', view_model = item_view_model)

    # Add item 
    @app.route('/create_item', methods = ['POST'])
    @writer_required
    def create_item():
        title = request.form ['title']
        si.add_item(title)
        return redirect(url_for('index'))

    # Update item status
    @app.route('/item_status', methods = ['GET','POST'])
    @writer_required
    def item_status():
        item_title = request.form ['item_title']
        item_status = request.form ['item_status']
        item = si.get_item(item_title)
        if item != None:
            si.save_item(item,item_status)
        return redirect(url_for('index'))

    # Delete item
    @app.route('/del_item', methods = ['GET','POST'])
    @writer_required
    def del_item():
        del_title = request.form['del_title']
        delete_item(del_title)
        logger.info("Item deleted: %s", del_title)
        return redirect(url_for('index'))
    
    # Route for logout
    @app.route('/logout')
    @login_required
    def logout():
        logger.info("User logged out. User id: %s", current_user.id)
        logout_user()
        return redirect(url_for('index'))

    ### OAuth ###
    # Obtain GitHub OAuth Secrets:
    client_id = os.getenv('CLIENT_ID')
    client_secret = os.getenv('CLIENT_SECRET')

    # Initialize login_manager class
    login_manager = flask_login.LoginManager()

    # Create client
    client = WebApplicationClient(client_id)

    @login_manager.unauthorized_handler
    def unauthenticated():
        # Add logic to redirect to the Github OAuth flow when unauthenticated
        # Request identity
        # Redirect to site
        # Return -> redirect to github
        redirecturl = client.prepare_request_uri("https://github.com/login/oauth/authorize")
        return redirect(redirecturl)

    @login_manager.user_loader
    def load_user(user_id):
        return User(user_id)

    @app.route('/login', methods = ['GET'])
    def login():
        code = request.args.get('code')
        token_url, headers, body = client.prepare_token_request('https://github.com/login/oauth/access_token', code = code )
        headers['Accept']= 'application/json'
        response = requests.post(token_url, headers = headers, data = body, auth = (client_id,client_secret))
        response = response.json()
        access_token = response['access_token']
        usr_url = 'https://api.github.com/user'
        headers = {'Authorization': 'token ' + access_token}
        usr_response = requests.get(usr_url, headers = headers )
        usr_response = usr_response.json()
        user = User(usr_response['id'])
        login_user(user)
        logger.info("User logged in: %s", usr_response['id'])
        return redirect(url_for('index'))

    login_manager.init_app(app)

    ### MAIN ###
    if __name__ == '__main__':
        app.run()

    return app
示例#30
0
    def create_oauth2_session(self):
        if self.auth_type != OAUTH2:
            raise ValueError(
                'Auth type must be %r for credentials type OAuth2Credentials' %
                OAUTH2)

        has_token = False
        scope = ['https://outlook.office365.com/.default']
        session_params = {}
        token_params = {}

        if isinstance(self.credentials, OAuth2AuthorizationCodeCredentials):
            # Ask for a refresh token
            scope.append('offline_access')

            # We don't know (or need) the Microsoft tenant ID. Use
            # common/ to let Microsoft select the appropriate tenant
            # for the provided authorization code or refresh token.
            #
            # Suppress looks-like-password warning from Bandit.
            token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token'  # nosec

            client_params = {}
            has_token = self.credentials.access_token is not None
            if has_token:
                session_params['token'] = self.credentials.access_token
            elif self.credentials.authorization_code is not None:
                token_params['code'] = self.credentials.authorization_code
                self.credentials.authorization_code = None

            if self.credentials.client_id is not None and self.credentials.client_secret is not None:
                # If we're given a client ID and secret, we have enough
                # to refresh access tokens ourselves. In other cases the
                # session will raise TokenExpiredError and we'll need to
                # ask the calling application to refresh the token (that
                # covers cases where the caller doesn't have access to
                # the client secret but is working with a service that
                # can provide it refreshed tokens on a limited basis).
                session_params.update({
                    'auto_refresh_kwargs': {
                        'client_id': self.credentials.client_id,
                        'client_secret': self.credentials.client_secret,
                    },
                    'auto_refresh_url':
                    token_url,
                    'token_updater':
                    self.credentials.on_token_auto_refreshed,
                })
            client = WebApplicationClient(self.credentials.client_id,
                                          **client_params)
        else:
            token_url = 'https://login.microsoftonline.com/%s/oauth2/v2.0/token' % self.credentials.tenant_id
            client = BackendApplicationClient(
                client_id=self.credentials.client_id)

        session = self.raw_session(client, session_params)
        if not has_token:
            # Fetch the token explicitly -- it doesn't occur implicitly
            token = session.fetch_token(
                token_url=token_url,
                client_id=self.credentials.client_id,
                client_secret=self.credentials.client_secret,
                scope=scope,
                **token_params)
            # Allow the credentials object to update its copy of the new
            # token, and give the application an opportunity to cache it
            self.credentials.on_token_auto_refreshed(token)
        session.auth = get_auth_instance(auth_type=OAUTH2, client=client)

        return session
def create_app():
    app = Flask(__name__)
    app.config.from_object('todo_app.flask_config.Config')
    app.logger.setLevel(app.config['LOG_LEVEL'])
    app.wsgi_app = ReverseProxied(app.wsgi_app)

    if app.config['LOGGLY_TOKEN'] is not None:
        handler = HTTPSHandler(f'https://logs-01.loggly.com/inputs/{app.config["LOGGLY_TOKEN"]}/tag/todo-app')
        formatter = jsonlogger.JsonFormatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s %(requesterIpAddr)s")
        handler.setFormatter(formatter)
        app.logger.addHandler(handler)

    client_id = os.environ['GITHUB_CLIENT_ID']
    client_secret = os.environ['GITHUB_CLIENT_SECRET']
    base_url="https://api.github.com"
    authorization_url="https://github.com/login/oauth/authorize"
    token_endpoint = "https://github.com/login/oauth/access_token"

    client = WebApplicationClient(client_id)
    todo = mongodb_todo()
    usermanager = MongoDbUserService()

    login_manager = LoginManager()
    login_manager.init_app(app)


    @app.errorhandler(Exception)
    def handle_error(e):
        app.logger.error('exception', extra={
            "method": "{}".format(request.method),
            "requesterIpAddr": "{}".format(request.remote_addr),
            "url": "{}".format(request.url)
        }, exc_info=True)

        return render_template("error.html", error=str(e))
    
    @app.after_request
    def after_request(response):
        app.logger.info("after_request", extra={
            "method": "{}".format(request.method),
            "requesterIpAddr": "{}".format(request.remote_addr),
            "url": "{}".format(request.url),
            "status_code": "{}".format(response.status)
        })
        return response

    @login_manager.user_loader
    def load_user(user_id):        
        return UserToLogin(user_id)
    
    @login_manager.unauthorized_handler
    def unauthenticated():
        app.logger.info("Unauthorized attemp made.", extra={
            "method": "{}".format(request.method),
            "requesterIpAddr": "{}".format(request.remote_addr),
            "url": "{}".format(request.url)
        })
        return redirect(url_for('login'))
    
    @app.route('/logout')
    @login_required
    def logout():
        app.logger.info("User {} logged out of the system.".format(current_user.id), extra={
            "method": "{}".format(request.method),
            "requesterIpAddr": "{}".format(request.remote_addr),
            "url": "{}".format(request.url)
        })
        logout_user()
        session.clear()        
        return redirect("https://github.com/logout")
    
    @app.route("/login")
    def login():
        request_uri = client.prepare_request_uri(
            authorization_url,
            redirect_uri=request.base_url + "/callback",
            scope=None,
        )
        return redirect(request_uri)

    @app.route("/login/callback")
    def callback():
        code = request.args.get("code")
        app.logger.debug("{}".format(code), extra={
            "method": "{}".format(request.method),
            "requesterIpAddr": "{}".format(request.remote_addr),
            "url": "{}".format(request.url)
        })

        # Prepare and send request to get tokens! 
        token_url, headers, body = client.prepare_token_request(
            token_endpoint,
            authorization_response=request.url,
            redirect_url=request.base_url,
            code=code,
        )

        token_response = requests.post(
            token_url,
            headers=headers,
            data=body,
            auth=(client_id, client_secret),
        )

        if token_response.status_code != 200:
            return redirect(url_for('login'))

        json_data = token_response.content.decode('utf8').replace("'", '"')
        # Parse the tokens!
        client.parse_request_body_response(json_data)
        userinfo_endpoint = "{}/user".format(base_url)
        uri, headers, body = client.add_token(userinfo_endpoint)
        userinfo_response = requests.get(uri, headers=headers, data=body)
        if userinfo_response.ok:
            account_info_json = userinfo_response.json()
            currentUserName = str(account_info_json['login'])               
            login_user(UserToLogin(currentUserName))
            app.logger.info("User logged in {}".format(current_user.id), extra={
                "method": "{}".format(request.method),
                "requesterIpAddr": "{}".format(request.remote_addr),
                "url": "{}".format(request.url)
            })

            if usermanager.get_totalusercount() == 0:
                usermanager.create_user(username=currentUserName,role="admin")
                app.logger.info("User logged in {} has been give admin level access.".format(current_user.id), extra={
                    "method": "{}".format(request.method),
                    "requesterIpAddr": "{}".format(request.remote_addr),
                    "url": "{}".format(request.url)
                })
            
            if (usermanager.get_totalusercount() > 0) and (usermanager.get_findusercount(qry={"username": currentUserName}) == 0):
                usermanager.create_user(username=currentUserName,role="read")
                app.logger.info("User logged in {} has been give read level access.".format(current_user.id), extra={
                    "method": "{}".format(request.method),
                    "requesterIpAddr": "{}".format(request.remote_addr),
                    "url": "{}".format(request.url)
                })

        return redirect(url_for('get_index'))


    @app.route('/', methods=['GET'])
    @login_required
    def sendhome():
        return redirect(url_for('get_index'))


    ##### Core TODO_Tasks#####
    #error handling for 404
    # @app.errorhandler(404)
    # def not_found(e):
    #     return render_template("error.html", error='resource not found!')

    @app.route('/contact')
    def contact():
        return render_template('contact.html')
    
    @app.route('/home', methods=['GET'])
    @login_required
    def get_index():
        cardslist = []
        items = todo.get_AllItems()
        if (app.config['LOGIN_DISABLED']):
            userRole = False
        else:
            userRole = usermanager.IsDisable()

        for item in items:
            cardslist.append(Card(item))
        item_view_model = ViewModel(cardslist)
        return render_template('index.html', view_model=item_view_model, strRole=userRole)

  
    @app.route('/new', methods=['GET'])   # New Task
    @login_required
    @usermanager.hasWritePermission
    def getnew_post():
        return render_template('new_task.html')

    @app.route('/home', methods=['POST'])   # New Task
    @login_required
    @usermanager.hasWritePermission
    def post_index():
        response = todo.create_task(
            name = request.form['title'],
            due = request.form['duedate'],
            desc = request.form['descarea']
        )        
        if response is not None:
            if current_app.config["LOGIN_DISABLED"]==False:
                app.logger.info("{} create new task".format(current_user.id), extra={
                    "method": "{}".format(request.method),
                    "requesterIpAddr": "{}".format(request.remote_addr),
                    "url": "{}".format(request.url),
                    "data": "name: {} due: {} desc: {}".format(request.form['title'], str(request.form['duedate']), request.form['descarea'])
                })
            return redirect('/home')
        else:
            return render_template("error.html",error="failed to create task!")

    
    @app.route('/edit/<id>', methods=['GET']) #Edit task
    @login_required
    @usermanager.hasWritePermission
    def get_edit(id):
        item = todo.get_task(id=id)
        if item is not None:
            item_info = Card(item)
            return render_template('edit.html', task=item_info)
        else:
            return render_template("error.html", error="failed to obtain task info!")

    @app.route('/edit/<id>', methods=['POST']) #Edit task
    @login_required
    @usermanager.hasWritePermission
    def post_edit(id):
        response= todo.update_task(
            id = id,
            name = request.form['title'],
            desc = request.form['descarea'],
            due = request.form['duedate'],
            status = request.form['status']
        )
        if response is not None:
            if current_app.config["LOGIN_DISABLED"]==False:
                app.logger.info("{} update task".format(current_user.id), extra={
                    "method": "{}".format(request.method),
                    "requesterIpAddr": "{}".format(request.remote_addr),
                    "url": "{}".format(request.url),
                    "data": "id: {} name: {} due: {} desc: {} status: {}".format(id, request.form['title'], str(request.form['duedate']), request.form['descarea'], request.form['status'])
                })
            return redirect('/home')
        else:
            return render_template("error.html", error="failed to update task!")
    
    @app.route('/delete/<id>') # delete task
    @login_required
    @usermanager.hasWritePermission
    def delete(id):
        response = todo.delete_task(id=id)
        if response is not None: 
            if current_app.config["LOGIN_DISABLED"]==False:
                app.logger.info("{} deleted task".format(current_user.id), extra={
                    "method": "{}".format(request.method),
                    "requesterIpAddr": "{}".format(request.remote_addr),
                    "url": "{}".format(request.url),
                    "data": "id: {}".format(id)
                })
            return redirect('/home')
        else:
            return render_template("error.html",error="failed to delete task!") 
    
    ### Additional views ###
    @app.route('/getpreviousdonetasks', methods=['GET'])
    @login_required
    def get_previous_done_tasks():
        cardslist = []
        items = todo.get_older_done_task()
        for item in items:
            cardslist.append(Card(item))
        item_view_model = ViewModel(cardslist)
        userRole = usermanager.IsDisable()
        return render_template('previous_done_task.html', view_model=item_view_model, strRole=userRole)

    
    @app.route('/gettodaydonetasks', methods=['GET'])
    @login_required
    def get_today_done_tasks():
        cardslist = []
        items = todo.get_today_done_task()
        for item in items:
            cardslist.append(Card(item))
        item_view_model = ViewModel(cardslist)
        userRole = usermanager.IsDisable()
        return render_template('today_done_task.html', view_model=item_view_model, strRole=userRole)

############# UserManagement ##########################

    @app.route('/usermanager', methods=['GET'])  #portal
    @login_required
    @usermanager.hasRoleAdmin
    def get_usermanager():
        user_list = []
        items = usermanager.get_AllUsers()
        for item in items:
            user_list.append(User(item))
        item_view_model = ViewModel(user_list)
        return render_template('userManager.html', view_model=item_view_model)        
    
    @app.route('/edituser/<id>', methods=['GET']) #Edit user
    @login_required
    @usermanager.hasRoleAdmin
    def get_edituser(id):
        item = usermanager.get_user(id=id)
        if item is not None:
            item_info = User(item)
            return render_template('editUser.html', user=item_info)
        else:
            return render_template("error.html", error="failed to obtain user info!")

    
    @app.route('/edituser/<id>', methods=['POST']) #Edit user
    @login_required
    @usermanager.hasRoleAdmin
    def post_edituser(id):
        response = usermanager.update_user(
            id = id,
            username = request.form['username'],
            role = request.form['role']
        )
        if response is not None:
            app.logger.info("{} updated user permission".format(current_user.id), extra={
                "method": "{}".format(request.method),
                "requesterIpAddr": "{}".format(request.remote_addr),
                "url": "{}".format(request.url),
                "data": "id: {} username: {} role: {}".format(id, request.form['username'], request.form['role'])
            })
            return redirect('/usermanager')
        else:
            return render_template("error.html", error="failed to update user!")

    
    @app.route('/deleteuser/<id>') # delete user
    @login_required
    @usermanager.hasRoleAdmin
    def deleteuser(id):
        response = usermanager.delete_user(id=id)
        if response is not None:
            app.logger.info("{} deleted user".format(current_user.id), extra={
                "method": "{}".format(request.method),
                "requesterIpAddr": "{}".format(request.remote_addr),
                "url": "{}".format(request.url),
                "data": "id: {}".format(id)
            })
            return redirect('/usermanager')
        else:
            return render_template("error.html",error="failed to delete user!")

###############################################
      
    
    return app
def do_run(config, endpoint_list):

    #setup some globals
    server_uri = config.get("server_uri")
    global SPLUNK_PORT
    global STANZA
    global SESSION_TOKEN
    global delimiter
    SPLUNK_PORT = server_uri[18:]
    STANZA = config.get("name")
    SESSION_TOKEN = config.get("session_key")

    #params

    http_method = config.get("http_method", "GET")
    request_payload = config.get("request_payload")

    #none | basic | digest | oauth1 | oauth2
    auth_type = config.get("auth_type", "none")

    #Delimiter to use for any multi "key=value" field inputs
    delimiter = config.get("delimiter", ",")

    #for basic and digest
    auth_user = config.get("auth_user")
    auth_password = config.get("auth_password")

    #for oauth1
    oauth1_client_key = config.get("oauth1_client_key")
    oauth1_client_secret = config.get("oauth1_client_secret")
    oauth1_access_token = config.get("oauth1_access_token")
    oauth1_access_token_secret = config.get("oauth1_access_token_secret")

    #for oauth2
    oauth2_token_type = config.get("oauth2_token_type", "Bearer")
    oauth2_access_token = config.get("oauth2_access_token")

    oauth2_refresh_token = config.get("oauth2_refresh_token")
    oauth2_refresh_url = config.get("oauth2_refresh_url")
    oauth2_refresh_props_str = config.get("oauth2_refresh_props")
    oauth2_client_id = config.get("oauth2_client_id")
    oauth2_client_secret = config.get("oauth2_client_secret")

    oauth2_refresh_props = {}
    if not oauth2_refresh_props_str is None:
        oauth2_refresh_props = dict((k.strip(), v.strip()) for k, v in (
            item.split('=', 1)
            for item in oauth2_refresh_props_str.split(delimiter)))
    oauth2_refresh_props['client_id'] = oauth2_client_id
    oauth2_refresh_props['client_secret'] = oauth2_client_secret

    http_header_propertys = {}
    http_header_propertys_str = config.get("http_header_propertys")
    if not http_header_propertys_str is None:
        http_header_propertys = dict((k.strip(), v.strip()) for k, v in (
            item.split('=', 1)
            for item in http_header_propertys_str.split(delimiter)))

    url_args = {}
    url_args_str = config.get("url_args")
    if not url_args_str is None:
        url_args = dict(
            (k.strip(), v.strip())
            for k, v in (item.split('=', 1)
                         for item in url_args_str.split(delimiter)))

    #json | xml | text
    response_type = config.get("response_type", "text")

    streaming_request = int(config.get("streaming_request", 0))

    http_proxy = config.get("http_proxy")
    https_proxy = config.get("https_proxy")

    proxies = {}

    if not http_proxy is None:
        proxies["http"] = http_proxy
    if not https_proxy is None:
        proxies["https"] = https_proxy

    cookies = {}
    cookies_str = config.get("cookies")
    if not cookies_str is None:
        cookies = dict((k.strip(), v.strip())
                       for k, v in (item.split('=', 1)
                                    for item in cookies_str.split(delimiter)))

    request_timeout = int(config.get("request_timeout", 30))

    backoff_time = int(config.get("backoff_time", 10))

    sequential_stagger_time = int(config.get("sequential_stagger_time", 0))

    polling_interval_string = config.get("polling_interval", "60")

    if polling_interval_string.isdigit():
        polling_type = 'interval'
        polling_interval = int(polling_interval_string)
    else:
        polling_type = 'cron'
        cron_start_date = datetime.now()
        cron_iter = croniter(polling_interval_string, cron_start_date)

    index_error_response_codes = int(
        config.get("index_error_response_codes", 0))

    response_filter_pattern = config.get("response_filter_pattern")

    if response_filter_pattern:
        global REGEX_PATTERN
        REGEX_PATTERN = re.compile(response_filter_pattern)

    response_handler_args = {}
    response_handler_args_str = config.get("response_handler_args")
    if not response_handler_args_str is None:
        response_handler_args = dict((k.strip(), v.strip()) for k, v in (
            item.split('=', 1)
            for item in response_handler_args_str.split(delimiter)))

    response_handler = config.get("response_handler", "DefaultResponseHandler")
    module = __import__("responsehandlers")
    class_ = getattr(module, response_handler)

    global RESPONSE_HANDLER_INSTANCE
    RESPONSE_HANDLER_INSTANCE = class_(**response_handler_args)

    custom_auth_handler = config.get("custom_auth_handler")

    if custom_auth_handler:
        module = __import__("authhandlers")
        class_ = getattr(module, custom_auth_handler)
        custom_auth_handler_args = {}
        custom_auth_handler_args_str = config.get("custom_auth_handler_args")
        if not custom_auth_handler_args_str is None:
            custom_auth_handler_args = dict(
                (k.strip(), v.strip()) for k, v in (
                    item.split('=', 1)
                    for item in custom_auth_handler_args_str.split(delimiter)))
        CUSTOM_AUTH_HANDLER_INSTANCE = class_(**custom_auth_handler_args)

    try:
        auth = None
        oauth2 = None
        if auth_type == "basic":
            auth = HTTPBasicAuth(auth_user, auth_password)
        elif auth_type == "digest":
            auth = HTTPDigestAuth(auth_user, auth_password)
        elif auth_type == "oauth1":
            auth = OAuth1(oauth1_client_key, oauth1_client_secret,
                          oauth1_access_token, oauth1_access_token_secret)
        elif auth_type == "oauth2":
            token = {}
            token["token_type"] = oauth2_token_type
            token["access_token"] = oauth2_access_token
            token["refresh_token"] = oauth2_refresh_token
            token["expires_in"] = "5"
            client = WebApplicationClient(oauth2_client_id)
            oauth2 = OAuth2Session(client,
                                   token=token,
                                   auto_refresh_url=oauth2_refresh_url,
                                   auto_refresh_kwargs=oauth2_refresh_props,
                                   token_updater=oauth2_token_updater)
        elif auth_type == "custom" and CUSTOM_AUTH_HANDLER_INSTANCE:
            auth = CUSTOM_AUTH_HANDLER_INSTANCE

        req_args = {
            "verify": False,
            "stream": bool(streaming_request),
            "timeout": float(request_timeout)
        }

        if auth:
            req_args["auth"] = auth
        if url_args:
            req_args["params"] = url_args
        if cookies:
            req_args["cookies"] = cookies
        if http_header_propertys:
            req_args["headers"] = http_header_propertys
        if proxies:
            req_args["proxies"] = proxies
        if request_payload and not http_method == "GET":
            req_args["data"] = request_payload

        while True:

            if polling_type == 'cron':
                next_cron_firing = cron_iter.get_next(datetime)
                while get_current_datetime_for_cron() != next_cron_firing:
                    time.sleep(float(10))

            for endpoint in endpoint_list:

                if "params" in req_args:
                    req_args_params_current = dictParameterToStringFormat(
                        req_args["params"])
                else:
                    req_args_params_current = ""
                if "cookies" in req_args:
                    req_args_cookies_current = dictParameterToStringFormat(
                        req_args["cookies"])
                else:
                    req_args_cookies_current = ""
                if "headers" in req_args:
                    req_args_headers_current = dictParameterToStringFormat(
                        req_args["headers"])
                else:
                    req_args_headers_current = ""
                if "data" in req_args:
                    req_args_data_current = req_args["data"]
                else:
                    req_args_data_current = ""

                try:
                    if oauth2:
                        if http_method == "GET":
                            r = oauth2.get(endpoint, **req_args)
                        elif http_method == "POST":
                            r = oauth2.post(endpoint, **req_args)
                        elif http_method == "PUT":
                            r = oauth2.put(endpoint, **req_args)
                    else:
                        if http_method == "GET":
                            r = requests.get(endpoint, **req_args)
                        elif http_method == "POST":
                            r = requests.post(endpoint, **req_args)
                        elif http_method == "PUT":
                            r = requests.put(endpoint, **req_args)

                except requests.exceptions.Timeout, e:
                    logging.error("HTTP Request Timeout error: %s" % str(e))
                    time.sleep(float(backoff_time))
                    continue
                except Exception as e:
                    logging.error("Exception performing request: %s" % str(e))
                    time.sleep(float(backoff_time))
                    continue
                try:
                    r.raise_for_status()
                    if streaming_request:
                        for line in r.iter_lines():
                            if line:
                                handle_output(r, line, response_type, req_args,
                                              endpoint)
                    else:
                        handle_output(r, r.text, response_type, req_args,
                                      endpoint)
                except requests.exceptions.HTTPError, e:
                    error_output = r.text
                    error_http_code = r.status_code
                    if index_error_response_codes:
                        error_event = ""
                        error_event += 'http_error_code = %s error_message = %s' % (
                            error_http_code, error_output)
                        print_xml_single_instance_mode(error_event)
                        sys.stdout.flush()
                    logging.error("HTTP Request error: %s" % str(e))
                    time.sleep(float(backoff_time))
                    continue
示例#33
0
def create_app():
    app = Flask(__name__)
    CLIENT_ID = os.environ.get("GITHUB_CLIENT_ID", None)
    CLIENT_SECRET = os.environ.get("GITHUB_CLIENT_SECRET", None)
    SECRET_KEY = os.environ.get("SECRET_KEY", None)
    WRITER_ROLE = os.environ.get("ROLEWRITER_USER", None)
    redirect_uri = os.environ.get("GITHUB_REDIRECT_URI", None)
    app.secret_key = SECRET_KEY
    logger = app.logger
    logger.setLevel(os.environ.get("LOG_LEVEL", "INFO"))

    if os.environ.get("LOGGLY_TOKEN", "") != "":
        handler = HTTPSHandler(
            f'https://logs-01.loggly.com/inputs/{os.environ.get("LOGGLY_TOKEN")}/tag/todo-app'
        )
        handler.setFormatter(
            Formatter(
                "[%(asctime)s] %(levelname)s in %(module)s: %(message)s"))
        app.logger.addHandler(handler)
    client = WebApplicationClient(CLIENT_ID)
    login_manager = LoginManager()
    login_manager.init_app(app)
    logger.debug("Created Application")

    @login_manager.unauthorized_handler
    def unauthenticated():
        identity_url = client.prepare_request_uri(
            'https://github.com/login/oauth/authorize', redirect_uri)
        app.logger.debug("Github authentication")
        return redirect(identity_url)

    @app.route("/login/callback")
    def callback():
        try:
            app.logger.debug("Github callback start")
            code = request.args.get("code")
            token_url, headers, body = client.prepare_token_request(
                "https://github.com/login/oauth/access_token",
                authorization_response=request.url,
                redirect_url=request.base_url,
                code=code,
            )
            token_response = requests.post(
                token_url,
                headers=headers,
                data=body,
                auth=(CLIENT_ID, CLIENT_SECRET),
            )

            # Parse the tokens!
            params = client.parse_request_body_response(token_response.text)
            uri, headers, body = client.add_token(
                "https://api.github.com/user")

            userinfo_response = requests.get(uri, headers=headers, data=body)
            app.logger.debug("Github callback succeess")

            users_name = userinfo_response.json()["login"]
            users_id = userinfo_response.json()["id"]
            email = userinfo_response.json()["email"]
            user = User(users_id, users_name, email, ROLES['reader'])
            appsession['users_id'] = users_id
            appsession['users_name'] = users_name
            appsession['email'] = email
            if users_name == WRITER_ROLE:
                user.access = ROLES['writer']
            else:
                user.access = ROLES['reader']
            app.logger.info("Logged in user %s", users_name)
            app.logger.info("Logged in user email %s", email)
            app.logger.info("Logged in user role %s", user.access)
            appsession['roles'] = user.access
            login_user(user)
            return redirect(url_for('index'))
        except Exception as e:
            app.logger.error(str(e))
            return "Could not authenticate user."

    @login_manager.user_loader
    def load_user(user_id):
        app.logger.debug("Creating user object")
        m_user_id = appsession.get('users_id')
        m_users_name = appsession.get('users_name')
        m_users_roles = appsession.get('roles')
        m_email = appsession.get('email')
        user = User(m_user_id, m_users_name, m_email, m_users_roles)
        return user

    @app.route('/')
    @login_required
    @requires_roles('reader', 'writer')
    def index():
        app.logger.debug("Index start")
        items = session.Boards().get_items()
        item_view_model = session.ViewModel(items)

        if app.config.get("LOGIN_DISABLED", False):
            mcurrent_user = ''
            misWriter = True  #for E2E testing
        else:
            mcurrent_user = current_user.username
            misWriter = (appsession.get('roles') == ROLES['writer'])
        app.logger.info("Is Writer %s", misWriter)
        app.logger.debug("Index end")
        return render_template('index.html',
                               view_model=item_view_model,
                               isWriter=misWriter,
                               currentuser=mcurrent_user)

    @app.route('/', methods=['POST'])
    @login_required
    @requires_roles('writer')
    def add_item():
        title = request.form.get('title')
        app.logger.info("Add Item %s", title)
        if title != '':
            session.Boards().add_item(title)
            app.logger.info("Item Successfully Added by %s", current_user.id)
        return redirect('/')

    @app.route('/<id>')
    @login_required
    @requires_roles('writer')
    def complete_item(id):
        if (id != "favicon.ico"):
            app.logger.info("Complete Item %s", id)
            todo_class = session.Boards()
            item = todo_class.get_item(id)
            item['status'] = "Completed"
            todo_class.save_item(item)
            app.logger.info("Item %s successfully Completed", id)
        return redirect('/')

    @app.route('/todo/<id>')
    @login_required
    @requires_roles('writer')
    def uncomplete_item(id):
        if (id != "favicon.ico"):
            app.logger.info("UnComplete Item %s", id)
            todo_class = session.Boards()
            item = todo_class.get_item(id)
            item['status'] = "Not Started"
            todo_class.save_item(item)
            app.logger.info("Item %s Set to unomplete.", id)
        return redirect('/')

    @app.route('/doing/<id>')
    @login_required
    @requires_roles('writer')
    def start_item(id):
        if (id != "favicon.ico"):
            app.logger.info("Start Item %s", id)
            todo_class = session.Boards()
            item = todo_class.get_item(id)
            item['status'] = "Doing"
            todo_class.save_item(item)
            app.logger.info("Item %s successfully Started.", id)
        return redirect('/')

    @app.route('/remove/<id>')
    @login_required
    @requires_roles('writer')
    def delete_item(id):
        app.logger.info("Remove Item %s", id)
        todo_class = session.Boards()
        todo_class.remove_item(id)
        app.logger.info("Item %s successfully Removed.", id)
        return redirect('/')

    return app
示例#34
0
    REMEMBER_COOKIE_DURATION = datetime.timedelta(days=365),
    GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID"),
    GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET"),
    GOOGLE_DISCOVERY_URL = os.getenv("GOOGLE_DISCOVERY_URL"),
    IMAGEKIT_PRIVATE_KEY = os.getenv("IMAGEKIT_PRIVATE_KEY"),
    IMAGEKIT_PUBLIC_KEY = os.getenv("IMAGEKIT_PUBLIC_KEY"),
    IMAGEKIT_URL_ENDPOINT = os.getenv("IMAGEKIT_URL_ENDPOINT")
)

# User session management setup
# https://flask-login.readthedocs.io/en/latest
login_manager = LoginManager()
login_manager.init_app(app)

# OAuth 2 client setup
client = WebApplicationClient(app.config['GOOGLE_CLIENT_ID'])

# enable CORS
CORS(app, resources={r'/*': {'origins': '*'}})

@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

@app.errorhandler(400)
def bad_request(error):
    return make_response(jsonify({'error': 'Bad request'}), 400)


@app.route("/")
def index():
示例#35
0
文件: views.py 项目: Andertaker/tvevt
def vk_register(request):
    if request.user.is_authenticated():
        return HttpResponseRedirect(reverse('user_detail'))
    
    code = request.GET.get('code', '')
    if code == '':
        raise ValueError(u"Bad response")
        #return render(request, 'tvevt/fail.html', context)
    

    client = WebApplicationClient(VK_APP_ID)
    uri = client.prepare_request_uri('https://oauth.vk.com/access_token',
                               client_secret=VK_APP_SECRET,
                               code=code,
                               redirect_uri='http://localhost/vk_register')

    h = HTTPSConnection("vk.com")
    h.request('GET', uri)
    r = h.getresponse()
    body = r.read()

    r = json.loads(body)
    user_id = r["user_id"]
    access_token = r["access_token"]

    uri = client.prepare_request_uri('https://api.vk.com/method/users.get',
                               user_id=user_id,
                               access_token=access_token,
                               fields='sex,bdate')

    h.request('GET', uri)
    r = h.getresponse()
    body = r.read()
    r = json.loads(body)
    user = r["response"][0]
    
    
    if user["uid"] <=0:
        raise ValueError(u"Bad uid value")
    
    list = User.objects.filter(vk_user_id=user["uid"])
    if len(list) == 1:
        u = list[0]
        login(request, u)
        return HttpResponseRedirect(reverse('user_detail'))
    
    else:
        "Если пользователя нет, то регистрируем его"
        
        username = "******" % user["uid"]
        l = user["bdate"].split('.')
        year = int(l[2])
        month = int(l[1])
        day = int(l[0])
        user["bdate"] = date(year, month, day)
        
        if user["sex"] == 2:
            user["sex"] = "male"
        elif user["sex"] == 1:
            user["sex"] = "female"
        else:
            user["sex"] == ''
    
        u = User(username=username,
                 vk_user_id=user["uid"],
                  first_name=user["first_name"], last_name=user["last_name"],
                  gender=user["sex"], birth_date=user["bdate"])
        u.save()
 
        login(request, u)
        return render(request, 'tvevt/success.html')
示例#36
0
from contentagregator.config import google_config

app = Flask(__name__)

app.debug=True
app.config.from_object('contentagregator.config.DevelopmentConfig')

db = SQLAlchemy(app)
assets = Environment(app)
migrate = Migrate(app, db)
api = Api(app)
jwt = JWTManager(app)
mail = Mail(app)
seeder = FlaskSeeder(app, db)
lang = Language(app)
client = WebApplicationClient(google_config['google_client_id'])

# celery setup
def make_celery(app):
    celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'],
                    broker=app.config['CELERY_BROKER_URL'])
    celery.conf.update(app.config)
    TaskBase = celery.Task
    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery
示例#37
0
def create_app():
    mongo_db_client = pymongo.MongoClient(
        os.getenv('DATABASE_CONNECTION_STRING'))
    db = mongo_db_client[os.getenv('DATABASE_NAME')]
    collection = db['todo_app_items']
    users_collection = db['users']

    app = Flask(__name__)
    app.config.from_object('todo_app.flask_config.Config')
    app.secret_key = os.getenv('SECRET_KEY')
    login_manager = LoginManager()

    web_application_client = WebApplicationClient(os.getenv('CLIENT_ID'))

    class User(UserMixin):
        def __init__(self, id, name, user_role):
            self.id = id
            self.name = name
            self.user_role = user_role

    @login_manager.unauthorized_handler
    def unauthenticated():
        return redirect(
            web_application_client.prepare_request_uri(
                'https://github.com/login/oauth/authorize'))

    @login_manager.user_loader
    def load_user(user_id):
        query = {'github_id': user_id}
        db_user = users_collection.find_one(query)
        user = User(user_id, db_user['name'], db_user['user_role'])
        return user

    login_manager.init_app(app)

    @app.route('/login/callback', methods=['GET'])
    def login_user_callback():
        token_url, headers, data = web_application_client.prepare_token_request(
            'https://github.com/login/oauth/access_token',
            code=request.args['code'],
            client_id=os.getenv('CLIENT_ID'),
            client_secret=os.getenv('CLIENT_SECRET'))

        headers['Accept'] = 'application/json'
        response = requests.post(token_url, headers=headers, data=data)
        web_application_client.parse_request_body_response(response.text)
        access_token = web_application_client.token['access_token']
        header = {'Authorization': f'Bearer {access_token}'}
        response = requests.get('https://api.github.com/user',
                                headers=header).json()
        github_id = str(response['id'])

        query = {'github_id': github_id}
        db_user = users_collection.find_one(query)

        if (db_user) == None:
            if (users_collection.count_documents({}) == 0):
                user_role = 'admin'
            else:
                user_role = 'reader'

            post = {
                'name': response['login'],
                'github_id': github_id,
                'user_role': user_role
            }
            users_collection.insert_one(post)
            db_user = users_collection.find_one(query)

        user = User(db_user['github_id'], db_user['name'],
                    db_user['user_role'])
        login_user(user)
        return redirect('/')

    def is_writer():
        return app.config[
            'LOGIN_DISABLED'] or current_user.user_role == 'writer'

    def is_admin():
        return app.config['LOGIN_DISABLED'] or current_user.user_role == 'admin'

    @app.route('/')
    @login_required
    def index():
        items = collection.find()
        cards = []
        for item in items:
            cards.append(
                Item(item['_id'], item['name'], item['description'],
                     item['due_date'].strftime('%d/%m/%Y'), item['status']))
        item_view_model = ViewModel(cards)
        return render_template('index.html',
                               view_model=item_view_model,
                               is_writer=is_writer(),
                               is_admin=is_admin())

    @app.route('/create-todo/', methods=['POST'])
    def create_todo():
        if not is_writer():
            return redirect('/')

        title = request.form.get('title')
        desc = request.form.get('description')
        due = request.form.get('due-date')
        post = {
            'name': title,
            'description': desc,
            'due_date': datetime.fromisoformat(due),
            'status': todo_status
        }
        collection.insert_one(post)
        return redirect('/')

    @app.route('/todo/<id>', methods=['POST'])
    def to_do(id):
        if not is_writer():
            return redirect('/')

        query = {'_id': ObjectId(id)}
        update_values = {'$set': {'status': todo_status}}
        collection.update_one(query, update_values)
        return redirect('/')

    @app.route('/doing/<id>', methods=['POST'])
    def doing(id):
        if not is_writer():
            return redirect('/')

        query = {'_id': ObjectId(id)}
        update_values = {'$set': {'status': doing_status}}
        collection.update_one(query, update_values)
        return redirect('/')

    @app.route('/done/<id>', methods=['POST'])
    def done(id):
        if not is_writer():
            return redirect('/')

        query = {'_id': ObjectId(id)}
        update_values = {'$set': {'status': done_status}}
        collection.update_one(query, update_values)
        return redirect('/')

    @app.route('/delete/<id>', methods=['POST'])
    def delete(id):
        if not is_writer():
            return redirect('/')

        query = {'_id': ObjectId(id)}
        collection.delete_one(query)
        return redirect('/')

    @app.route('/users', methods=['GET'])
    def users():
        db_users = users_collection.find()
        users = []
        for item in db_users:
            user = User(item['github_id'], item['name'], item['user_role'])
            users.append(user)
        return render_template('users.html', users=users)

    @app.route('/update-user-role/<id>/<user_role>', methods=['POST'])
    def update_user_role(id, user_role):
        if not is_admin():
            return redirect('/')

        query = {'github_id': id}
        update_values = {'$set': {'user_role': user_role}}
        users_collection.update_one(query, update_values)
        return redirect('/users')

    return app
示例#38
0
def setup_google_authorization(app, CFG):
    # If any of this stuff is not set, consider
    # Google Authorization not being enabled.
    if "Google_Authorization" not in CFG.sections():
        return

    ga_CFG = CFG["Google_Authorization"]

    def get_google_provider_cfg():
        if ga_CFG is None:
            return None
        return requests.get(GOOGLE_DISCOVERY_URL).json()

    GOOGLE_CLIENT_ID = ga_CFG.get("google_client_id", "None")
    if GOOGLE_CLIENT_ID == "None":
        return

    GOOGLE_CLIENT_SECRET = ga_CFG.get("google_client_secret", "None")
    if GOOGLE_CLIENT_SECRET == "None":
        return

    GOOGLE_DISCOVERY_URL = (
        "https://accounts.google.com/.well-known/openid-configuration")

    # OAuth2 google client setup
    google_client = WebApplicationClient(GOOGLE_CLIENT_ID)

    @app.route("/login_google")
    def login_google():
        if is_authenticated(session, request):
            return redirect(url_for(".me"))

        # Find out what URL to hit for Google login
        google_provider_cfg = get_google_provider_cfg()
        if google_provider_cfg is None:
            return global_vars.redirect_error(
                "Google Authentication impossible.", error_code=400)

        authorization_endpoint = google_provider_cfg["authorization_endpoint"]

        # Use library to construct the request for Google login and provide
        # scopes that let you retrieve user's profile from Google
        request_uri = google_client.prepare_request_uri(
            authorization_endpoint,
            redirect_uri=request.base_url + "/callback",
            scope=["openid", "email", "profile"],
        )
        return redirect(request_uri)

    @app.route("/login_google/callback")
    def callback():
        if is_authenticated(session, request):
            return redirect(url_for(".me"))

        # Authorization code Google sent back.
        auth_code = request.args.get("code")

        google_provider_cfg = get_google_provider_cfg()
        if google_provider_cfg is None:
            return global_vars.redirect_error(
                "Google Authentication impossible.", error_code=400)

        # Getting a URL to hit  to get tokens that allow to ask for access.
        token_endpoint = google_provider_cfg["token_endpoint"]

        # Prepare and send a request to get the token.
        token_url, headers, body = google_client.prepare_token_request(
            token_endpoint,
            authorization_response=request.url,
            redirect_url=request.base_url,
            code=auth_code,
        )
        token_response = requests.post(
            token_url,
            headers=headers,
            data=body,
            auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET),
        )

        # Parse the token.
        google_client.parse_request_body_response(
            json.dumps(token_response.json()))

        # Getting a URL that will provide all user information.
        userinfo_endpoint = google_provider_cfg["userinfo_endpoint"]
        uri, headers, body = google_client.add_token(userinfo_endpoint)
        userinfo_response = requests.get(uri, headers=headers,
                                         data=body).json()

        # Checking whether user's email is actually verified.
        if userinfo_response.get("email_verified"):
            unique_id = userinfo_response["sub"]
            users_email = userinfo_response["email"]
            picture = userinfo_response["picture"]
            users_name = userinfo_response["given_name"]
        else:
            return global_vars.redirect_error(
                "User email not available or not verified by Google.", 400)

        # Try to find a User_Info matching this id in DB.
        user = User_Info.get(google_id=unique_id)
        if user is None:
            user = User_Info(
                name=users_name,
                email=users_email,
                profile_pic=picture,
                google_id=unique_id,
            )
            user.insert()
            """
            session_info = user.insert()
            session["user_id"] = user.user_id
            session["key"] = session_info["key"]
            """

        # Begin user session by logging the user in
        login_user(user, remember=True)

        client = global_vars.clients_by_sid[request.sid]
        client.user_info = user
        client.client_info.user_id = user.user_id

        # Send user back to homepage
        return redirect(url_for(".me"))
示例#39
0
文件: app.py 项目: aphrx/jabber
    login_user,
    logout_user,
)

app = Flask(__name__, template_folder='templates')
# We can make this secret key as environ variable later to sign cookies
app.secret_key = "test"  #os.environ.get("SECRET_KEY")# or os.urandom(24)
app.config["MONGO_URI"] = "mongodb://*****:*****@app.route("/")
def index():
    if 'user_id' in session:
        print(session['user_id'])
    return render_template("index.html")


@app.route("/postings")
def postings():
    # If not logged in, show Login button
示例#40
0
import os
import json
import requests

from flask_login import LoginManager
from oauthlib.oauth2 import WebApplicationClient

from support.config import GoogleOAuth

login_manager = LoginManager()

oauth = GoogleOAuth()
client = WebApplicationClient(oauth.GOOGLE_CLIENT_ID)


def get_google_provider_cfg():
    return requests.get(oauth.GOOGLE_DISCOVERY_URL).json()
示例#41
0
import requests
import datetime
from bson.json_util import dumps
from bson.json_util import loads
from todo_app.flask_config import Config
from todo_app.classModels import Item, ViewModel, User
import pymongo
from werkzeug.exceptions import Forbidden
import logging
from loggly.handlers import HTTPSHandler
from logging import Formatter

client_id = os.getenv("client_id")
client_secret = os.getenv("client_secret")
redirect_uri_value = os.getenv("redirect_uri")
client = WebApplicationClient(client_id)

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    sess = Session()
    app.secret_key = os.getenv("SECRET_KEY")
    app.logger.setLevel(app.config['LOG_LEVEL'])
    app.config['SESSION_TYPE'] = 'filesystem'
    sess.init_app(app)
    if app.config['LOGGLY_TOKEN'] is not None:
        handler = HTTPSHandler(f'https://logs-01.loggly.com/inputs/{app.config["LOGGLY_TOKEN"]}/tag/todo-app')
        handler.setFormatter(Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s"))
        app.logger.addHandler(handler)
    collection=os.getenv("MONGO_COLLECTION")
    mongo_val = pymongo.MongoClient(os.getenv("MONGODB_CONNECTION_STRING"))
示例#42
0
        print("Required environment variables are not set. Exiting...")
        exit(0)

logging.basicConfig(filename=config['PATH_TO_LOG_FILE'],
                    level=logging.INFO,
                    format=config['LOG_FORMAT'])
LOGGER = logging.getLogger()

LOGGER.info("All the environment variable required are set")

# Flask app setup
app = Flask(__name__)
app.secret_key = os.environ.get("SECRET_KEY") or os.urandom(24)

# OAuth 2 client setup
CLIENT = WebApplicationClient(config['CLIENT_ID'])


# --------------------------   ROUTES  -------------------------------
@app.route("/")
def home():
    LOGGER.info("Home page accessed")
    return render_template('connect.html')


@app.route("/login")
def login():
    LOGGER.info(
        "Client requested to connect to Xero. Fetching Xero request URL from Xero"
    )
    request_uri = CLIENT.prepare_request_uri(
示例#43
0
def get_google_client():
    google_client_id = get_google_client_id()
    return WebApplicationClient(google_client_id)
示例#44
0
import requests
import os
import json
from API.models import User
from API.model_datastore import create_user, get_user
from flask import Blueprint, request, redirect, url_for, session
from flask_login import (login_required, login_user, logout_user)
from oauthlib.oauth2 import WebApplicationClient
"""
Google Oauth is templated from https://realpython.com/flask-google-login/
The auth blueprint is used for logging in the user and handling the users session.

"""
auth = Blueprint('auth', __name__)
client = WebApplicationClient(os.environ['GOOGLE_CLIENT_ID'])


@auth.route("/login")
def login():
    # Find out what URL to hit for Google login
    google_provider_cfg = get_google_provider_cfg()
    authorization_endpoint = google_provider_cfg["authorization_endpoint"]

    # Use library to construct the request for login and provide
    # scopes that let you retrieve user's profile from Google
    request_uri = client.prepare_request_uri(
        authorization_endpoint,
        redirect_uri=fix_http(request.base_url) + "/callback",
        scope=["openid", "email", "profile"],
    )
    session['url'] = request.referrer
    def test_prepare_request_body(self):
        """
        see issue #585
            https://github.com/oauthlib/oauthlib/issues/585

        `prepare_request_body` should support the following scenarios:
            1. Include client_id alone in the body (default)
            2. Include client_id and client_secret in auth and not include them in the body (RFC preferred solution)
            3. Include client_id and client_secret in the body (RFC alternative solution)
            4. Include client_id in the body and an empty string for client_secret.
        """
        client = WebApplicationClient(self.client_id)

        # scenario 1, default behavior to include `client_id`
        r1 = client.prepare_request_body()
        self.assertEqual(
            r1, 'grant_type=authorization_code&client_id=%s' % self.client_id)

        r1b = client.prepare_request_body(include_client_id=True)
        self.assertEqual(
            r1b, 'grant_type=authorization_code&client_id=%s' % self.client_id)

        # scenario 2, do not include `client_id` in the body, so it can be sent in auth.
        r2 = client.prepare_request_body(include_client_id=False)
        self.assertEqual(r2, 'grant_type=authorization_code')

        # scenario 3, Include client_id and client_secret in the body (RFC alternative solution)
        # the order of kwargs being appended is not guaranteed. for brevity, check the 2 permutations instead of sorting
        r3 = client.prepare_request_body(client_secret=self.client_secret)
        r3_params = dict(urlparse.parse_qsl(r3, keep_blank_values=True))
        self.assertEqual(len(r3_params.keys()), 3)
        self.assertEqual(r3_params['grant_type'], 'authorization_code')
        self.assertEqual(r3_params['client_id'], self.client_id)
        self.assertEqual(r3_params['client_secret'], self.client_secret)

        r3b = client.prepare_request_body(include_client_id=True,
                                          client_secret=self.client_secret)
        r3b_params = dict(urlparse.parse_qsl(r3b, keep_blank_values=True))
        self.assertEqual(len(r3b_params.keys()), 3)
        self.assertEqual(r3b_params['grant_type'], 'authorization_code')
        self.assertEqual(r3b_params['client_id'], self.client_id)
        self.assertEqual(r3b_params['client_secret'], self.client_secret)

        # scenario 4, `client_secret` is an empty string
        r4 = client.prepare_request_body(include_client_id=True,
                                         client_secret='')
        r4_params = dict(urlparse.parse_qsl(r4, keep_blank_values=True))
        self.assertEqual(len(r4_params.keys()), 3)
        self.assertEqual(r4_params['grant_type'], 'authorization_code')
        self.assertEqual(r4_params['client_id'], self.client_id)
        self.assertEqual(r4_params['client_secret'], '')

        # scenario 4b, `client_secret` is `None`
        r4b = client.prepare_request_body(include_client_id=True,
                                          client_secret=None)
        r4b_params = dict(urlparse.parse_qsl(r4b, keep_blank_values=True))
        self.assertEqual(len(r4b_params.keys()), 2)
        self.assertEqual(r4b_params['grant_type'], 'authorization_code')
        self.assertEqual(r4b_params['client_id'], self.client_id)

        # scenario Warnings
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")  # catch all

            # warning1 - raise a DeprecationWarning if a `client_id` is submitted
            rWarnings1 = client.prepare_request_body(client_id=self.client_id)
            self.assertEqual(len(w), 1)
            self.assertIsInstance(w[0].message, DeprecationWarning)

            # testing the exact warning message in Python2&Python3 is a pain

        # scenario Exceptions
        # exception1 - raise a ValueError if the a different `client_id` is submitted
        with self.assertRaises(ValueError) as cm:
            client.prepare_request_body(client_id='different_client_id')
示例#46
0
文件: auth.py 项目: sm5art/demix
import json

from demix.utils.logging import logger_factory
from demix.auth import encode
from demix.config import get_cfg
from demix.db import get_db
from demix.utils.flask import protected, current_user, custom_error

GOOGLE_DISCOVERY_URL = (
    "https://accounts.google.com/.well-known/openid-configuration")
auth = Blueprint(
    'auth',
    __name__,
)
cfg = get_cfg('google')  # stores google secret info
client = WebApplicationClient(cfg['client_id'])  # needed for google


def get_google_provider_cfg():
    return requests.get(GOOGLE_DISCOVERY_URL).json()


google_provider_cfg = get_google_provider_cfg()
logger = logger_factory(__name__)
db = get_db()


@auth.route("/api/me")
@protected
def me():
    user = current_user()
示例#47
0
    def get_session(self,
                    *,
                    state=None,
                    redirect_uri=None,
                    load_token=False,
                    scopes=None):
        """ Create a requests Session object

        :param str state: session-state identifier to rebuild OAuth session (CSRF protection)
        :param str redirect_uri: callback URL specified in previous requests
        :param list(str) scopes: list of scopes we require access to
        :param bool load_token: load and ensure token is present
        :return: A ready to use requests session, or a rebuilt in-flow session
        :rtype: OAuth2Session
        """

        redirect_uri = redirect_uri or self.oauth_redirect_url
        client_id, _ = self.auth

        if self.auth_flow_type == 'authorization':
            oauth_client = WebApplicationClient(client_id=client_id)
        elif self.auth_flow_type == 'credentials':
            oauth_client = BackendApplicationClient(client_id=client_id)
        else:
            raise ValueError(
                '"auth_flow_type" must be either "authorization" or "credentials"'
            )

        requested_scopes = scopes or self.scopes

        if load_token:
            # gets a fresh token from the store
            token = self.token_backend.get_token()
            if token is None:
                raise RuntimeError(
                    'No auth token found. Authentication Flow needed')

            oauth_client.token = token
            if self.auth_flow_type == 'authorization':
                requested_scopes = None  # the scopes are already in the token (Not if type is backend)
            session = OAuth2Session(client_id=client_id,
                                    client=oauth_client,
                                    token=token,
                                    scope=requested_scopes)
        else:
            session = OAuth2Session(client_id=client_id,
                                    client=oauth_client,
                                    state=state,
                                    redirect_uri=redirect_uri,
                                    scope=requested_scopes)

        session.proxies = self.proxy

        if self.request_retries:
            retry = Retry(total=self.request_retries,
                          read=self.request_retries,
                          connect=self.request_retries,
                          backoff_factor=RETRIES_BACKOFF_FACTOR,
                          status_forcelist=RETRIES_STATUS_LIST)
            adapter = HTTPAdapter(max_retries=retry)
            session.mount('http://', adapter)
            session.mount('https://', adapter)

        return session