views.py 5 KB
Newer Older
janis.streib's avatar
janis.streib committed
1
2
3
4
from flask import render_template, request, redirect, abort, flash, jsonify
from net_suite import db
from net_suite.views import get_db_conn
from net_suite.model import *
janis.streib's avatar
janis.streib committed
5
6
7
8
9
10
from . import login_oic, app
from oic.oic.message import RegistrationResponse, AuthorizationResponse
from oic.oic import Client
from oic.utils.authn.client import CLIENT_AUTHN_METHOD
from oic import rndstr
from oic.utils.http_util import Redirect
janis.streib's avatar
janis.streib committed
11
12


janis.streib's avatar
janis.streib committed
13
14
15
16
17
18
19
20
def get_client():
    oic_client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    oic_provider_info = oic_client.provider_config(app.config.get('OIC_ENDPOINT'))
    info = {"client_id": app.config.get('OIC_CLIENT_ID'), "client_secret": app.config.get('OIC_CLIENT_SECRET')}
    client_reg = RegistrationResponse(**info)
    oic_client.store_registration_info(client_reg)
    return oic_client

janis.streib's avatar
FMT    
janis.streib committed
21

janis.streib's avatar
janis.streib committed
22
23
24
25
26
27
28
def get_authorization_response(client):
    authorization_response = client.parse_response(
        AuthorizationResponse,
        info=request.args,
        sformat='dict')
    return authorization_response

janis.streib's avatar
FMT    
janis.streib committed
29

janis.streib's avatar
janis.streib committed
30
@login_oic.route('/api/login', methods=['POST'])
janis.streib's avatar
janis.streib committed
31
32
33
def api_login():
    s = request.environ['beaker.session']
    if 'login' not in s:
janis.streib's avatar
janis.streib committed
34
35
36
37
38
39
40
41
42
43
        oic_client = get_client()
        s["state"] = rndstr()
        s["nonce"] = rndstr()
        debug_t_host = request.environ.get('HTTP_ORIGIN', None)
        s.save()
        args = {
            "client_id": oic_client.client_id,
            "response_type": "code",
            "scope": ["openid", 'profile', 'email'],
            "nonce": s["nonce"],
janis.streib's avatar
FMT    
janis.streib committed
44
45
46
            "redirect_uri": app.config.get('DEBUG_OIC_REDIR') + '/' + debug_t_host.split('//', 1)[
                1] if db.host_omdl.OP_ENV_IS_DEVEL and request.host.split(':')[0] == 'localhost' else app.config.get(
                'OIC_REDIR'),
janis.streib's avatar
janis.streib committed
47
48
49
50
51
52
            "state": s["state"]
        }
        auth_req = oic_client.construct_AuthorizationRequest(request_args=args)
        login_url = auth_req.request(oic_client.authorization_endpoint)
        return jsonify({'status': 'usr_redir', 'url': login_url})
    if not 'login_token' in s and not isinstance(s['login'], SimpleKITUser):
janis.streib's avatar
FMT    
janis.streib committed
53
        s['login_token'] = s['login'].create_session_token(db, get_db_conn(), False)
janis.streib's avatar
janis.streib committed
54
55
56
        s.save()
    return jsonify({'login': s['login'], 'token': s.get('login_token', None)})

janis.streib's avatar
FMT    
janis.streib committed
57

janis.streib's avatar
janis.streib committed
58
59
60
61
62
def user_from_userinfo(db, conn, userinfo):
    user = DBMgr.get_by_login_name(db, conn, userinfo['preferred_username'])
    if user is not None:
        return user
    return SimpleKITUser(login_name=userinfo['preferred_username'],
janis.streib's avatar
FMT    
janis.streib committed
63
64
65
66
                         first_name=userinfo.get('givenName', None),
                         last_name=userinfo.get('sn', None),
                         email=userinfo['email'])

janis.streib's avatar
janis.streib committed
67
68
69
70
71
72
73
74
75
76
77
78
79

@login_oic.route('/api/oic_responder')
def oic_responder(t_host=None):
    s = request.environ['beaker.session']
    oic_client = get_client()
    aresp = get_authorization_response(oic_client)

    code = aresp["code"]
    assert aresp["state"] == s["state"]
    args = {
        "code": aresp['code'],
        "redirect_uri": app.config.get('OIC_REDIR'),
    }
janis.streib's avatar
FMT    
janis.streib committed
80

janis.streib's avatar
janis.streib committed
81
    resp = oic_client.do_access_token_request(state=aresp['state'],
janis.streib's avatar
FMT    
janis.streib committed
82
83
                                              request_args=args,
                                              authn_method='client_secret_basic')
janis.streib's avatar
janis.streib committed
84
85
86
87
88
    userinfo = oic_client.do_user_info_request(state=s["state"])
    s['login'] = user_from_userinfo(db, get_db_conn(), userinfo)
    s.save()
    return redirect('/oic_login')

janis.streib's avatar
FMT    
janis.streib committed
89

janis.streib's avatar
janis.streib committed
90
91
92
93
@login_oic.route('/api/debug_oic_responder/<t_host>')
def debug_oic_responder(t_host=None):
    if not (db.host_omdl.OP_ENV_IS_DEVEL and t_host is not None and t_host.split(':')[0] == 'localhost'):
        abort(404)
janis.streib's avatar
FMT    
janis.streib committed
94

janis.streib's avatar
janis.streib committed
95
96
97
98
99
    oic_client = get_client()
    aresp = get_authorization_response(oic_client)
    code = aresp["code"]
    args = {
        "code": aresp['code'],
janis.streib's avatar
FMT    
janis.streib committed
100
        "redirect_uri": app.config.get('DEBUG_OIC_REDIR') + '/' + t_host,
janis.streib's avatar
janis.streib committed
101
    }
janis.streib's avatar
FMT    
janis.streib committed
102

janis.streib's avatar
janis.streib committed
103
    resp = oic_client.do_access_token_request(state=aresp['state'],
janis.streib's avatar
FMT    
janis.streib committed
104
105
                                              request_args=args,
                                              authn_method='client_secret_basic')
janis.streib's avatar
janis.streib committed
106
107
    print(resp)
    userinfo = oic_client.do_user_info_request(state=aresp["state"])
janis.streib's avatar
FMT    
janis.streib committed
108
109
    new_target = 'http://' + t_host + '/api/debug_oic_receiver'
    return render_template('debug_forward.html', **{'redir': t_host, 'new_target': new_target, 'userinfo': userinfo})
janis.streib's avatar
janis.streib committed
110
111
112
113
114
115
116
117
118


@login_oic.route('/api/debug_oic_receiver', methods=['POST'])
def debug_oic_receiver():
    if not db.host_omdl.OP_ENV_IS_DEVEL:
        abort(404)
    s = request.environ['beaker.session']
    s['login'] = user_from_userinfo(db, get_db_conn(), request.form)
    s.save()
janis.streib's avatar
FMT    
janis.streib committed
119
120
    return redirect('http://' + request.form['redir'] + '/oic_login')

janis.streib's avatar
janis.streib committed
121
122
123
124
125
126
127
128
129
130

@login_oic.route('/api/logout', methods=['POST'])
def api_logout():
    s = request.environ['beaker.session']
    if 'login' in s:
        if request.json.get('token_pk', None) is not None:
            APIToken(login_name=s['login'].login_name, pk=int(request.json['token_pk'])).delete(db, get_db_conn())
        s.delete()
    s.save()
    return jsonify({'logout': 'success'})