-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathauth.py
executable file
·160 lines (136 loc) · 5.76 KB
/
auth.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/python2.6
#-*- coding: UTF-8 -*-
import sys, time, os, json, traceback, datetime, urllib, random;
import cherrypy, MySQLdb;
from utility import error, trace, get_work_dir, reload_config, send_mail, enable_crossdomain, sql_exec;
SESSION_KEY = '_cp_user_id'
_config = None;
def auth_init(config):
global _config;
_config = config;
'''
authorize: get the user ids that cannot access by user_id.
'''
def authorize_get_exception_user_id(user_id):
if user_id is None:
return [];
# check admin role, if admin, access all users.
records = sql_exec("select user_id from dr_authorize_admin where user_id='%s'"%(user_id));
if len(records) > 0:
return [];
# check manager role, if manager, access himself and all users managed by him.
records = sql_exec("select user_id from dr_user "
"where user_id!='%s' "
"and user_id not in(select user_id from dr_authorize_manager where manager_id='%s')"
%(user_id, user_id));
ret = [];
for record in records:
ret.append(record["user_id"]);
return ret;
'''
authorize: require user specified by request_user_id
'''
def authorize_user(request_user_id):
auth = _config["auth"];
if not auth["on"]:
return;
# method donot require check.
conditions = cherrypy.request.config.get('auth.require', None)
if conditions is None:
return;
# QQ-OAuth not enabled.
if auth["strategy"] == "qq_oauth":
# check QQ-OAuth session.
user_id = cherrypy.session.get(SESSION_KEY);
if user_id is None:
error("authorize_user invalid, no session.");
enable_crossdomain();
raise cherrypy.HTTPError(401, "You are not authorized, login please.");
return;
if request_user_id in authorize_get_exception_user_id(user_id):
error("authorize_user(id=%s) requires user id=%s invalid, check authorization failed."%(user_id, request_user_id));
enable_crossdomain();
raise cherrypy.HTTPError(403, "You(id=%s) are not authorized as %s, login please."%(user_id, request_user_id));
return;
trace("authorize success, user_id=%s requires id=%s"%(user_id, request_user_id));
return;
def check_auth(*args, **kwargs):
# auth not enabled in config.
auth = _config["auth"];
if not auth["on"]:
return;
# method donot require check.
conditions = cherrypy.request.config.get('auth.require', None)
if conditions is None:
return;
# QQ-OAuth not enabled.
if auth["strategy"] == "qq_oauth":
trace("check session, session_id=%s"%(cherrypy.session.id));
# check QQ-OAuth session.
user_id = cherrypy.session.get(SESSION_KEY);
if user_id is None:
error("session invalid, check auth failed.");
enable_crossdomain();
raise cherrypy.HTTPError(401, "You are not authorized, login please.");
return;
# check user enabled.
if True:
user_id = cherrypy.session.get(SESSION_KEY);
trace("check whether user enabled. id=%s"%(user_id));
records = sql_exec("select user_id from dr_user where user_id='%s' and enabled=true",(user_id));
if len(records) <= 0:
error("user disabled, id=%s."%(user_id));
enable_crossdomain();
raise cherrypy.HTTPError(401, "You are disabled");
return;
# check condition.
for condition in conditions:
if not condition():
error("codition check invalid, check auth failed.");
enable_crossdomain();
raise cherrypy.HTTPError(401, "You are not authorized for specified condition");
return;
trace("check auth success. user_id=%s"%(user_id));
# to enable the hook, must enable the config tools.auth.on to True.
cherrypy.tools.auth = cherrypy.Tool('before_handler', check_auth)
# the conditions for check_auth
# require admin to complete these oprations.
def require_admin():
user_id = cherrypy.session.get(SESSION_KEY);
records = sql_exec("select user_id from dr_authorize_admin where user_id='%s'"%(user_id));
return len(records) > 0;
'''
if request contains the session_id, hack to set the cookie to enable session
'''
def crossdomain_session(*args, **kwargs):
# to generate the query string.
# the on_start_resource handler have not parse the query string.
cherrypy.request.process_query_string();
# reload session id if request contains api_key session_id.
if "api_key" in cherrypy.request.params:
# get the origin session id
origin_session_id = "";
if "session_id" in cherrypy.request.cookie:
origin_session_id = cherrypy.request.cookie["session_id"];
# update session id
session_id = cherrypy.request.params["api_key"];
# remove the session_id in query_string
cherrypy.request.params.clear();
cherrypy.request.query_string = cherrypy.request.query_string.replace("api_key="+session_id, "");
# hack cookie.
cherrypy.request.cookie["session_id"] = session_id;
trace("hack cookie session %s to %s"%(origin_session_id, session_id));
# to enable the hook, must enable the config tools.crossdomain_session.on to True.
cherrypy.tools.crossdomain_session = cherrypy.Tool('on_start_resource', crossdomain_session)
'''
@conditions defines what need to check for method.
'''
def require_auth(*conditions):
def decorate(f):
if not hasattr(f, "_cp_config"):
f._cp_config = {};
if 'auth.require' not in f._cp_config:
f._cp_config['auth.require'] = []
f._cp_config['auth.require'].extend(conditions)
return f;
return decorate;