| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314 |
- #!/usr/bin/python3
- #
- # Copyright (c) 2019 Clementine Computing LLC.
- #
- # This file is part of PopuFare.
- #
- # PopuFare is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # PopuFare is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
- #
- ## WORK IN PROGRESS
- import json
- import mysql.connector
- import time
- import datetime
- import copy
- import hashlib
- import sys
- import getopt
- POPUFARE_API_VERSION = "2.0.0"
- #conn = mysql.connector.connect(user='bus', password='bus', host='localhost', database='busdb', port=3306)
- _USER = 'busapi'
- _PASSWORD = 'bus'
- _HOST = 'localhost'
- _DATABASE = 'busdb'
- _PORT = 5506
- Function = [
- "User",
- "Card",
- "Pass",
- "Log",
- "PricePoints",
- "AdminGetCard", "AdminGetCards", "AdminGetPass", "AdminGetUser",
- "AdminGetAdmin", "AdminGetPassesOnCard", "AdminGetPendingQueue", "AdminProcessPendingQueue",
- "AdminRemovePendingQueue", "AdminCreateCardBlock", "AdminCreateCard", "AdminSetUser",
- "AdminSetAdmin", "AdminAddPass", "AdminAddCard", "AdminAddUser",
- "AdminAddAdmin", "AdminRemovePass", "AdminRemovePasses", "AdminRemoveCard",
- "AdminRemoveUser", "AdminRemoveAdmin", "AdminTransferCard", "AdminTransferPass",
- "AdminGetPassOptions", "AdminAddCardToUser", "AdminRemoveCardFromUser", "AdminGetAdminPermissions",
- "AdminAddAdminPermissions", "AdminRemoveAdminPermissions", "AdminAddAdminApiPermissions", "AdminRemoveAdminApiPermissions",
- "AdminSetAdminApiPermissions", "AdminGetCustomCard", "AdminGetAdmins", "AdminSearchCards",
- "AdminSearchUsers", "AdminSearchAdmins"]
- PASS_FIELDS = ["logical_card_id", "issued", "activated", "deactivated", "firstused", "lastused",
- "nrides_orig", "nrides_remain", "nday_orig", "nday_expiration",
- "active", "expired", "queue_order",
- "rule", "comment", "paytype" ]
- CARD_FIELDS = ["mag_token", "rfid_token", "comment", "userid", "issued", "deactivated", "lastused",
- "firstused", "group_id", "issuetype"]
- USER_FIELDS = ["username", "comment", "first_name", "last_name", "phone",
- "email", "address", "city", "state", "zip", "passwordhash",
- "shipping_address", "shipping_city", "shipping_state", "shipping_zip",
- "shipping_name", "shipping_country_code", "shipping_country_name"]
- GROUP_FIELDS = ["id", "group_id", "group_name"]
- RULECLASS_FIELDS = ["id", "group_id", "group_name"]
- def Request(ctx, db_info = { "user":_USER, "pass":_PASSWORD, "host":_HOST, "db":_DATABASE, "port":_PORT}):
- #_conn = mysql.connector.connect(user=_USER, password=_PASSWORD, host=_HOST, database=_DATABASE, port=_PORT)
- _conn = mysql.connector.connect(user=db_info["user"], password=db_info["pass"], host=db_info["host"], database=db_info["db"], port=db_info["port"])
- res = {}
- if "function" in ctx:
- if ctx["function"] == "CardInfo":
- res = CardInfo(_conn, ctx)
- elif ctx["function"] == "UserInfo":
- res = UserInfo(_conn, ctx)
- elif ctx["function"] == "User":
- res = User(_conn, ctx)
- elif ctx["function"] == "Card":
- res = Card(_conn, ctx)
- elif ctx["function"] == "Pass":
- res = Pass(_conn, ctx)
- elif ctx["function"] == "Group":
- res = Group(_conn, ctx)
- elif ctx["function"] == "Ruleclass":
- res = Ruleclass(_conn, ctx)
- elif ctx["function"] == "RecycleCard":
- res = RecycleCard(_conn, ctx)
- elif ctx["function"] == "AddCardBlock":
- res = AddCardBlock(_conn, ctx)
- elif ctx["function"] == "Search":
- res = Search(_conn, ctx)
- elif ctx["function"] == "Pending":
- res = Pending(_conn, ctx)
- elif ctx["function"] == "ping":
- res["result"] = "success"
- res["data"] = "pong"
- _conn.close()
- return res
- ## _ _ __
- ## ___ __ _ _ __ __| (_)_ __ / _| ___
- ## / __/ _` | '__/ _` | | '_ \| |_ / _ \
- ## | (_| (_| | | | (_| | | | | | _| (_) |
- ## \___\__,_|_| \__,_|_|_| |_|_| \___/
- ##
- def CardInfo(db, ctx):
- card_res = {}
- action = "get"
- if "action" in ctx:
- action = ctx["action"]
- if action == "get":
- print("CardInfo:", ctx)
- cardid = -1
- if "logical_card_id" in ctx:
- cardid = ctx["logical_card_id"]
- card_res["logical_card_id"] = cardid
- card_res = Card(db, {"action":"get", "logical_card_id": cardid})
- card_res["pass"] = []
- if card_res["result"] == "success":
- ## through each of the passes on the card
- ##
- pass_query = "select user_pass_id from user_pass where logical_card_id = %s and expired = 0 order by queue_order asc"
- pass_cursor = db.cursor()
- pass_cursor.execute(pass_query, [card_res["logical_card_id"]])
- pass_rows = pass_cursor.fetchall()
- for pass_row in pass_rows:
- pass_res = Pass(db, {"action":"get", "user_pass_id":pass_row[0]})
- card_res["pass"].append(pass_res)
- card_res["user"] = {}
- if ((card_res["userid"] is not None) and (int(card_res["userid"]) >= 0)):
- card_res["user"] = User(db, {"action":"get", "userid": card_res["userid"] })
- elif action == "search":
- card_res["cards"] = []
- res_cardid = Card(db, ctx)
- for cid in res_cardid["logical_card_ids"]:
- _c = CardInfo(db, {"action":"get", "logical_card_id":cid})
- card_res["cards"].append(_c)
- card_res["result"] = "success"
- return card_res
- ## _ __
- ## _ _ ___ ___ _ __(_)_ __ / _| ___
- ## | | | / __|/ _ \ '__| | '_ \| |_ / _ \
- ## | |_| \__ \ __/ | | | | | | _| (_) |
- ## \__,_|___/\___|_| |_|_| |_|_| \___/
- ##
- def UserInfo(db, ctx):
- res = {}
- res["result"] = "fail"
- userid = -1
- if ("userid" in ctx):
- userid = ctx["userid"]
- pass_fields = PASS_FIELDS.copy()
- card_fields = CARD_FIELDS.copy()
- user_fields = USER_FIELDS.copy()
- res["userid"] = userid
- cursor = db.cursor()
- ## fill in user data
- ##
- res["user"] = {}
- fields = USER_FIELDS.copy()
- query = "select " + ",".join(fields) + " from users where userid = %s"
- cursor.execute(query, [userid])
- row = cursor.fetchone()
- if row is None:
- res["api_comment"] = "user not found"
- return res
- res["user"]["userid"] = userid
- for idx,f in enumerate(user_fields):
- res["user"][f] = row[idx]
- ## go through each card and fill in card data and pass data
- ##
- res["card"] = []
- query = "select logical_card_id from user_card where userid = %s and active = 1 order by logical_card_id asc"
- card_cursor = db.cursor()
- card_cursor.execute(query, [userid])
- rows = card_cursor.fetchall()
- for row in rows:
- card_res = CardInfo(db, {"logical_card_id":row[0]})
- res["card"].append(card_res)
- res["result"] = "success"
- return res
- def _update_pass_bits(cursor, passid):
- q = "select logical_card_id from user_pass where user_pass_id = %s"
- cursor.execute(q, [passid])
- rows = cursor.fetchall()
- print("\n\nupdating pass bits", passid, "\n\n")
- cardid = -1
- for row in rows:
- cardid = row[0]
- break
- print("\n\nupdating pass bits cardid:", cardid, "\n\n")
- if cardid < 0: return
- q = "update user_pass set active = 0 where logical_card_id = %s"
- cursor.execute(q, [cardid])
- q = "update user_pass set active = 1 where logical_card_id = %s and expired = 0 and queue_order = " + \
- "( select min(x.queue_order) from user_pass x where x.logical_card_id = %s and x.expired = 0 )"
- cursor.execute(q, [cardid,cardid])
- ## _ _
- ## _ __ _ _| | ___ ___| | __ _ ___ ___
- ## | '__| | | | |/ _ \/ __| |/ _` / __/ __|
- ## | | | |_| | | __/ (__| | (_| \__ \__ \
- ## |_| \__,_|_|\___|\___|_|\__,_|___/___/
- ##
- def Ruleclass(db, ctx):
- res = {}
- ruleclass_fields = RULECLASS_FIELDS.copy()
- cursor = db.cursor()
- fields = ruleclass_fields.copy()
- field_vals = []
- if ctx["action"] == "search":
- query = "select id, rulename, ruleclass from rule_class"
- cursor.execute(query)
- rows = cursor.fetchall()
- res["ruleclass"] = []
- for row in rows:
- res["ruleclass"].append({"id":row[0], "rulename":row[1], "ruleclass":row[2]})
- db.commit()
- return res
- ##
- ## _ __ __ _ ___ ___
- ## | '_ \ / _` / __/ __|
- ## | |_) | (_| \__ \__ \
- ## | .__/ \__,_|___/___/
- ## |_|
- def Pass(db, ctx):
- res = {}
- passid = -1
- if ("user_pass_id" in ctx):
- passid = ctx["user_pass_id"]
- pass_fields = PASS_FIELDS.copy()
- cursor = db.cursor()
- fields = pass_fields.copy()
- field_vals = []
- if (ctx["action"] == "get"):
- query = "select " + ",".join(pass_fields) + " from user_pass where user_pass_id = %s"
- cursor.execute(query, [passid])
- row = cursor.fetchone()
- if row is not None:
- res["result"] = "success"
- res["user_pass_id"] = passid
- for idx,f in enumerate(pass_fields):
- if isinstance(row[idx], datetime.datetime):
- res[f] = row[idx].strftime("%Y-%m-%d %H:%M:%S")
- else:
- res[f] = row[idx]
- else:
- res["result"] = "fail"
- res["api_comment"] = "pass not found"
- elif (ctx["action"] == "add"):
- if (not "logical_card_id" in ctx) or (ctx["logical_card_id"] == ''):
- res["result"] = "fail"
- res["api_comment"] = "must have logical_card_id to add pass"
- else:
- ## fill in some default values
- ##
- dt = time.strftime('%Y-%m-%d %H:%M:%S')
- if "issued" not in ctx: ctx["issued"] = dt
- if "expired" not in ctx: ctx["expired"] = 0
- if "active" not in ctx: ctx["active"] = 0
- if "logical_card_id" in ctx:
- cardid = ctx["logical_card_id"]
- _q = "select queue_order from user_pass where logical_card_id = %s and expired = 0 order by queue_order desc limit 1"
- _c = db.cursor()
- _c.execute(_q, [cardid])
- _r = _c.fetchone()
- if _r is not None:
- ctx["queue_order"] = int(_r[0])+1
- else:
- ctx["active"] = 1
- ctx["queue_order"] = 0
- else:
- ctx["queue_order"] = 0
- for f in pass_fields:
- if f in ctx: field_vals.append(ctx[f])
- else: field_vals.append(None)
- query = "insert into user_pass (" + ",".join(fields) + ") values (" + ",".join(["%s"]*len(fields)) + ")"
- print(query)
- print(fields, field_vals)
- cursor.execute(query, field_vals)
- res["user_pass_id"] = cursor.lastrowid
- res["result"] = "success"
- _update_pass_bits(cursor, passid);
- elif (ctx["action"] == "update"):
- update_field = []
- update_val = []
- for f in pass_fields:
- if f in ctx:
- update_field.append(f + "= %s")
- update_val.append(ctx[f])
- update_val.append(passid)
- query = "update user_pass set " + ",".join(update_field) + " where user_pass_id = %s"
- cursor.execute(query, update_val)
- res["user_pass_id"] = passid
- res["result"] = "success"
- _update_pass_bits(cursor, passid);
- elif (ctx["action"] == "deactivate"):
- update_field = []
- update_val = []
- for f in pass_fields:
- if f in ctx:
- update_field.append(f + "= %s")
- update_val.append(ctx[f])
- update_val.append(passid)
- query = "update user_pass set active = 0, expired = 1 where user_pass_id = %s"
- cursor.execute(query, [passid])
- _update_pass_bits(cursor, passid);
- res["user_pass_id"] = passid
- res["result"] = "success"
- elif (ctx["action"] == "delete"):
- query = "delete from user_pass where user_pass_id = %s"
- cursor.execute(query, [passid])
- _update_pass_bits(cursor, passid);
- res["result"] = "success"
- db.commit()
- return res
- ## _
- ## ___ __ _ _ __ __| |
- ## / __/ _` | '__/ _` |
- ## | (_| (_| | | | (_| |
- ## \___\__,_|_| \__,_|
- ##
- def Card(db, ctx):
- card_fields = CARD_FIELDS.copy()
- res = {}
- cardid = -1
- if ("logical_card_id" in ctx):
- cardid = ctx["logical_card_id"]
- cursor = db.cursor()
- fields = card_fields.copy()
- field_vals = []
- if (ctx["action"] == "get"):
- query = "select " + ",".join(card_fields) + " from user_card where logical_card_id = %s"
- cursor.execute(query, [cardid])
- row = cursor.fetchone()
- if row is not None:
- res["logical_card_id"] = cardid
- for idx,f in enumerate(card_fields):
- if isinstance(row[idx], datetime.datetime):
- res[f] = row[idx].strftime("%Y-%m-%d %H:%M:%S")
- else:
- res[f] = row[idx]
- res["result"] = "success"
- else:
- res["result"] = "fail"
- res["api_comment"] = "card not found"
- elif (ctx["action"] == "add"):
- fields.append("active")
- for f in card_fields:
- if f in ctx: field_vals.append(ctx[f])
- else: field_vals.append(None)
- field_vals.append(1)
- query = "insert into user_card (" + ",".join(fields) + ") values (" + ",".join(["%s"]*len(fields)) + ")"
- cursor.execute(query, field_vals)
- res["logical_card_id"] = cursor.lastrowid
- res["result"] = "success"
- elif (ctx["action"] == "update"):
- if not "logical_card_id" in ctx:
- res["result"] = "fail"
- res["api_comment"] = "must supply a logical_card_id"
- else:
- update_field = []
- update_val = []
- query_card_id = ctx["logical_card_id"]
- cursor.execute("select logical_card_id from user_card where logical_card_id = %s", [query_card_id])
- rows = cursor.fetchall()
- if len(rows) == 0:
- res["result"] = "fail"
- res["api_comment"] = "card not found"
- else:
- print(">>>>", len(rows))
- for row in rows:
- logical_card_id = row[0]
- for f in card_fields:
- if f in ctx:
- update_field.append(f + "= %s")
- update_val.append(ctx[f])
- update_val.append(cardid)
- query = "update user_card set " + ",".join(update_field) + " where logical_card_id = %s"
- cursor.execute(query, update_val)
- res["logical_card_id"] = cardid
- res["result"] = "success"
- elif (ctx["action"] == "delete"):
- query = "delete from user_card where logical_card_id = %s"
- cursor.execute(query, [cardid])
- res["result"] = "success"
- elif (ctx["action"] == "search"):
- query = "select logical_card_id from user_card where "
- n_search = 0
- if "logical_card_id" in ctx:
- query += " logical_card_id = %s"
- field_vals.append( ctx["logical_card_id"])
- n_search += 1
- if "mag_token" in ctx:
- query += " mag_token like %s "
- field_vals.append( '%' + ctx["mag_token"] + '%')
- n_search += 1
- if "rfid_token" in ctx:
- if len(field_vals)>0: query += " and "
- query += " rfid_token like %s "
- field_vals.append( '%' + ctx["rfid_token"] + '%')
- n_search += 1
- query_limit = " "
- if "limit" in ctx:
- query_limit = " limit %s "
- search_vals.append(ctx["limit"])
- query += query_limit
- res["logical_card_ids"] = []
- if n_search > 0:
- cursor.execute(query, field_vals)
- rows = cursor.fetchall()
- for row in rows:
- res["logical_card_ids"].append(row[0])
- res["result"] = "success"
- db.commit()
- return res
- ##
- ## __ _ _ __ ___ _ _ _ __
- ## / _` | '__/ _ \| | | | '_ \
- ## | (_| | | | (_) | |_| | |_) |
- ## \__, |_| \___/ \__,_| .__/
- ## |___/ |_|
- def Group(db,ctx):
- group_res = { "result":"fail"}
- action = "get"
- if "action" in ctx:
- action = ctx["action"]
- cursor = db.cursor()
- if action == "get":
- group_res["group"] = []
- query = "select group_id, group_name from groups order by group_id asc"
- cursor.execute(query)
- rows = cursor.fetchall()
- for row in rows:
- group_res["group"].append({"group_id":row[0], "group_name":row[1]})
- group_res["result"] = "success"
- elif action == "add":
- if "group_name" not in ctx:
- group_res["result"] = "fail"
- group_res["api_comment"] = "must provide group name to add"
- return res
- group_name = ctx["group_name"]
- group_id = -1
- cursor.execute("select max(group_id) from groups")
- x = cursor.fetchone()
- if x[0] is None:
- group_id = 1
- else:
- group_id = int(x[0]) + 1
- cursor.execute("insert into groups (group_id, group_name) values (%s, %s)", [group_id, group_name])
- group_res["result"] = "success"
- group_res["group_id"] = group_id
- group_res["group_name"] = group_name
- elif action == "getone":
- group_res["group"] = []
- query = "select group_id, group_name from groups where group_name = %s "
- cursor.execute(query, [ctx["group"]])
- row = cursor.fetchone()
- if not row:
- group_res["result"] = "fail"
- group_res["api_comment"] = "invalid group"
- else:
- group_res["result"] = "success"
- group_res["group_id"] = row[0]
- elif action == "default":
- return Group(db, {"action":"getone", "group":"TEST-ORG"})
- db.commit()
- return group_res
- ##
- ## _ _ ___ ___ _ __
- ## | | | / __|/ _ \ '__|
- ## | |_| \__ \ __/ |
- ## \__,_|___/\___|_|
- ##
- def User(db, ctx):
- user_fields = USER_FIELDS.copy()
- res = {}
- cursor = db.cursor()
- fields = user_fields.copy()
- user_vals = []
- userid = -1
- if "userid" in ctx: userid = ctx["userid"]
- print("cp.user")
- ## USER GET
- ##
-
- if (ctx["action"] == "get"):
- query = "select " + ",".join(user_fields) + " from users where userid = %s"
- cursor.execute(query, [userid])
- row = cursor.fetchone()
- if row is not None:
- res["userid"] = userid
- for idx,f in enumerate(user_fields):
- if isinstance(row[idx], datetime.datetime):
- res[f] = row[idx].strftime("%Y-%m-%d %H:%M:%S")
- else:
- res[f] = row[idx]
- res["result"] = "success"
- else:
- res["result"] = "fail"
- res["api_comment"] = "user not found"
- ## USER ADD
- ##
- elif (ctx["action"] == "add"):
- if ((not "password" in ctx) or
- (not "username" in ctx) ):
- res["api_comment"] = "invalid parameters, need username and password to create account"
- res["result"] = "fail"
- else:
- uname = ctx["username"]
- pword = ctx["password"]
- fields.append("active")
- fields.append("created")
- for f in user_fields:
- if f in ctx: user_vals.append(ctx[f])
- elif f == "passwordhash":
- ha = hashlib.sha256()
- ha.update(str.encode(uname))
- ha.update(str.encode(pword))
- user_vals.append(ha.hexdigest())
- else: user_vals.append(None)
- user_vals.append(1)
- user_vals.append(time.strftime('%Y-%m-%d %H:%M:%S'))
- query = "insert into users (" + ",".join(fields) + ") values (" + ",".join(["%s"]*len(fields)) + ")"
- cursor.execute(query, user_vals)
- res["userid"] = cursor.lastrowid
- res["result"] = "success"
- ## USER UPDATE
- ##
- elif (ctx["action"] == "update"):
- if not "userid" in ctx:
- res["result"] = "fail"
- res["api_comment"] = "no userid specified"
- else:
- uname = ''
- query = "select username from users where userid = %s";
- cursor.execute(query, [userid])
- rows = cursor.fetchall()
- for row in rows:
- uname = row[0]
- if uname == '':
- res["result"] = "fail"
- res["api_comment"] = "could not find username"
- else:
- update_field = []
- update_val = []
- print("user_field:", user_fields)
- print("ctx:", ctx)
- for f in user_fields:
- if (f == "passwordhash") and ("password" in ctx):
- update_field.append(" passwordhash = %s ")
- ha = hashlib.sha256()
- ha.update(str.encode(uname))
- ha.update(str.encode(ctx["password"]))
- update_val.append(ha.hexdigest())
- elif f in ctx:
- update_field.append(f + "= %s")
- update_val.append(ctx[f])
- else:
- pass
- #update_val.append(None)
- update_val.append(userid)
- if len(update_field) == 0:
- print("NOPE")
- print("manage_user.update>>>", userid, ":".join(update_field), ":".join(update_val), len(update_field))
- query = "update users set " + ",".join(update_field) + " where userid = %s"
- print("WTFFF???", query)
- cursor.execute(query, update_val)
- res["userid"] = userid
- res["result"] = "success"
- ## USER DELETE
- ##
- elif (ctx["action"] == "delete"):
- query = "delete from users where userid = %s"
- cursor.execute(query, [userid])
- ## USER SEARCH
- ##
- elif (ctx["action"] == "search"):
- res["userids"] = []
- res["userid"] = userid
- res["result"] = "success"
- search_field = []
- search_val = []
- for f in user_fields:
- if f in ctx:
- search_field.append(f + " like %s")
- search_val.append('%' + ctx[f] + '%')
- query_limit = " "
- if "limit" in ctx:
- query_limit = " limit %s "
- search_val.append(ctx["limit"])
- query = "select userid from users where " + " and ".join(search_field) + query_limit
- cursor.execute(query, search_val)
- rows = cursor.fetchall()
- for row in rows:
- res["userids"].append(row[0])
- db.commit()
- return res
- ## _ _
- ## _ __ ___ ___ _ _ ___| | ___ ___ __ _ _ __ __| |
- ## | '__/ _ \/ __| | | |/ __| |/ _ \ / __/ _` | '__/ _` |
- ## | | | __/ (__| |_| | (__| | __/ | (_| (_| | | | (_| |
- ## |_| \___|\___|\__, |\___|_|\___| \___\__,_|_| \__,_|
- ## |___/
- def RecycleCard(db, ctx):
- res = {"result":"fail"}
- cursor = db.cursor()
- fields = ["logical_card_id", "rfid_token", "mag_token", "group",
- "userid",
- "rule", "pass_class", "nrides_remain", "nrides_orig", "nday_orig" ]
- val = {}
- for f in fields:
- if f in ctx:
- if ctx[f] and len(ctx[f]) > 0:
- val[f] = ctx[f]
- if ((not ("logical_card_id" in val)) and
- (not ("rfid_token" in val)) and
- (not ("mag_token" in val))):
- return res
- logical_card_id = -1
- if not ("logical_card_id" in val):
- if "mag_token" in val:
- query = "select logical_card_id from user_card where mag_token = %s and active = 1"
- cursor.execute(query, [val["mag_token"]])
- cid = cursor.fetchone()
- if cid is not None:
- val["logical_card_id"] = cid[0]
- else:
- return res
- elif "rfid_token" in val:
- query = "select logical_card_id from user_card where rfid_token = %s and active = 1"
- cursor.execute(query, [val["rfid_token"]])
- cid = cursor.fetchone()
- if cid is not None:
- val["logical_card_id"] = cid[0]
- else:
- return res
- group_info = Group(db, {"action":"default"})
- if "group" in val:
- group_info = Group(db, {"action":"getone", "group":val["group"]})
- if group_info["result"] != "success":
- res["api_comment"] = "invalid group"
- return res
- query = "update user_card set active = 0 where logical_card_id = %s"
- cursor.execute(query, [val["logical_card_id"]])
- card_info = {"action":"add", "group_id":group_info["group_id"], "active":1}
- if "mag_token" in val: card_info["mag_token"] = val["mag_token"]
- if "rfid_token" in val: card_info["rfid_token"] = val["rfid_token"]
- card_res = Card(db, card_info)
- if card_res["result"] != "success":
- res["result"] = "fail"
- res["api_comment"] = "failed to find card"
- return res
- res["logical_card_id"] = card_res["logical_card_id"]
- if "pass_class" in val:
- pass_opt = {"action":"add", "logical_card_id": res["logical_card_id"] }
- if val["pass_class"] == "OTHER":
- pass_opt["rule"] = val["rule"]
- Pass(db, pass_opt)
- elif val["pass_class"] == "NRIDE":
- pass_opt["rule"] = val["rule"]
- pass_opt["nrides_orig"] = val["nrides_orig"]
- pass_opt["nrides_remain"] = val["nrides_remain"]
- Pass(db, pass_opt)
- elif val["pass_class"] == "NDAY":
- pass_opt["rule"] = val["rule"]
- pass_opt["nday_orig"] = val["nday_orig"]
- Pass(db, pass_opt)
-
- return res
- ## _
- ## ___ ___ __ _ _ __ ___| |__
- ## / __|/ _ \/ _` | '__/ __| '_ \
- ## \__ \ __/ (_| | | | (__| | | |
- ## |___/\___|\__,_|_| \___|_| |_|
- ##
- def Search(db, ctx):
- res = {"result":"fail"}
- cursor = db.cursor()
- fields = ["search_type", "search_string", "start", "count"]
- start = "0"
- count = "100"
- val = {}
- for f in fields:
- if f in ctx:
- if ctx[f] and len(ctx[f]) > 0:
- val[f] = ctx[f]
- if "start" in val: start = val["start"]
- if "count" in val: count = val["count"]
- if val["search_type"] == "card":
- t = val["search_string"]
- p = '%' + t + '%'
- query = "select logical_card_id, mag_token, rfid_token, userid, issued, firstused, lastused, group_id, issuetype"
- query += " from user_card where mag_token like %s "
- query += " or rfid_token like %s "
- query += " or comment like %s "
- query += " or issuetype like %s "
- query += " and active = 1 "
- query += " order by logical_card_id desc"
- query += " limit %s,%s "
- _v = [p,p, p, p, int(start), int(start) + int(count)]
- #cursor.execute(query, [p, p, p, p])
- cursor.execute(query, _v)
- rows = cursor.fetchall()
- res["data"] = []
- for row in rows:
- _d = {
- "iscard": 1,
- "logical_card_id": row[0],
- "mag_token": row[1],
- "rfid_token": row[2],
- "userid": row[3],
- "issued": row[4],
- "firstused": row[5],
- "lastused": row[6],
- "group_id": row[7],
- "issuetype": row[8]
- }
- res["data"].append( _d )
- res["result"] = "success"
- elif val["search_type"] == "user":
- t = val["search_string"]
- p = '%' + t + '%'
- fields = [ "username", "first_name", "last_name", "phone", "email", "address", "city","state", "zip", "created",
- "shipping_address", "shipping_city", "shipping_state", "shipping_zip", "shipping_name",
- "shipping_country_code", "shipping_country_name" ]
- query = "select userid, " + ", ".join(fields)
- query += " from users "
- query += " where " + " like %s or ".join(fields) + " like %s "
- query += " and active = 1 "
- query += " order by userid desc"
- query += " limit %s,%s "
- print("user query:", query)
- _v = [p]*len(fields)
- _v.append(int(start))
- _v.append(int(start) + int(count))
- #cursor.execute(query, [p]*len(fields))
- cursor.execute(query, _v)
- rows = cursor.fetchall()
- res["data"] = []
- for row in rows:
- _d = { "userid": row[0], "isuser": 1 }
- for idx,f in enumerate(fields):
- _d[f] = row[idx+1]
- res["data"].append( _d )
- res["result"] = "success"
- elif val["search_type"] == "admin":
- t = val["search_string"]
- p = '%' + t + '%'
- fields = [ "username", "comment" ]
- query = "select userid, group_id, " + ", ".join(fields)
- query += " from admins "
- query += " where " + " like %s or ".join(fields) + " like %s "
- query += " and active = 1 "
- query += " order by userid desc"
- query += " limit %s,%s "
- print("user query:", query)
- _v = [p]*len(fields)
- _v.append(int(start))
- _v.append(int(start) + int(count))
- cursor.execute(query, _v)
- rows = cursor.fetchall()
- res["data"] = []
- for row in rows:
- _d = { "userid": row[0], "group_id": row[1], "isadmin": 1 }
- for idx,f in enumerate(fields):
- _d[f] = row[idx+2]
- res["data"].append( _d )
- res["result"] = "success"
- return res
- ## _ _ _ _ _ _
- ## __ _ __| | __| | ___ __ _ _ __ __| | | |__ | | ___ ___| | __
- ## / _` |/ _` |/ _` | / __/ _` | '__/ _` | | '_ \| |/ _ \ / __| |/ /
- ## | (_| | (_| | (_| | | (_| (_| | | | (_| | | |_) | | (_) | (__| <
- ## \__,_|\__,_|\__,_| \___\__,_|_| \__,_| |_.__/|_|\___/ \___|_|\_\
- ##
- def AddCardBlock(db, ctx):
- res = {"result":"fail"}
- cursor = db.cursor()
- fields = ["mag_token", "rfid_token", "group_id",
- "rule", "nday_orig", "nrides_remain", "nrides_orig",
- "count",
- "pass_rule", "pass_nrides_remain", "pass_nrides_orig",
- "pass_nday_orig", "pass_class"]
- val = {}
- for f in fields:
- if f in ctx:
- if ctx[f] and len(ctx[f]) > 0:
- val[f] = ctx[f]
- if not ("count" in val):
- res["result"] = "fail"
- res["api_comment"] = "count must be positive"
- return res
- if ((not ("mag_token" in val)) and
- (not ("rfid_token" in val))):
- res["result"] = "fail"
- res["api_comment"] = "mag_token and/or rfid_token must be specified"
- return res
- use_mag = False
- use_rfid = False
- if "mag_token" in val:
- use_mag = True
- pfx_mag_cred = val["mag_token"].split(":")[0]
- base_mag_cred = int(val["mag_token"].split(":")[-1])
- if "rfid_token" in val:
- use_rfid = True
- pfx_rfid_cred = ":".join(val["rfid_token"].split(":")[0:2])
- base_rfid_cred = int(val["rfid_token"].split(":")[-1])
- logical_card_ids = []
- for idx in range(int(val["count"])):
- card_info = {"action":"add", "group_id":val["group_id"], "active":1}
- if "mag_token" in val: card_info["mag_token"] = val["mag_token"]
- if "rfid_token" in val: card_info["rfid_token"] = val["rfid_token"]
- if use_mag:
- card_info["mag_token"] = pfx_mag_cred + ":" + str(base_mag_cred + idx)
- if use_rfid:
- card_info["rfid_token"] = pfx_rfid_cred + ":" + str(base_rfid_cred + idx)
- card_res = Card(db, card_info)
- if card_res["result"] != "success":
- res["result"] = "fail"
- res["api_comment"] = "failed to add card"
- return res
- logical_card_id = card_res["logical_card_id"]
-
- if "pass_rule" in val:
- pass_info = {"action":"add", "logical_card_id":logical_card_id, "active":1,
- "rule" : val["pass_rule"] }
- if val["pass_class"] == "OTHER":
- pass
- elif val["pass_class"] == "NRIDE":
- pass_info["nrides_remain"] = val["pass_nrides_remain"]
- pass_info["nrides_orig"] = val["pass_nrides_orig"]
- elif val["pass_class"] == "NDAY":
- pass_info["nday_orig"] = val["pass_nday_orig"]
- pass_res = Pass(db, pass_info)
- logical_card_ids.append(logical_card_id)
- res["result"] = "success"
- res["logical_card_ids"] = logical_card_ids
- return res
- ## ____ _ _
- ## | _ \ ___ _ __ __| (_)_ __ __ _
- ## | |_) / _ \ '_ \ / _` | | '_ \ / _` |
- ## | __/ __/ | | | (_| | | | | | (_| |
- ## |_| \___|_| |_|\__,_|_|_| |_|\__, |
- ## |___/
- def Pending(db, ctx):
- res = {"result":"fail"}
- cursor = db.cursor()
- fields = ["org_card_order_queue_id", "userid", "logical_card_id", "created", "processed", "comment" ]
- val = {}
- for f in fields:
- if f in ctx:
- if (type(ctx[f]) == int) or (ctx[f] and ((type(ctx[f]) != int) and (len(ctx[f]) > 0))):
- val[f] = ctx[f]
- if not "comment" in val:
- val["comment"] = ''
- if (ctx["action"] == "getall"):
- query = "select org_card_order_queue_id, userid, logical_card_id, "
- query += " date_format(created, '%Y-%m-%d %H:%i:%S'), "
- query += " date_format(processed,'%Y-%m-%d %H:%i:%S'), comment, pending "
- query += " from org_card_order_queue "
- query += " where pending = 1 "
- query += " order by org_card_order_queue_id asc"
- cursor.execute(query)
- rows = cursor.fetchall()
- res["data"] = []
- for row in rows:
- _c = Card(db, {"action":"get", "logical_card_id":row[2]})
- mag_token = ""
- if "mag_token" in _c: mag_token = _c["mag_token"]
- rfid_token = ""
- if "rfid_token" in _c: rfid_token = _c["rfid_token"]
- _r = {"org_card_order_queue_id":row[0], "userid":row[1], "logical_card_id":row[2], "created": row[3],
- "processed":row[4], "comment":row[5], "pending":row[6],
- "mag_token":mag_token, "rfid_token":rfid_token}
- res["data"].append(_r)
- res["result"] = "success"
- if (ctx["action"] == "get"):
- query = "select org_card_order_queue_id, userid, logical_card_id, "
- query += " date_format(created, '%Y-%m-%d %H:%i:%S'), "
- query += " date_format(processed,'%Y-%m-%d %H:%i:%S'), comment, pending "
- query += " from org_card_order_queue "
- query += " where pending = 1 and org_card_order_queue_id = %s"
- cursor.execute(query, [val["org_card_order_queue_id"]])
- row = cursor.fetchone()
- if row is None:
- res["api_comment"] = "pending card not found"
- return res
- cols = ["org_card_order_queue_id", "userid", "logical_card_id", "created", "processed", "comment", "pending" ]
- res["pending_card"] = {}
- for idx,f in enumerate(cols):
- res["pending_card"][f] = row[idx]
- cid = res["pending_card"]["logical_card_id"]
- _r = CardInfo(db, {"action":"get", "logical_card_id":cid})
- if _r["result"] == "fail":
- return _r
- res["cardinfo"] = _r
- res["result"] = "success"
- elif (ctx["action"] == "add"):
- query = "insert into org_card_order_queue (userid, logical_card_id, comment, pending, created) values (%s,%s,%s,1,now())"
- cursor.execute(query, [val["userid"], val["logical_card_id"], val["comment"]])
- res["org_card_order_queue_id"] = cursor.lastrowid
- res["result"] = "success"
- elif (ctx["action"] == "process"):
- query = "update org_card_order_queue set pending = 0, processed = now() where org_card_order_queue_id = %s"
- cursor.execute(query, [val["org_card_order_queue_id"]])
- res["result"] = "success"
- db.commit()
- return res
- ## _
- ## _ __ ___ __ _(_)_ __
- ## | '_ ` _ \ / _` | | '_ \
- ## | | | | | | (_| | | | | |
- ## |_| |_| |_|\__,_|_|_| |_|
- ##
- def __test(db):
- print("main")
- print("---------")
- print("---------")
- print("---------")
- res = User(db, {"action":"add", "username":"abe" })
- print("user.add:", res)
- res = User(db, {"action":"update", "username":"abeabe", "userid":res["userid"]})
- print("user.update:", res)
- res = User(db, {"action":"get", "userid":res["userid"]})
- print("user.get:", res)
- res = User(db, {"action":"delete", "userid": res["userid"]})
- print("user.delete:", res)
-
- print("---------")
- print("---------")
- print("---------")
- res = Card(db, {"action":"get", "logical_card_id":1})
- print("card.get:", res)
- res = Card(db, {"action":"add", "mag_token":"2:1234", "rfid_token":"26:20:415", "comment":"testing api", "userid":1})
- print("card.add:", res)
- res = Card(db, {"action":"update", "mag_token":"2:9234", "logical_card_id":res["logical_card_id"]})
- print("card.update:", res)
- res = Card(db, {"action":"delete", "logical_card_id":res["logical_card_id"]})
- print("card.delete:", res)
- print("---------")
- print("---------")
- print("---------")
- res = Pass(db, {"action":"get", "user_pass_id":11})
- print("pass.get:", res)
- res = Pass(db, {"action":"add", "logical_card_id":1, "queue_order":9, "rule":"TEST-ORG-NDAY", "nday_orig":3})
- print("pass.add:", res)
- res = Pass(db, {"action":"update", "user_pass_id":res["user_pass_id"], "queue_order":10, "rule":"TEST-ORG-NDAY", "nday_orig":5})
- print("pass.update:", res)
- res = Pass(db, {"action":"delete", "user_pass_id":res["user_pass_id"]})
- print("pass.delete:", res)
- print("---------")
- print("---------")
- print("---------")
- res = UserInfo(db, {"userid":348})
- print("userinfo:", json.dumps(res, indent=2))
- print("---------")
- print("---------")
- print("---------")
- res = Request({"function":"CardInfo", "action":"search", "logical_card_id":1})
- print("request.card.search:", res)
- def show_version(ofp):
- ofp.write("PopufareAPI version " + POPUFARE_API_VERSION + "\n")
- ofp.flush()
- def show_help(ofp):
- show_version(ofp)
- ofp.write("\nusage:\n")
- ofp.write("\n")
- ofp.write(" PopufareAPI [-h] [-v] [-c config] [-u dbuser] [-p dbpass] [-H dbhost] [-D db] [-P dbport] <json_data>\n")
- ofp.write("\n")
- ofp.write(" -c config file\n")
- ofp.write(" -u db user\n")
- ofp.write(" -p db pass\n")
- ofp.write(" -H db host\n")
- ofp.write(" -D db name\n")
- ofp.write(" -P db port\n")
- ofp.write(" -h help (this screen)\n")
- ofp.write(" -v show version\n")
- ofp.write("\n")
- ofp.write("example:\n")
- ofp.write("\n")
- ofp.write(" PopufareAPI -d '{\"function\":\"ping\"}\n")
- ofp.write("\n")
- ofp.flush()
- if __name__ == "__main__":
- api_opt = {
- "db_info": {
- "user":"busapi",
- "pass":"bus",
- "host":"localhost",
- "db":"busdb",
- "port":5506
- },
- "config":"",
- "data":""
- }
- data = {}
- opts,args = getopt.getopt(sys.argv[1:], "hd:u:p:H:D:P:c:")
- for o,a in opts:
- if o == "-h":
- show_help(sys.stdout)
- sys.exit(0)
- elif o == "-c":
- api_opt["config"] = a
- elif o == "-u":
- api_opt["db_info"]["user"] = a
- elif o == "-p":
- api_opt["db_info"]["pass"] = a
- elif o == "-H":
- api_opt["db_info"]["host"] = a
- elif o == "-D":
- api_opt["db_info"]["db"] = a
- elif o == "-P":
- api_opt["db_info"]["port"] = int(a)
- #elif o == "-d":
- # api_opt["data"] = json.loads(a)
- else:
- show_help(sys.stderr)
- sys.exit(-1)
- if len(args) < 1:
- sys.stderr.write("no data request\n")
- show_help(sys.stderr)
- sys.exit(-1)
- api_opt["data"] = json.loads(args[0])
- res = Request(api_opt["data"], api_opt["db_info"])
- print(json.dumps(res,indent=2))
- #conn = mysql.connector.connect(user=_USER, password=_PASSWORD, host=_HOST, database=_DATABASE, port=_PORT)
- #conn = mysql.connector.connect(user=api_opt["dbuser"], password=api_opt["dbpass"], host=api_opt["dbhost"], database=api_opt["db"], port=api_opt["dbport"])
- #main(conn)
- #conn.close()
|