Merge branch 'feature/internal-admin-api' into 'develop'

Internal admin api views

See merge request isard/isard-sso!40
Josep Maria Viñolas Auquer 2021-08-22 07:50:38 +00:00
commit 31d994d917
7 changed files with 112 additions and 5 deletions

View File

@ -87,6 +87,7 @@ Import all views
from .views import LoginViews
from .views import WebViews
from .views import ApiViews
from .views import InternalViews

View File

@ -36,6 +36,11 @@ ram_users={
'id': os.environ["KEYCLOAK_USER"],
'password': os.environ["KEYCLOAK_PASSWORD"],
'role': 'admin',
},
os.environ["WORDPRESS_MARIADB_USER"]: {
'id': os.environ["WORDPRESS_MARIADB_USER"],
'password': os.environ["WORDPRESS_MARIADB_PASSWORD"],
'role': 'manager',
}
}

View File

@ -15,8 +15,6 @@ import threading
threads={}
# q = Queue.Queue()
from pprint import pprint
from keycloak.exceptions import KeycloakGetError
@app.route('/api/resync')
@ -99,8 +97,6 @@ def groups(provider=False):
if provider == 'keycloak':
return json.dumps(app.admin.delete_keycloak_groups()), 200, {'Content-Type': 'application/json'}
### SYSADM USERS ONLY
@app.route('/api/external', methods=['POST', 'PUT', 'GET','DELETE'])

View File

@ -0,0 +1,83 @@
#!flask/bin/python
# coding=utf-8
from admin import app
import logging as log
import traceback
import time,json
import sys,os
from flask import request
from .decorators import is_internal
@app.route('/api/internal/users', methods=['GET'])
@is_internal
def internal_users():
if request.method == 'GET':
sorted_users = sorted(app.admin.get_mix_users(), key=lambda k: k['username'])
# group_users = [user for user in sorted_users if data['path'] in user['keycloak_groups']]
users=[]
for user in sorted_users:
if not user['enabled']: continue
users.append(user_parser(user))
return json.dumps(users), 200, {'Content-Type': 'application/json'}
@app.route('/api/internal/users/filter', methods=['POST'])
@is_internal
def internal_users_search():
if request.method == 'POST':
data=request.get_json(force=True)
users = app.admin.get_mix_users()
result = [user_parser(user) for user in users
if data['text'] in user['username'] or
data['text'] in user['first'] or
data['text'] in user['last'] or
data['text'] in user['email']]
sorted_result = sorted(result, key=lambda k: k['id'])
return json.dumps(sorted_result), 200, {'Content-Type': 'application/json'}
@app.route('/api/internal/groups', methods=['GET'])
@is_internal
def internal_groups():
if request.method == 'GET':
sorted_groups = sorted(app.admin.get_mix_groups(), key=lambda k: k['name'])
groups=[]
for group in sorted_groups:
if not group['path'].startswith('/'): continue
groups.append({'id':group['path'],
'name':group['name'],
'description':group.get('description','')})
return json.dumps(groups), 200, {'Content-Type': 'application/json'}
@app.route('/api/internal/group/users', methods=['POST'])
@is_internal
def internal_group_users():
if request.method == 'POST':
data=request.get_json(force=True)
sorted_users = sorted(app.admin.get_mix_users(), key=lambda k: k['username'])
# group_users = [user for user in sorted_users if data['path'] in user['keycloak_groups']]
users=[]
for user in sorted_users:
if data['path'] not in user['keycloak_groups'] or not user['enabled']: continue
users.append(user_parser(user))
return json.dumps(users), 200, {'Content-Type': 'application/json'}
@app.route('/api/internal/roles', methods=['GET'])
@is_internal
def internal_roles():
if request.method == 'GET':
roles=[]
for role in sorted(app.admin.get_roles(), key=lambda k: k['name']):
if role['name'] == 'admin': continue
roles.append({'id':role['id'],
'name':role['name'],
'description':role.get('description','')})
return json.dumps(roles), 200, {'Content-Type': 'application/json'}
def user_parser(user):
return {'id':user['username'],
'first':user['first'],
'last':user['last'],
'role':user['roles'][0] if len(user['roles']) else None,
'email':user['email'],
'groups':user['keycloak_groups']}

View File

@ -0,0 +1,18 @@
#!flask/bin/python
# coding=utf-8
from functools import wraps
from flask import request, redirect, url_for
from flask_login import logout_user
import socket
def is_internal(fn):
@wraps(fn)
def decorated_view(*args, **kwargs):
remote_addr=request.headers['X-Forwarded-For'].split(',')[0] if 'X-Forwarded-For' in request.headers else request.remote_addr.split(',')[0]
## Now only checks if it is wordpress container,
## but we should check if it is internal net and not haproxy
if socket.gethostbyname('isard-apps-wordpress') == remote_addr: return fn(*args, **kwargs)
logout_user()
return redirect(url_for('login'))
return decorated_view

View File

@ -166,6 +166,10 @@ backend be_wp
acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found
http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host
http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto
http-request set-header X-SSL %[ssl_fc]
#reqadd X-Forwarded-Proto:\ https
http-request set-header X-Forwarded-Proto https
server wp isard-apps-wordpress:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none