diff --git a/authlibs/api/api.py b/authlibs/api/api.py index e2fa702..ed05250 100644 --- a/authlibs/api/api.py +++ b/authlibs/api/api.py @@ -11,7 +11,9 @@ from authlibs.slackutils import automatch_missing_slack_ids,add_user_to_channel from authlibs.members.notices import send_all_notices import slackapi +import base64 import random,string +import tempfile # You must call this modules "register_pages" with main app's "create_rotues" blueprint = Blueprint("api", __name__, template_folder='templates', static_folder="static",url_prefix="/api") @@ -316,6 +318,62 @@ def api_member_search_handler(searchstr): output = json_dump(ubersearch(searchstr,only=['members'],membertypes=['Active']),indent=2) return output, 200, {'Content-Type': 'application/json', 'Content-Language': 'en'} +@blueprint.route('/v1/kiosklog', methods=['OPTIONS']) +#@api_only +def api_v1_kiosklog_options(): + return "", 200, { + 'Access-Control-Allow-Origin':'https://plachenko.github.io', + 'Access-Control-Allow-Headers':'Content-Type,Authorization', + 'Access-Control-Allow-Credentials':'true', + 'Access-Control-Allow-Methods':'OPTIONS,GET', + 'Content-Type': 'application/json', 'Content-Language': 'en'} + +@blueprint.route('/v1/kiosklog', methods=['POST']) +@api_only +def api_v1_kiosklog(): + data=request.get_json() + print "REQUEST",request + print "DATA",data + if not data: + return json_dump({'result':'failure','reason':'Not JSON request'}), 400, {'Access-Control-Allow-Origin':'*','Content-type': 'application/json'} + + if 'user' not in data or 'event' not in data: + return json_dump({'result':'failure','reason':'Field missing'}), 400, {'Access-Control-Allow-Origin':'*','Content-type': 'application/json'} + + + imagename="" + if 'visibleimage' in data: + try: + img = base64.b64decode(data['visibleimage']) + tf = tempfile.NamedTemporaryFile(dir="authlibs/logs/static/kioskimages",suffix='.jpg',delete=False) + tf.write(img) + imagename=tf.name + nf = imagename.replace(".jpg","_ir.jpg") + ff = open(nf,"w") + img_ir = base64.b64decode(data['irimage']) + ff.write(img_ir) + imagename = "kioskimages:"+imagename.split("/")[-1].replace(".jpg","") + except BaseException as e: + print e + pass + m = Member.query.filter(Member.member==data['user']).one_or_none() + if not m: + return json_dump({'result':'failure','reason':'Member not found'}), 400, {'Access-Control-Allow-Origin':'*','Content-type': 'application/json'} + + e=None + if data['event'] == 'ACCEPTED': + e = eventtypes.RATTBE_LOGEVENT_MEMBER_KIOSK_ACCEPTED.id + elif data['event'] == 'DENIED': + e = eventtypes.RATTBE_LOGEVENT_MEMBER_KIOSK_DENIED.id + elif data['event'] == 'FAILED': + e = eventtypes.RATTBE_LOGEVENT_MEMBER_KIOSK_FAILED.id + else: + return json_dump({'result':'failure','reason':'Bad event type'}), 400, {'Access-Control-Allow-Origin':'*','Content-type': 'application/json'} + + authutil.log(e,member_id=m.id,message=imagename,commit=0) + db.session.commit() + return json_dump({'result':'success'}), 200, {'Access-Control-Allow-Origin':'*','Content-type': 'application/json'} + # REQUIRE json payload with proper JSON content-type as such: # curl http://testkey:testkey@127.0.0.1:5000/api/v1/authorize -H "Content-Type:application/json" -d '{"slack_id":"brad.goodman","resources":[4],"members":[11,22,32],"level":2}' # This is a hyper-prorected API call, because it cal assume the identity of anyone it specifies @@ -490,6 +548,16 @@ def api_v1_get_resources(): result.append({'id':x.id,'name':x.name,'short':x.short,'slack_admin_chan':x.slack_admin_chan,'slack_chan':x.slack_chan}) return json_dump(result), 200, {'Content-Type': 'application/json', 'Content-Language': 'en'} +@blueprint.route('/v1/resources//fob/', methods=['OPTIONS']) +#@api_only +def api_v1_show_resource_fob_options(id,fob): + return "", 200, { + 'Access-Control-Allow-Origin':'https://plachenko.github.io', + 'Access-Control-Allow-Headers':'Content-Type,Authorization', + 'Access-Control-Allow-Credentials':'true', + 'Access-Control-Allow-Methods':'OPTIONS,GET', + 'Content-Type': 'application/json', 'Content-Language': 'en'} + @blueprint.route('/v1/resources//fob/', methods=['GET']) @api_only def api_v1_show_resource_fob(id,fob): @@ -499,9 +567,19 @@ def api_v1_show_resource_fob(id,fob): output = accesslib.getAccessControlList(rid) for x in json.loads(output): if int(x['raw_tag_id']) == fob: - return json.dumps(x), 200, {'Content-Type': 'application/json', 'Content-Language': 'en'} + return json.dumps(x), 200, {'Access-Control-Allow-Origin':'*','Content-Type': 'application/json', 'Content-Language': 'en'} return "{\"status\":\"Fob not found\"}", 404, {'Content-Type': 'application/json', 'Content-Language': 'en'} +@blueprint.route('/v1/resources//acl', methods=['OPTIONS']) +#@api_only +def api_v1_show_resource_acl_options(id): + return "", 200, { + 'Access-Control-Allow-Origin':'https://plachenko.github.io', + 'Access-Control-Allow-Headers':'Content-Type,Authorization', + 'Access-Control-Allow-Credentials':'true', + 'Access-Control-Allow-Methods':'OPTIONS,GET', + 'Content-Type': 'application/json', 'Content-Language': 'en'} + @blueprint.route('/v1/resources//acl', methods=['GET']) @api_only def api_v1_show_resource_acl(id): @@ -509,7 +587,7 @@ def api_v1_show_resource_acl(id): rid = safestr(id) # Note: Returns all so resource can know who tried to access it and failed, w/o further lookup output = accesslib.getAccessControlList(rid) - return output, 200, {'Content-Type': 'application/json', 'Content-Language': 'en'} + return output, 200, {'Access-Control-Allow-Origin':'*','Content-Type': 'application/json', 'Content-Language': 'en'} @blueprint.route('/ubersearch/',methods=['GET']) @login_required diff --git a/authlibs/eventtypes.py b/authlibs/eventtypes.py index cb13cf4..6ea4e4a 100644 --- a/authlibs/eventtypes.py +++ b/authlibs/eventtypes.py @@ -90,6 +90,18 @@ class RATTBE_LOGEVENT_MEMBER_NOTICE_SENT: id=1020 desc='Notice Sent' +class RATTBE_LOGEVENT_MEMBER_KIOSK_ACCEPTED: + id=1021 + desc='Entry Kiosk Accepted' + +class RATTBE_LOGEVENT_MEMBER_KIOSK_DENIED: + id=1022 + desc='Entry Kiosk Denied' + +class RATTBE_LOGEVENT_MEMBER_KIOSK_FAILED: + id=1024 + desc='Entry Kiosk Failed' + class RATTBE_LOGEVENT_SYSTEM_OTHER: id=2000 desc='Other System Event' diff --git a/authlibs/logs/logs.py b/authlibs/logs/logs.py index 0f5098b..e9cdb9e 100644 --- a/authlibs/logs/logs.py +++ b/authlibs/logs/logs.py @@ -269,7 +269,11 @@ def generate(fmt=None): r['event']=l.event_type if l.message: - r['message']=l.message + if (l.message.startswith("kioskimages:")): + r['message']="See Images" + r['extern_link']=url_for("logs.kioskentry",ke=l.message.replace("kioskimages:","")) + else: + r['message']=l.message else: r['message']="" @@ -385,7 +389,14 @@ def generate(fmt=None): return render_template('logs.html',logs=logs,resources=fil_resources,tools=fil_tools,nodes=fil_nodes,meta=meta) -@blueprint.route('/large.csv') +@blueprint.route('/kiosk/') +def kioskentry(ke): + ke = ke.replace("/","") + ke = ke.replace(".","") + ke = ke.replace("kioskimages:","") + return render_template('kiosk_entry.html',entry=ke) + +blueprint.route('/large.csv') def generate_large_csv(): def generate(): for row in iter_all_rows(): diff --git a/authlibs/logs/static/kioskimages/EMPTY b/authlibs/logs/static/kioskimages/EMPTY new file mode 100644 index 0000000..e69de29 diff --git a/authlibs/logs/templates/kiosk_entry.html b/authlibs/logs/templates/kiosk_entry.html new file mode 100644 index 0000000..8cab130 --- /dev/null +++ b/authlibs/logs/templates/kiosk_entry.html @@ -0,0 +1,11 @@ +{% extends "layout_bootstrap.html" %} +{% block body %} +

