Browse Source

Login base

pull/2140/head
Ruud 12 years ago
parent
commit
9783409756
  1. 57
      couchpotato/__init__.py
  2. 45
      couchpotato/core/auth.py
  3. 9
      couchpotato/runner.py
  4. 18
      couchpotato/templates/login.html

57
couchpotato/__init__.py

@ -1,11 +1,10 @@
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.helpers.variable import md5
from couchpotato.core.helpers.variable import md5, tryInt
from couchpotato.core.logger import CPLog
from couchpotato.environment import Env
from tornado import template
from tornado.web import RequestHandler
from tornado.web import RequestHandler, authenticated
import os
import time
import traceback
@ -16,9 +15,23 @@ log = CPLog(__name__)
views = {}
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
@requires_auth
class WebHandler(RequestHandler):
class WebHandler(BaseHandler):
@authenticated
def get(self, route, *args, **kwargs):
route = route.strip('/')
if not views.get(route):
@ -28,7 +41,7 @@ class WebHandler(RequestHandler):
try:
self.write(views[route]())
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'})
def addView(route, func, static = False):
@ -79,6 +92,38 @@ class KeyHandler(RequestHandler):
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):
index_url = Env.get('web_base')
url = rh.request.uri[len(index_url):]

45
couchpotato/core/auth.py

@ -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

9
couchpotato/runner.py

@ -1,6 +1,6 @@
from argparse import ArgumentParser
from cache import FileSystemCache
from couchpotato import KeyHandler
from couchpotato import KeyHandler, LoginHandler, LogoutHandler
from couchpotato.api import NonBlockHandler, ApiHandler
from couchpotato.core.event import fireEventAsync, fireEvent
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,
debug = config['use_reloader'],
gzip = True,
cookie_secret = api_key,
login_url = "/login",
)
Env.set('app', application)
# Request handlers
application.add_handlers(".*$", [
(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'%sgetkey(/?)' % web_base, KeyHandler), # Get API key
(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
(r'%s(.*)(/?)' % web_base, WebHandler),

18
couchpotato/templates/login.html

@ -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>
Loading…
Cancel
Save