Merge branch 'feature/internal-admin-api' into 'develop'
Internal admin api views See merge request isard/isard-sso!40
commit
31d994d917
|
@ -87,6 +87,7 @@ Import all views
|
||||||
from .views import LoginViews
|
from .views import LoginViews
|
||||||
from .views import WebViews
|
from .views import WebViews
|
||||||
from .views import ApiViews
|
from .views import ApiViews
|
||||||
|
from .views import InternalViews
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,11 @@ ram_users={
|
||||||
'id': os.environ["KEYCLOAK_USER"],
|
'id': os.environ["KEYCLOAK_USER"],
|
||||||
'password': os.environ["KEYCLOAK_PASSWORD"],
|
'password': os.environ["KEYCLOAK_PASSWORD"],
|
||||||
'role': 'admin',
|
'role': 'admin',
|
||||||
|
},
|
||||||
|
os.environ["WORDPRESS_MARIADB_USER"]: {
|
||||||
|
'id': os.environ["WORDPRESS_MARIADB_USER"],
|
||||||
|
'password': os.environ["WORDPRESS_MARIADB_PASSWORD"],
|
||||||
|
'role': 'manager',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@ import threading
|
||||||
threads={}
|
threads={}
|
||||||
# q = Queue.Queue()
|
# q = Queue.Queue()
|
||||||
|
|
||||||
from pprint import pprint
|
|
||||||
|
|
||||||
from keycloak.exceptions import KeycloakGetError
|
from keycloak.exceptions import KeycloakGetError
|
||||||
|
|
||||||
@app.route('/api/resync')
|
@app.route('/api/resync')
|
||||||
|
@ -99,8 +97,6 @@ def groups(provider=False):
|
||||||
if provider == 'keycloak':
|
if provider == 'keycloak':
|
||||||
return json.dumps(app.admin.delete_keycloak_groups()), 200, {'Content-Type': 'application/json'}
|
return json.dumps(app.admin.delete_keycloak_groups()), 200, {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### SYSADM USERS ONLY
|
### SYSADM USERS ONLY
|
||||||
|
|
||||||
@app.route('/api/external', methods=['POST', 'PUT', 'GET','DELETE'])
|
@app.route('/api/external', methods=['POST', 'PUT', 'GET','DELETE'])
|
||||||
|
|
|
@ -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']}
|
|
@ -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
|
|
@ -126,4 +126,4 @@ class WordpressSaml():
|
||||||
self.db.update("""DELETE FROM wp_options WHERE option_name = 'onelogin_saml_advanced_settings_sp_x509cert'""")
|
self.db.update("""DELETE FROM wp_options WHERE option_name = 'onelogin_saml_advanced_settings_sp_x509cert'""")
|
||||||
self.db.update("""DELETE FROM wp_options WHERE option_name = 'onelogin_saml_advanced_settings_sp_privatekey'""")
|
self.db.update("""DELETE FROM wp_options WHERE option_name = 'onelogin_saml_advanced_settings_sp_privatekey'""")
|
||||||
|
|
||||||
nw=WordpressSaml()
|
nw=WordpressSaml()
|
||||||
|
|
|
@ -166,6 +166,10 @@ backend be_wp
|
||||||
acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found
|
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-Host %[req.hdr(Host)] unless existing-x-forwarded-host
|
||||||
http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto
|
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
|
server wp isard-apps-wordpress:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue