naming/styling changes; change base response schema
This commit is contained in:
		
							parent
							
								
									26b6dc1907
								
							
						
					
					
						commit
						3640d1b1de
					
				
							
								
								
									
										169
									
								
								server.py
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								server.py
									
									
									
									
									
								
							| @ -5,66 +5,70 @@ import cherrypy | |||||||
| import sqlite3 | import sqlite3 | ||||||
| import json | import json | ||||||
| 
 | 
 | ||||||
| dbname = "data.sqlite" |  | ||||||
| 
 | 
 | ||||||
|  | dbname = "data.sqlite" | ||||||
| with sqlite3.connect(dbname) as _c: | with sqlite3.connect(dbname) as _c: | ||||||
|     if not db.user_resolve(_c, "anonymous"): |     db.anon_object = db.user_resolve(_c, "anonymous") | ||||||
|         db.user_register(_c, *db.anonymous) |     if not db.anon_object: | ||||||
|  |         db.anon_object = db.user_register(_c, *db.anon_credentials) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # creates a database connection for each thread | # creates a database connection for each thread | ||||||
| def connect(_): | def db_connect(_): | ||||||
|     cherrypy.thread_data.db = sqlite3.connect(dbname) |     cherrypy.thread_data.db = sqlite3.connect(dbname) | ||||||
| cherrypy.engine.subscribe('start_thread', connect) | cherrypy.engine.subscribe('start_thread', db_connect) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def bbjapi(function): | def api_method(function): | ||||||
|     """ |     """ | ||||||
|     A wrapper that handles encoding of objects and errors to a |     A wrapper that handles encoding of objects and errors to a | ||||||
|     standard format for the API, resolves and authorizes users |     standard format for the API, resolves and authorizes users | ||||||
|     from header data, and prepares thread data to handle the |     from header data, and prepares cherrypy.thread_data so other | ||||||
|     request. |     funtions can handle the request. | ||||||
| 
 | 
 | ||||||
|     In addition, all BBJException's will return their attached |     In the body of each api method and all the functions | ||||||
|     schema, and unhandled exceptions return a code 1 error schema. |     they utilize, BBJExceptions are caught and their attached | ||||||
|  |     schema is dispatched to the client. All other unhandled | ||||||
|  |     exceptions will throw a code 1 back at the client and log | ||||||
|  |     it for inspection. | ||||||
|     """ |     """ | ||||||
|     @wraps(function) |     @wraps(function) | ||||||
|     def wrapper(*args, **kwargs): |     def wrapper(*args, **kwargs): | ||||||
|         headers = cherrypy.request.headers |         response = None | ||||||
|         username = headers.get("User") |  | ||||||
|         auth = headers.get("Auth") |  | ||||||
|         anon = False |  | ||||||
| 
 |  | ||||||
|         if not username and not auth: |  | ||||||
|             user = db.user_resolve(cherrypy.thread_data.db, "anonymous") |  | ||||||
|             anon = True |  | ||||||
|         elif not username or not auth: |  | ||||||
|             return json.dumps(schema.error(5, |  | ||||||
|                 "User or Auth was given without the other.")) |  | ||||||
| 
 |  | ||||||
|         if not anon: |  | ||||||
|             user = db.user_resolve(cherrypy.thread_data.db, username) |  | ||||||
|             if not user: |  | ||||||
|                 return json.dumps(schema.error(4, |  | ||||||
|                     "Username is not registered.")) |  | ||||||
| 
 |  | ||||||
|             elif auth != user["auth_hash"]: |  | ||||||
|                 return json.dumps(schema.error(5, |  | ||||||
|                     "Invalid authorization key for user.")) |  | ||||||
| 
 |  | ||||||
|         cherrypy.thread_data.user = user |  | ||||||
|         cherrypy.thread_data.anon = anon |  | ||||||
| 
 |  | ||||||
|         try: |         try: | ||||||
|             value = function(*args, **kwargs) |             username = cherrypy.request.headers.get("User") | ||||||
|  |             auth = cherrypy.request.headers.get("Auth") | ||||||
|  |             anon = False | ||||||
|  | 
 | ||||||
|  |             if not username and not auth: | ||||||
|  |                 user = db.anon_object | ||||||
|  |                 anon = True | ||||||
|  |             elif not username or not auth: | ||||||
|  |                 return json.dumps(schema.error(5, | ||||||
|  |                     "User or Auth was given without the other.")) | ||||||
|  | 
 | ||||||
|  |             if not anon: | ||||||
|  |                 user = db.user_resolve(cherrypy.thread_data.db, username) | ||||||
|  |                 if auth != user["auth_hash"]: | ||||||
|  |                     return json.dumps(schema.error(5, | ||||||
|  |                         "Invalid authorization key for user.")) | ||||||
|  | 
 | ||||||
|  |             cherrypy.thread_data.user = user | ||||||
|  |             cherrypy.thread_data.anon = anon | ||||||
|  |             response = function(*args, **kwargs) | ||||||
| 
 | 
 | ||||||
|         except BBJException as e: |         except BBJException as e: | ||||||
|             value = e.schema |             response = e.schema | ||||||
| 
 | 
 | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             value = schema.error(1, str(e)) |             response = schema.error(1, repr(e)) | ||||||
|  |             # TODO: use a logging file or module or something | ||||||
|  |             # repr() in this case is more verbose than just passing it in | ||||||
|  |             print(repr(e)) | ||||||
|  | 
 | ||||||
|  |         finally: | ||||||
|  |             return json.dumps(response) | ||||||
| 
 | 
 | ||||||
|         return json.dumps(value) |  | ||||||
|     return wrapper |     return wrapper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -76,8 +80,8 @@ def create_usermap(connection, obj): | |||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     if isinstance(obj, dict): |     if isinstance(obj, dict): | ||||||
|         # this is a message object for a thread, unravel it |         # this is a message object for a thread, ditch the keys | ||||||
|         obj = [value for key, value in obj.items()] |         obj = obj.values() | ||||||
| 
 | 
 | ||||||
|     return { |     return { | ||||||
|         user_id: db.user_resolve( |         user_id: db.user_resolve( | ||||||
| @ -114,18 +118,40 @@ APICONFIG = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class API(object): | class API(object): | ||||||
|     @bbjapi |     @api_method | ||||||
|  |     @cherrypy.expose | ||||||
|  |     def get_me(self): | ||||||
|  |         """ | ||||||
|  |         Requires no arguments. Returns your internal user object, | ||||||
|  |         including your authorization hash. | ||||||
|  |         """ | ||||||
|  |         return schema.response(cherrypy.thread_data.user) | ||||||
|  | 
 | ||||||
|  |     @api_method | ||||||
|  |     @cherrypy.expose | ||||||
|  |     def user_get(self): | ||||||
|  |         """ | ||||||
|  |         Retreive an external user object for the given `user`. | ||||||
|  |         Can be a user_id or user_name. | ||||||
|  |         """ | ||||||
|  |         args = cherrypy.request.json | ||||||
|  |         validate(["user"]) | ||||||
|  |         return schema.response(db.user_resolve( | ||||||
|  |             cherrypy.thread_data.db, | ||||||
|  |             args["user"], | ||||||
|  |             return_false=False, | ||||||
|  |             externalize=True)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     @api_method | ||||||
|     @cherrypy.expose |     @cherrypy.expose | ||||||
|     def thread_index(self): |     def thread_index(self): | ||||||
|         threads = db.thread_index(cherrypy.thread_data.db) |         threads = db.thread_index(cherrypy.thread_data.db) | ||||||
|         usermap = create_usermap(cherrypy.thread_data.db, threads) |         usermap = create_usermap(cherrypy.thread_data.db, threads) | ||||||
|         return schema.response({ |         return schema.response(threads, usermap) | ||||||
|             "data": threads, |  | ||||||
|             "usermap": usermap |  | ||||||
|         }) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     @bbjapi |     @api_method | ||||||
|     @cherrypy.expose |     @cherrypy.expose | ||||||
|     @cherrypy.tools.json_in() |     @cherrypy.tools.json_in() | ||||||
|     def thread_create(self): |     def thread_create(self): | ||||||
| @ -142,27 +168,22 @@ class API(object): | |||||||
|               cherrypy.thread_data.user |               cherrypy.thread_data.user | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return schema.response({ |         return schema.response(thread, usermap) | ||||||
|             "data": thread, |  | ||||||
|             "usermap": usermap |  | ||||||
|         }) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     @bbjapi |     @api_method | ||||||
|     @cherrypy.expose |     @cherrypy.expose | ||||||
|     @cherrypy.tools.json_in() |     @cherrypy.tools.json_in() | ||||||
|     def thread_reply(self): |     def thread_reply(self): | ||||||
|         args = cherrypy.request.json |         args = cherrypy.request.json | ||||||
|         validate(args, ["thread_id", "body"]) |         validate(args, ["thread_id", "body"]) | ||||||
|         return schema.response({ |         return schema.response(db.thread_reply( | ||||||
|             "data": db.thread_reply( |             cherrypy.thread_data.db, | ||||||
|                 cherrypy.thread_data.db, |             cherrypy.thread_data.user["user_id"], | ||||||
|                 cherrypy.thread_data.user["user_id"], |             args["thread_id"], args["body"])) | ||||||
|                 args["thread_id"], args["body"]) |  | ||||||
|         }) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     @bbjapi |     @api_method | ||||||
|     @cherrypy.expose |     @cherrypy.expose | ||||||
|     @cherrypy.tools.json_in() |     @cherrypy.tools.json_in() | ||||||
|     def thread_load(self): |     def thread_load(self): | ||||||
| @ -177,38 +198,32 @@ class API(object): | |||||||
|             cherrypy.thread_data.db, |             cherrypy.thread_data.db, | ||||||
|             thread["messages"]) |             thread["messages"]) | ||||||
| 
 | 
 | ||||||
|         return schema.response({ |         return schema.response(thread, usermap) | ||||||
|             "data": thread, |  | ||||||
|             "usermap": usermap |  | ||||||
|         }) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     @bbjapi |     @api_method | ||||||
|     @cherrypy.expose |     @cherrypy.expose | ||||||
|     @cherrypy.tools.json_in() |     @cherrypy.tools.json_in() | ||||||
|     def user_register(self): |     def user_register(self): | ||||||
|         args = cherrypy.request.json |         args = cherrypy.request.json | ||||||
|         validate(args, ["user_name", "auth_hash"]) |         validate(args, ["user_name", "auth_hash"]) | ||||||
|         return schema.response({ |         return schema.response(db.user_register( | ||||||
|             "data": db.user_register( |             cherrypy.thread_data.db, | ||||||
|                 cherrypy.thread_data.db, |             args["user_name"], | ||||||
|                 args["user_name"], args["auth_hash"]) |             args["auth_hash"])) | ||||||
|         }) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     @bbjapi |     @api_method | ||||||
|     @cherrypy.expose |     @cherrypy.expose | ||||||
|     @cherrypy.tools.json_in() |     @cherrypy.tools.json_in() | ||||||
|     def edit_query(self): |     def edit_query(self): | ||||||
|         args = cherrypy.request.json |         args = cherrypy.request.json | ||||||
|         validate(args, ["thread_id", "post_id"]) |         validate(args, ["thread_id", "post_id"]) | ||||||
|         return schema.response({ |         return schema.response(message_edit_query( | ||||||
|             "data": message_edit_query( |             cherrypy.thread_data.db, | ||||||
|                 cherrypy.thread_data.db, |             cherrypy.thread_data.user["user_id"], | ||||||
|                 cherrypy.thread_data.user["user_id"], |             args["thread_id"], | ||||||
|                 args["thread_id"], |             args["post_id"])) | ||||||
|                 args["post_id"]) |  | ||||||
|         }) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								setup.sh
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.sh
									
									
									
									
									
								
							| @ -2,7 +2,7 @@ | |||||||
| set -e | set -e | ||||||
| 
 | 
 | ||||||
| if [[ $1 == --init ]]; then | if [[ $1 == --init ]]; then | ||||||
| 	sqlite3 bbj.db < schema.sql | 	sqlite3 data.sqlite < schema.sql | ||||||
| 	echo cleared | 	echo cleared | ||||||
| 	exit | 	exit | ||||||
| fi | fi | ||||||
|  | |||||||
| @ -25,7 +25,8 @@ import pickle | |||||||
| import json | import json | ||||||
| import os | import os | ||||||
| 
 | 
 | ||||||
| anonymous = \ | anon_object = None | ||||||
|  | anon_credentials = \ | ||||||
|     ("anonymous", |     ("anonymous", | ||||||
|      "5430eeed859cad61d925097ec4f53246" |      "5430eeed859cad61d925097ec4f53246" | ||||||
|      "1ccf1ab6b9802b09a313be1478a4d614") |      "1ccf1ab6b9802b09a313be1478a4d614") | ||||||
| @ -228,7 +229,7 @@ def user_resolve(connection, name_or_id, externalize=False, return_false=True): | |||||||
|         return False |         return False | ||||||
|     raise BBJParameterError( |     raise BBJParameterError( | ||||||
|         "Requested user element ({})" |         "Requested user element ({})" | ||||||
|         " does not exist".format(name_or_id)) |         " is not registered".format(name_or_id)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def user_update(connection, user_object, parameters): | def user_update(connection, user_object, parameters): | ||||||
|  | |||||||
| @ -1,12 +1,15 @@ | |||||||
| def base(): | def base(): | ||||||
|     return { |     return { | ||||||
|         "error": False |         "error": False, | ||||||
|  |         "data": None, | ||||||
|  |         "usermap": dict() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def response(dictionary): | def response(data, usermap={}): | ||||||
|     result = base() |     result = base() | ||||||
|     result.update(dictionary) |     result["data"] = data | ||||||
|  |     result["usermap"].update(usermap) | ||||||
|     return result |     return result | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user