Login base
This commit is contained in:
1 parent
faa136a365
commit
d7700900db
4 files changed
+76
-53
No files matched your search
+51
-6
@@ -1,11 +1,10 @@
|
|||||||
from couchpotato.api import api_docs, api_docs_missing, api
|
from couchpotato.api import api_docs, api_docs_missing, api
|
||||||
from couchpotato.core.auth import requires_auth
|
|
||||||
from couchpotato.core.event import fireEvent
|
from couchpotato.core.event import fireEvent
|
||||||
from couchpotato.core.helpers.variable import md5
|
from couchpotato.core.helpers.variable import md5, tryInt
|
||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
from couchpotato.environment import Env
|
from couchpotato.environment import Env
|
||||||
from tornado import template
|
from tornado import template
|
||||||
from tornado.web import RequestHandler
|
from tornado.web import RequestHandler, authenticated
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
@@ -16,9 +15,23 @@ log = CPLog(__name__)
|
|||||||
views = {}
|
views = {}
|
||||||
template_loader = template.Loader(os.path.join(os.path.dirname(__file__), 'templates'))
|
template_loader = template.Loader(os.path.join(os.path.dirname(__file__), 'templates'))
|
||||||
|
|
||||||
|
|
||||||
|
class BaseHandler(RequestHandler):
|
||||||
|
|
||||||
|
def get_current_user(self):
|
||||||
|
username = Env.setting('username')
|
||||||
|
password = Env.setting('password')
|
||||||
|
|
||||||
|
if username or password:
|
||||||
|
print self.get_secure_cookie('user')
|
||||||
|
return self.get_secure_cookie('user')
|
||||||
|
else: # Login when no username or password are set
|
||||||
|
return True
|
||||||
|
|
||||||
# Main web handler
|
# Main web handler
|
||||||
@requires_auth
|
class WebHandler(BaseHandler):
|
||||||
class WebHandler(RequestHandler):
|
|
||||||
|
@authenticated
|
||||||
def get(self, route, *args, **kwargs):
|
def get(self, route, *args, **kwargs):
|
||||||
route = route.strip('/')
|
route = route.strip('/')
|
||||||
if not views.get(route):
|
if not views.get(route):
|
||||||
@@ -28,7 +41,7 @@ class WebHandler(RequestHandler):
|
|||||||
try:
|
try:
|
||||||
self.write(views[route]())
|
self.write(views[route]())
|
||||||
except:
|
except:
|
||||||
log.error('Failed doing web request "%s": %s', (route, traceback.format_exc()))
|
log.error("Failed doing web request '%s': %s", (route, traceback.format_exc()))
|
||||||
self.write({'success': False, 'error': 'Failed returning results'})
|
self.write({'success': False, 'error': 'Failed returning results'})
|
||||||
|
|
||||||
def addView(route, func, static = False):
|
def addView(route, func, static = False):
|
||||||
@@ -79,6 +92,38 @@ class KeyHandler(RequestHandler):
|
|||||||
self.write({'success': False, 'error': 'Failed returning results'})
|
self.write({'success': False, 'error': 'Failed returning results'})
|
||||||
|
|
||||||
|
|
||||||
|
class LoginHandler(BaseHandler):
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
|
||||||
|
if self.get_current_user():
|
||||||
|
self.redirect('/')
|
||||||
|
else:
|
||||||
|
self.write(template_loader.load('login.html').generate())
|
||||||
|
|
||||||
|
def post(self, *args, **kwargs):
|
||||||
|
|
||||||
|
api = None
|
||||||
|
|
||||||
|
username = Env.setting('username')
|
||||||
|
password = Env.setting('password')
|
||||||
|
|
||||||
|
if (self.get_argument('username') == username or not username) and (md5(self.get_argument('password')) == password or not password):
|
||||||
|
api = Env.setting('api_key')
|
||||||
|
|
||||||
|
if api:
|
||||||
|
remember_me = tryInt(self.get_argument('remember_me', default = 0))
|
||||||
|
self.set_secure_cookie('user', api, expires_days = 30 if remember_me else 0)
|
||||||
|
|
||||||
|
self.redirect('/')
|
||||||
|
|
||||||
|
class LogoutHandler(BaseHandler):
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
self.clear_cookie('user')
|
||||||
|
self.redirect('/login')
|
||||||
|
|
||||||
|
|
||||||
def page_not_found(rh):
|
def page_not_found(rh):
|
||||||
index_url = Env.get('web_base')
|
index_url = Env.get('web_base')
|
||||||
url = rh.request.uri[len(index_url):]
|
url = rh.request.uri[len(index_url):]
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
from couchpotato.core.helpers.variable import md5
|
|
||||||
from couchpotato.environment import Env
|
|
||||||
import base64
|
|
||||||
|
|
||||||
def check_auth(username, password):
|
|
||||||
return username == Env.setting('username') and password == Env.setting('password')
|
|
||||||
|
|
||||||
def requires_auth(handler_class):
|
|
||||||
|
|
||||||
def wrap_execute(handler_execute):
|
|
||||||
|
|
||||||
def require_basic_auth(handler, kwargs):
|
|
||||||
|
|
||||||
if Env.setting('username') and Env.setting('password'):
|
|
||||||
|
|
||||||
auth_header = handler.request.headers.get('Authorization')
|
|
||||||
auth_decoded = base64.decodestring(auth_header[6:]) if auth_header else None
|
|
||||||
|
|
||||||
username = ''
|
|
||||||
password = ''
|
|
||||||
|
|
||||||
if auth_decoded:
|
|
||||||
username, password = auth_decoded.split(':', 2)
|
|
||||||
|
|
||||||
if auth_header is None or not auth_header.startswith('Basic ') or (not check_auth(username.decode('latin'), md5(password.decode('latin')))):
|
|
||||||
handler.set_status(401)
|
|
||||||
handler.set_header('WWW-Authenticate', 'Basic realm="CouchPotato Login"')
|
|
||||||
handler._transforms = []
|
|
||||||
handler.finish()
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _execute(self, transforms, *args, **kwargs):
|
|
||||||
|
|
||||||
if not require_basic_auth(self, kwargs):
|
|
||||||
return False
|
|
||||||
return handler_execute(self, transforms, *args, **kwargs)
|
|
||||||
|
|
||||||
return _execute
|
|
||||||
|
|
||||||
handler_class._execute = wrap_execute(handler_class._execute)
|
|
||||||
|
|
||||||
return handler_class
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from cache import FileSystemCache
|
from cache import FileSystemCache
|
||||||
from couchpotato import KeyHandler
|
from couchpotato import KeyHandler, LoginHandler, LogoutHandler
|
||||||
from couchpotato.api import NonBlockHandler, ApiHandler
|
from couchpotato.api import NonBlockHandler, ApiHandler
|
||||||
from couchpotato.core.event import fireEventAsync, fireEvent
|
from couchpotato.core.event import fireEventAsync, fireEvent
|
||||||
from couchpotato.core.helpers.encoding import toUnicode
|
from couchpotato.core.helpers.encoding import toUnicode
|
||||||
@@ -233,10 +233,11 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
|
|||||||
log_function = lambda x : None,
|
log_function = lambda x : None,
|
||||||
debug = config['use_reloader'],
|
debug = config['use_reloader'],
|
||||||
gzip = True,
|
gzip = True,
|
||||||
|
cookie_secret = api_key,
|
||||||
|
login_url = "/login",
|
||||||
)
|
)
|
||||||
Env.set('app', application)
|
Env.set('app', application)
|
||||||
|
|
||||||
|
|
||||||
# Request handlers
|
# Request handlers
|
||||||
application.add_handlers(".*$", [
|
application.add_handlers(".*$", [
|
||||||
(r'%snonblock/(.*)(/?)' % api_base, NonBlockHandler),
|
(r'%snonblock/(.*)(/?)' % api_base, NonBlockHandler),
|
||||||
@@ -245,6 +246,10 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
|
|||||||
(r'%s(.*)(/?)' % api_base, ApiHandler), # Main API handler
|
(r'%s(.*)(/?)' % api_base, ApiHandler), # Main API handler
|
||||||
(r'%sgetkey(/?)' % web_base, KeyHandler), # Get API key
|
(r'%sgetkey(/?)' % web_base, KeyHandler), # Get API key
|
||||||
(r'%s' % api_base, RedirectHandler, {"url": web_base + 'docs/'}), # API docs
|
(r'%s' % api_base, RedirectHandler, {"url": web_base + 'docs/'}), # API docs
|
||||||
|
|
||||||
|
# Login handlers
|
||||||
|
(r'%slogin(/?)' % web_base, LoginHandler),
|
||||||
|
(r'%slogout(/?)' % web_base, LogoutHandler),
|
||||||
|
|
||||||
# Catch all webhandlers
|
# Catch all webhandlers
|
||||||
(r'%s(.*)(/?)' % web_base, WebHandler),
|
(r'%s(.*)(/?)' % web_base, WebHandler),
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{% autoescape None %}
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
|
||||||
|
<title>Login</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form action="" method="post">
|
||||||
|
<div><input name="username" type="text" placeholder="Username" /></div>
|
||||||
|
<div><input name="password" type="password" placeholder="Password" /></div>
|
||||||
|
<div><label title="for 30 days"><input name="remember_me" type="checkbox" value="1" checked="checked" /> Remember me</label></div>
|
||||||
|
<div><input name="submit" type="submit" value="Login" /></div>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in new issue
Block a user