def login(self, token): client = self.make_session(token=token) resp = client.get(config.get("oauth.google", "user_info")) info = json.loads(resp.content.decode('utf-8')) # StackOverflow suggests UUIDs aren't very secure for session # identifiers, but offered recommendations that use os.urandom(), # same as the UUID module's fully random identifiers, such as uuid4. # ¯\_('')_/¯ new_session = UserSession(id=uuid.uuid4().hex, info=info, token=token) self.__sessions[new_session.id] = new_session # Session ID for server-side authentication bottle.response.set_cookie( name=config.get("session", "session_id"), value=new_session.id, secret=config.get("session", "cookie_secret"), path="/", httponly=True, secure=True, expires=new_session.token['expires_at']) return
def handle_login(): global oauth_state google = oauth.OAuth2Session( client_id = config.get("oauth.google", "client_id"), redirect_uri = config.get("oauth.google", "redirect_to"), scope = config.get("oauth.google", "scopes")) auth_uri, state = google.authorization_url( config.get("oauth.google", "auth_uri")) # approval_prompt='force') oauth_state = state bottle.redirect(auth_uri)
def handle_process(): global oauth_state google = oauth.OAuth2Session( client_id=config.get("oauth.google", "client_id"), redirect_uri=config.get("oauth.google", "redirect_to"), state=oauth_state) token = google.fetch_token( config.get("oauth.google", "token_uri"), client_secret=config.get("oauth.google", "client_secret"), code=bottle.request.GET.get('code')) sessions.login(token) bottle.redirect("/")
def design_docs_setup(): """Pushes the CouchDB design docs to the database. These documents are required. """ os.chdir(os.path.join(os.path.dirname(__file__), "couchdb_design")) spawn(['couchapp', 'push', '.', config.get('database', 'couchapp_dest')])
def make_session(self, *, token=None, session_id=None): if token is None: if session_id is not None: token = self.__sessions[session_id].token else: return None return oauth.OAuth2Session( # standard session open client_id=config.get("oauth.google", "client_id"), token=token)
def wrapper(*args, **kwargs): session_id = bottle.request.get_cookie( config.get("session", "session_id"), secret=config.get("session", "cookie_secret")) if session_id is None: # not logged in (no cookie) bottle.response.status = '401 Unauthorized' return session = None if not kwargs.get('user_session'): # Get the session state if we don't have one already. session = sessions.user_session(session_id=session_id) if session is None: # not logged in (no session matching provided ID) bottle.redirect("/") return kwargs['user_session'] = session return fn(*args, **kwargs)
def run(self, handler): from wsgiref.simple_server import make_server, WSGIRequestHandler import ssl if self.quiet: class QuietHandler(WSGIRequestHandler): def log_request(*args, **kw): pass self.options['handler_class'] = QuietHandler srv = make_server(self.host, self.port, handler, **self.options) srv.socket = ssl.wrap_socket ( srv.socket, certfile=config.get("https", "certificate"), # path to certificate server_side=True) srv.serve_forever()
def connect(): server = couchdb.Server(config.get("database", "netloc")) server.resource.credentials = (config.get("database", "app_user"), config.get("database", "app_passwd")) return server
def database_setup(): """Bootstrap CouchDB Database. Requires couchdb admin. 1. Creates a new user (default: icecrate). 2. Creates the app database (default: icecrate). 3. Sets up the _security object (only admin and icecrate can access). """ admin_user = input("CouchDB Admin (blank for admin party): ") admin_pass = getpass("Password (blank for admin party): ") # It's uncommon, but this can be changed. user_db_name = input("CouchDB users database (_users): ") if not user_db_name: user_db_name = "_users" server = couchdb.Server(config.get("database", "netloc")) # We might be in Admin Party mode. if admin_user: # Sign in with admin. server.resource.credentials = (admin_user, admin_pass) # App user usersdb = server[user_db_name] user_id = "org.couchdb.user:{user}".format(user=config.get("database", "app_user")) print("checking database user... ", end="") if user_id not in usersdb: print("missing.\ncreating database user... ", end="") usersdb.save({ "_id": user_id, "type": "user", "name": config.get("database", "app_user"), "password": config.get("database", "app_passwd"), "roles": []}) print("ok.") # setting up database print("checking database... ", end="") if config.get("database", "app_db") not in server: print("missing.\ncreating database... ", end="") server.create(config.get("database", "app_db")) appdb = server[config.get("database", "app_db")] print("ok.") print("checking _security object... ", end="") security = appdb.security security_is_dirty = False if "admins" not in security: print("empty.\nsetting up _security... ", end="") security['admins'] = {} security_is_dirty = True if "names" not in security.get("admins"): security['admins']['names'] = [] security_is_dirty = True if config.get("database", "app_user") not in security['admins']['names']: security['admins']['names'].append(config.get("database", "app_user")) security_is_dirty = True if "roles" not in security.get("admins"): security['admins']['roles'] = ["admins"] _security_is_dirty = True if security_is_dirty: appdb.security = security print("ok.")
def main(): ssl_server = ssl.SSLWSGIRefServer( host=config.get("host", "addr"), port=config.get("host", "port")) bottle.run(ssl.use_https(app), server=ssl_server)