Kiosk Entry

+ +
+
+ + +
+
+{% endblock %} diff --git a/authlibs/logs/templates/logs.html b/authlibs/logs/templates/logs.html index 318b319..8206d44 100644 --- a/authlibs/logs/templates/logs.html +++ b/authlibs/logs/templates/logs.html @@ -158,7 +158,13 @@ {{ l.doneby }} - {{ l.message }} + + {% if l.extern_link %} + {{ l.message }} + {% else %} + {{ l.message }} + {% endif %} + {% endfor %} diff --git a/authlibs/members/templates/member_header.html b/authlibs/members/templates/member_header.html index b9d2959..4550cfb 100644 --- a/authlibs/members/templates/member_header.html +++ b/authlibs/members/templates/member_header.html @@ -2,11 +2,11 @@
- {% if rec.has_privs() %} + {% if current_user.has_privs() %} {% endif %} - {% if rec.has_privs() %} + {% if current_user.has_privs() %} {% endif %} diff --git a/authlibs/slackutils.py b/authlibs/slackutils.py index 9e4f393..ec3b933 100755 --- a/authlibs/slackutils.py +++ b/authlibs/slackutils.py @@ -27,7 +27,7 @@ from templateCommon import * Config = init.get_config() -slack_token = Config.get('Slack','ADMIN_API_TOKEN') +slack_token = Config.get('Slack','BOT_API_TOKEN') slack_disabled = Config.has_option('Slack','Disabled') diff --git a/authlibs/training/training.py b/authlibs/training/training.py index 6bdfdb4..d869e1c 100644 --- a/authlibs/training/training.py +++ b/authlibs/training/training.py @@ -29,7 +29,7 @@ def training(): ar['desc'] = 'Authorization was revoked' ar['status'] = 'cannot' elif ma.level >0: - ar['desc'] = 'Your are a Resource Manager' + ar['desc'] = 'You\'r are a Resource Manager' ar['status'] = 'already' else: #User has no access - can they train? @@ -148,9 +148,6 @@ def quiz(resource): if not r: flash("No resrouce","warning") return redirect(url_for('empty')) - if accesslib.user_privs_on_resource(member=current_user,resource=r) < AccessByMember.LEVEL_ARM: - flash("You are not authorized to edit this quiz","warning") - return redirect(url_for('training.training')) qz = ResourceQuiz.query.filter(ResourceQuiz.resource_id == r.id).all() if len(qz) == 0: flash("Quiz is missing - contact Resource Manager","warning") diff --git a/templates/layout_bootstrap.html b/templates/layout_bootstrap.html index c833dee..33eed9e 100644 --- a/templates/layout_bootstrap.html +++ b/templates/layout_bootstrap.html @@ -88,7 +88,7 @@