def test_create_https_certificates(self): """ Test that create_https_certificates successfully generates certificate and private key """ try: import OpenSSL except ImportError: self.skipTest('pyOpenSSL is not installed') return False base_path = os.path.dirname(__file__) cert_path = os.path.abspath(os.path.join(base_path, 'test.crt')) pkey_path = os.path.abspath(os.path.join(base_path, 'test.key')) def removeTestFiles(): try: os.remove(cert_path) os.remove(pkey_path) except OSError: pass removeTestFiles() # always remove existing self.assertTrue(helpers.create_https_certificates( cert_path, pkey_path)) self.assertTrue(os.path.isfile(cert_path)) self.assertTrue(os.path.isfile(pkey_path)) FILETYPE_PEM = OpenSSL.crypto.FILETYPE_PEM try: with open(cert_path, 'rb') as f: cert = OpenSSL.crypto.load_certificate(FILETYPE_PEM, f.read()) except Exception as error: removeTestFiles() self.fail('Unable to load certificate') try: with open(pkey_path, 'rb') as f: pkey = OpenSSL.crypto.load_privatekey(FILETYPE_PEM, f.read()) except Exception as error: removeTestFiles() self.fail('Unable to load private key') context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD) context.use_privatekey(pkey) context.use_certificate(cert) failed = False try: context.check_privatekey() except OpenSSL.SSL.Error: failed = True finally: removeTestFiles() self.assertFalse(failed, 'private key does not match certificate')
def __init__(self, options=None): super().__init__() self.daemon = True self.alive = True self.name = "WEBSERVER" self.options = options if settings.WEB_HOST and settings.WEB_HOST != "0.0.0.0": web_host = settings.WEB_HOST else: web_host = ("0.0.0.0", "")[settings.WEB_IPV6] self.options.update({ "data_root": os.path.join(settings.PROG_DIR, "gui", settings.GUI_NAME), "web_root": settings.WEB_ROOT, "host": web_host, "enable_https": settings.ENABLE_HTTPS, "handle_reverse_proxy": settings.HANDLE_REVERSE_PROXY, "log_dir": (None, settings.LOG_DIR)[settings.WEB_LOG], # 'username': oldbeard.WEB_USERNAME or '', # 'password': oldbeard.WEB_PASSWORD or '', }) self.options.setdefault("port", settings.WEB_PORT or 8081) self.server = None # video root if settings.ROOT_DIRS: root_dirs = settings.ROOT_DIRS.split("|") self.video_root = root_dirs[int(root_dirs[0]) + 1] else: self.video_root = None # web root if self.options["web_root"]: settings.WEB_ROOT = self.options[ "web_root"] = "/" + self.options["web_root"].strip("/") # api root if not settings.API_KEY: settings.API_KEY = generateApiKey() self.options[ "api_root"] = f"{settings.WEB_ROOT}/api/{settings.API_KEY}" # tornado setup self.enable_https = self.options["enable_https"] self.https_cert = None if settings.HTTPS_CERT: self.https_cert = os.path.realpath(settings.HTTPS_CERT) if not os.path.exists(self.https_cert) and not os.path.isabs( self.https_cert): self.https_cert = os.path.realpath( os.path.join(settings.DATA_DIR, settings.HTTPS_CERT)) self.https_key = None if settings.HTTPS_KEY: self.https_key = os.path.realpath(settings.HTTPS_KEY) if not os.path.exists(self.https_key) and not os.path.isabs( self.https_key): self.https_key = os.path.realpath( os.path.join(settings.DATA_DIR, settings.HTTPS_KEY)) if self.enable_https: # If either the HTTPS certificate or key do not exist, make some self-signed ones. if not (self.https_cert and os.path.exists(self.https_cert) and self.https_key and os.path.exists(self.https_key)): if not create_https_certificates(self.https_cert, self.https_key): logger.info( "Unable to create CERT/KEY files, disabling HTTPS") settings.ENABLE_HTTPS = self.enable_https = False if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)): logger.warning( "Disabled HTTPS because of missing CERT and KEY files") settings.ENABLE_HTTPS = self.enable_https = False asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy()) # Load the app self.app = Application( [], debug= False, # enables autoreload, compiled_template_cache, static_hash_cache, serve_traceback - This fixes the 404 page and fixes autoreload for # devs. We could now update without restart possibly if we check DB version hasnt changed! autoreload=False, gzip=settings.WEB_USE_GZIP, cookie_secret=settings.WEB_COOKIE_SECRET, login_url=f'{self.options["web_root"]}/login/', static_path=self.options["data_root"], static_url_prefix=f'{self.options["web_root"]}/', static_handler_class=SickChillStaticFileHandler # default_handler_class=Custom404Handler ) # Static File Handlers self.app.add_handlers( ".*$", [ url( rf'{self.options["web_root"]}/(favicon\.ico)', SickChillStaticFileHandler, { "path": os.path.join(self.options["data_root"], "images/ico") }, name="favicon", ), url( rf'{self.options["web_root"]}/images/(.*)', SickChillStaticFileHandler, { "path": os.path.join(self.options["data_root"], "images") }, name="images", ), url( rf'{self.options["web_root"]}/cache/images/(.*)', SickChillStaticFileHandler, {"path": os.path.join(settings.CACHE_DIR, "images")}, name="image_cache", ), url(rf'{self.options["web_root"]}/css/(.*)', SickChillStaticFileHandler, {"path": os.path.join(self.options["data_root"], "css")}, name="css"), url(rf'{self.options["web_root"]}/js/(.*)', SickChillStaticFileHandler, {"path": os.path.join(self.options["data_root"], "js")}, name="js"), url( rf'{self.options["web_root"]}/fonts/(.*)', SickChillStaticFileHandler, {"path": os.path.join(self.options["data_root"], "fonts")}, name="fonts", ) # TODO: WTF is this? # url(rf'{self.options["web_root"]}/videos/(.*)', SickChillStaticFileHandler, # {"path": self.video_root}, name='videos') ], ) # Main Handlers self.app.add_handlers( ".*$", [ url(rf'{self.options["api_root"]}(/?.*)', ApiHandler, name="api"), url(rf'{self.options["web_root"]}/getkey(/?.*)', KeyHandler, name="get_api_key"), url(rf'{self.options["web_root"]}/api/builder', RedirectHandler, {"url": self.options["web_root"] + "/apibuilder/"}, name="apibuilder"), url(rf'{self.options["web_root"]}/login(/?)', LoginHandler, name="login"), url(rf'{self.options["web_root"]}/logout(/?)', LogoutHandler, name="logout"), url(rf'{self.options["web_root"]}/calendar/?', CalendarHandler, name="calendar"), url(rf'{self.options["web_root"]}/movies/(?P<route>details)/(?P<slug>.*)/', MoviesHandler, name="movies-details"), url(rf'{self.options["web_root"]}/movies/(?P<route>remove)/(?P<pk>.*)/', MoviesHandler, name="movies-remove"), url(rf'{self.options["web_root"]}/movies/(?P<route>add)/', MoviesHandler, name="movies-add"), url(rf'{self.options["web_root"]}/movies/(?P<route>search)/', MoviesHandler, name="movies-search"), url(rf'{self.options["web_root"]}/movies/(?P<route>list)/', MoviesHandler, name="movies-list"), url(rf'{self.options["web_root"]}/movies/(.*)', MoviesHandler, name="movies"), # routes added by @route decorator # Plus naked index with missing web_root prefix ] + Route.get_routes(self.options["web_root"]), )