Commit ff93ed77 authored by janis.streib's avatar janis.streib 🦉
Browse files

ADD: OIC login

parent 69859523
Pipeline #94798 passed with stages
in 7 minutes and 14 seconds
export default {
NETDB_API_BASE_URL: "/api/3.0/"
NETDB_API_BASE_URL: "/api/3.0/",
ENABLE_OIC: true,
}
import Axios from 'axios';
import config from '@/../netvs.config'
const LOGIN_RESOURCE = '/api/login';
const LOGOUT_RESOURCE = '/api/logout';
export default {
login(username, password) {
if (config.ENABLE_OIC) {
return Axios.post(LOGIN_RESOURCE)
}
return Axios.post(LOGIN_RESOURCE, {'username': username, 'password': password})
},
logout(token_pk) {
......
......@@ -30,6 +30,16 @@ export default new Router({
}
}
},
{
path: '/oic_login',
name: 'login',
component: () => import('./views/OICLogin.vue'),
meta: {
resolveName: function () {
return "OIC Login"
}
}
},
{
path: '/user/tokens',
name: 'tokens',
......
......@@ -2,29 +2,32 @@
<div class="login">
<p>Willkommen auf der Eingangsseite zur Selbstverwaltung der aktuell angebotenen Basisdienste für das
KITnet.</p>
<div class="jumbotron">
<b-jumbotron>
<div class="pull-left">
<img class="hidden-xs hidden-sm pull-left" src="@/assets/img/scc_logo.png"/>
</div>
<b-form @submit="login">
<div class="pull-left logincont">
<label for="username">KIT-Account</label>
<input id="username" class="form-control" v-model="username" autofocus type="text"/>
<label for="password">Passwort</label>
<input id="password" class="form-control" v-model="password" type="password"/><br/>
<template v-if="!use_oic">
<label for="username">KIT-Account</label>
<input id="username" class="form-control" v-model="username" autofocus type="text"/>
<label for="password">Passwort</label>
<input id="password" class="form-control" v-model="password" type="password"/><br/>
</template>
<button class="btn btn-outline-primary pull-right" type="submit"><i
class="fa fa-sign-in" aria-hidden="true"> </i> Anmelden
</button>
</div>
</b-form>
<span class="clearfix"></span>
</div>
</b-jumbotron>
</div>
</template>
<script>
import LoginService from '@/api-services/login.service'
import router from '@/router'
import config from '@/../netvs.config'
export default {
name: 'net_suite_login',
......@@ -32,13 +35,14 @@
return {
username: '',
password: '',
prevRoute: null
prevRoute: null,
use_oic: config.ENABLE_OIC
}
},
beforeRouteEnter(to, from, next) {
next(vm => {
window.console.debug(from.path)
if(from.path != '/login') {
if (from.path != '/login') {
vm.prevRoute = from
}
})
......@@ -48,7 +52,11 @@
ev.preventDefault()
let self = this
LoginService.login(this.username, this.password).then((response) => {
if(response.data.login != null) {
if(response.data.status == 'usr_redir') {
window.location = response.data.url
return
}
if (response.data.login != null) {
self.$store.commit('login', {user: response.data.login, token: response.data.token})
router.push(self.prevRoute.path)
} else {
......
<template>
<div class="login">
<h1>Logging in...</h1>
</div>
</template>
<script>
import LoginService from '@/api-services/login.service'
export default {
name: 'net_suite_login',
created: function () {
let self = this
LoginService.login().then((response) => {
if (response.data.status == 'usr_redir') {
window.location = response.data.url
return
}
if (response.data.login != null) {
self.$store.commit('login', {user: response.data.login, token: response.data.token})
self.$router.push('/')
} else {
// TODO: invalid login
}
})
}
}
</script>
......@@ -8,7 +8,7 @@ module.exports = {
'^/api': {
target: 'https://netvs-devel-devel.scc.kit.edu',
//target: 'http://localhost:5000
changeOrigin: true
changeOrigin: false
}
}
}
......
......@@ -7,7 +7,7 @@ import sys
import os
import inspect
import subprocess
from .model import DBObject, MetaDBObject
from .model import DBObject, MetaDBObject, SimpleKITUser
import importlib
import kitnet.lib.netdd
import kitnet.lib.host_oper_mode_data
......@@ -39,7 +39,7 @@ class ModMetaData(object):
class CustomJSONEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, DBObject):
if isinstance(obj, DBObject) or isinstance(obj, SimpleKITUser):
return {k: v for (k, v) in obj.__dict__.items() if not k.startswith('_')}
elif isinstance(obj, ipaddress.IPv4Network) or isinstance(obj, ipaddress.IPv6Network):
return {'address': str(obj), 'netmask': obj.netmask, 'broadcast_address': obj.broadcast_address}
......
from flask import Blueprint
from net_suite import app
login_url = 'login_oic.login'
login_oic = Blueprint('login_oic', __name__)
from oic.oic import Client
from oic import rndstr
from oic.utils.authn.client import CLIENT_AUTHN_METHOD
state = rndstr()
nonce = rndstr()
client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
provider_info = client.provider_config('https://oidc.scc.kit.edu/auth/realms/kit/')
registration_response = client.register(
provider_info["registration_endpoint"])
args = {
"client_id": client.client_id,
"response_type": "code",
"scope": ["openid"],
"nonce": nonce,
"redirect_uri": client.registration_response["redirect_uris"][0],
"state": state
}
print(registration_response)
auth_req = client.construct_AuthorizationRequest(request_args=args)
login_url = auth_req.request(client.authorization_endpoint)
from . import views
......@@ -2,30 +2,123 @@ 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 *
from . import login_oic
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
@login_oic.route('/api/login', methods=['GET', 'POST'])
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
def get_authorization_response(client):
authorization_response = client.parse_response(
AuthorizationResponse,
info=request.args,
sformat='dict')
return authorization_response
@login_oic.route('/api/login', methods=['POST'])
def api_login():
s = request.environ['beaker.session']
if 'login' not in s:
if request.method == 'POST':
username = request.json['username'].strip()
password = request.json['password']
if ldap_con.login(username=username, password=password):
user = DBMgr.get_by_login_name(db, get_db_conn(), username)
if user is not None:
s['login'] = user
s['plan'] = Transaction()
s.save()
return jsonify({'login': user})
else:
user = ldap_con.get_simple_kit_user(username=username)
s['login'] = user
s['plan'] = Transaction()
s.save()
return jsonify({'login': user})
else:
return jsonify({'login': None})
return jsonify({'login': s['login']})
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"],
"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'),
"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):
s['login_token'] = s['login'].create_session_token(db, get_db_conn(), False)
s.save()
return jsonify({'login': s['login'], 'token': s.get('login_token', None)})
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'],
first_name=userinfo.get('givenName', None),
last_name=userinfo.get('sn', None),
email=userinfo['email'])
@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'),
}
resp = oic_client.do_access_token_request(state=aresp['state'],
request_args=args,
authn_method='client_secret_basic')
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')
@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)
oic_client = get_client()
aresp = get_authorization_response(oic_client)
code = aresp["code"]
args = {
"code": aresp['code'],
"redirect_uri": app.config.get('DEBUG_OIC_REDIR') + '/'+t_host,
}
resp = oic_client.do_access_token_request(state=aresp['state'],
request_args=args,
authn_method='client_secret_basic')
print(resp)
userinfo = oic_client.do_user_info_request(state=aresp["state"])
new_target = 'http://'+t_host+'/api/debug_oic_receiver'
return render_template('debug_forward.html', **{'redir':t_host,'new_target': new_target, 'userinfo': userinfo})
@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()
return redirect('http://'+request.form['redir']+'/oic_login')
@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'})
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment