def web_auth(self): typeAuth = str(self.request.arguments["typeauth"][0]) loadValue = self.request.arguments["value"][0] method = Conf.getCSValue("TypeAuths/%s/method" % typeAuth) auths = ['Certificate'] if Conf.getCSSections("TypeAuths")['OK']: auths.extend(Conf.getCSSections("TypeAuths").get("Value")) if (typeAuth == 'Logout') or (typeAuth not in auths): typeAuth = self.get_secure_cookie("TypeAuth") self.set_secure_cookie("TypeAuth", 'Visitor') elif method == 'oAuth2': accessToken = loadValue url = Conf.getCSValue( 'TypeAuths/%s/authority' % typeAuth) + '/userinfo' access = 'Bearer ' + accessToken heads = { 'Authorization': access, 'Content-Type': 'application/json' } oJson = requests.get(url, headers=heads, verify=False).json() res = getUsernameForID(oJson['sub']) if res['OK']: self.set_secure_cookie("TypeAuth", typeAuth) self.set_secure_cookie("AccessToken", accessToken) self.write({"value": 'Done'}) else: self.write({"value": 'NotRegistred', "profile": oJson}) else: self.set_secure_cookie("TypeAuth", typeAuth)
def web_index(self): # Render base template data = self.getSessionData() url_state = "" if self.request.arguments.has_key("url_state") and len(self.request.arguments["url_state"][0]) > 0: url_state = self.request.arguments["url_state"][0] view_name = Conf.getTheme() if self.request.arguments.has_key("view") and len(self.request.arguments["view"][0]) > 0: view_name = self.request.arguments["view"][0] theme_name = "ext-all-gray" if self.request.arguments.has_key("theme") and len(self.request.arguments["theme"][0]) > 0: if self.request.arguments["theme"][0]=="Neptune": theme_name = "ext-all-neptune" if self.request.arguments["theme"][0]=="Classic": theme_name = "ext-all" open_app = "" if self.request.arguments.has_key("open_app") and len(self.request.arguments["open_app"][0]) > 0: open_app = self.request.arguments["open_app"][0].strip() level = str(gLogger.getLevel()).lower() self.render( "root.tpl", base_url = data[ 'baseURL' ], _dev = Conf.devMode(), ext_version = data[ 'extVersion' ], url_state = url_state, extensions = data[ 'extensions' ], credentials = data[ 'user' ], title = Conf.getTitle(), theme = theme_name, root_url = Conf.rootURL(), view = view_name, open_app = open_app, debug_level= level)
def web_index(self): # Render base template data = self.getSessionData() url_state = "" if self.request.arguments.has_key("url_state") and len( self.request.arguments["url_state"][0]) > 0: url_state = xss_filter(self.request.arguments["url_state"][0]) view_name = Conf.getTheme() if self.request.arguments.has_key("view") and len( self.request.arguments["view"][0]) > 0: view_name = xss_filter(self.request.arguments["view"][0]) theme_name = "ext-all-gray" if self.request.arguments.has_key("theme") and len( self.request.arguments["theme"][0]) > 0: if self.request.arguments["theme"][0] == "Neptune": theme_name = "ext-all-neptune" if self.request.arguments["theme"][0] == "Classic": theme_name = "ext-all" open_app = "" if self.request.arguments.has_key("open_app") and len( self.request.arguments["open_app"][0]) > 0: open_app = xss_filter( self.request.arguments["open_app"][0].strip()) icon = data['baseURL'] + Conf.getIcon() background = data['baseURL'] + Conf.getBackgroud() logo = data['baseURL'] + Conf.getLogo() welcomeFile = Conf.getWelcome() welcome = '' if welcomeFile: try: with open(welcomeFile, 'r') as f: welcome = f.read().replace('\n', '') except: gLogger.warn('Welcome page not found here: %s' % welcomeFile) level = str(gLogger.getLevel()).lower() self.render("root.tpl", iconUrl=icon, base_url=data['baseURL'], _dev=Conf.devMode(), ext_version=data['extVersion'], url_state=url_state, extensions=data['extensions'], credentials=data['user'], title=Conf.getTitle(), theme=theme_name, root_url=Conf.rootURL(), view=view_name, open_app=open_app, debug_level=level, welcome=welcome, backgroundImage=background, logo=logo)
def __checkPath( self, setup, group, route ): """ Check the request, auth, credentials and DISET config """ if route[-1] == "/": methodName = "index" handlerRoute = route else: iP = route.rfind( "/" ) methodName = route[ iP + 1: ] handlerRoute = route[ :iP ] if not setup: setup = Conf.setup() self.__setup = setup if not self.__auth( handlerRoute, group ): return WErr( 401 ) DN = self.getUserDN() if DN: self.__disetConfig.setDN( DN ) group = self.getUserGroup() if group: self.__disetConfig.setGroup( group ) self.__disetConfig.setSetup( setup ) return WOK( methodName )
def web_index(self): # Render base template data = SessionData().getData() self.render("root.tpl", base_url=data["baseURL"], _dev=Conf.devMode(), ext_version=data['extVersion'])
def __processCredentials( self ): """ Extract the user credentials based on the certificate or what comes from the balancer """ self.__credDict = {} #NGINX if Conf.balancer() == "nginx": headers = self.request.headers if headers[ 'X-Scheme' ] == "https" and headers[ 'X-Ssl_client_verify' ] == 'SUCCESS': DN = headers[ 'X-Ssl_client_s_dn' ] self.__credDict[ 'subject' ] = DN self.__credDict[ 'issuer' ] = headers[ 'X-Ssl_client_i_dn' ] result = Registry.getUsernameForDN( DN ) if not result[ 'OK' ]: self.__credDict[ 'validDN' ] = False else: self.__credDict[ 'validDN' ] = True self.__credDict[ 'username' ] = result[ 'Value' ] return #TORNADO if not self.request.protocol == "https": return derCert = self.request.get_ssl_certificate( binary_form = True ) if not derCert: return pemCert = ssl.DER_cert_to_PEM_cert( derCert ) chain = X509Chain() chain.loadChainFromString( pemCert ) result = chain.getCredentials() if not result[ 'OK' ]: self.log.error( "Could not get client credentials %s" % result[ 'Message' ] ) return self.__credDict = result[ 'Value' ]
def oAuth2(): if self.get_secure_cookie("AccessToken"): access_token = self.get_secure_cookie("AccessToken") url = Conf.getCSValue( "TypeAuths/%s/authority" % typeAuth) + '/userinfo' heads = { 'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/json' } if 'error' in requests.get(url, headers=heads, verify=False).json(): self.log.error('OIDC request error: %s' % requests.get( url, headers=heads, verify=False).json()['error']) return ID = requests.get(url, headers=heads, verify=False).json()['sub'] result = getUsernameForID(ID) if result['OK']: self.__credDict['username'] = result['Value'] result = getDNForUsername(self.__credDict['username']) if result['OK']: self.__credDict['validDN'] = True self.__credDict['DN'] = result['Value'][0] result = getCAForUsername(self.__credDict['username']) if result['OK']: self.__credDict['issuer'] = result['Value'][0] return
def __change( self, setup = None, group = None ): if not setup: setup = self.getUserSetup() if not group: group = self.getUserGroup() or 'anon' url = [ Conf.rootURL().strip( "/" ), "s:%s" % setup, "g:%s" % group ] self.redirect( "/%s" % "/".join( url ) )
def __processCredentials(self): """ Extract the user credentials based on the certificate or what comes from the balancer """ self.__credDict = {} #NGINX if Conf.balancer() == "nginx": headers = self.request.headers if headers['X-Scheme'] == "https" and headers[ 'X-Ssl_client_verify'] == 'SUCCESS': DN = headers['X-Ssl_client_s_dn'] self.__credDict['subject'] = DN self.__credDict['issuer'] = headers['X-Ssl_client_i_dn'] result = Registry.getUsernameForDN(DN) if not result['OK']: self.__credDict['validDN'] = False else: self.__credDict['validDN'] = True self.__credDict['username'] = result['Value'] return #TORNADO if not self.request.protocol == "https": return derCert = self.request.get_ssl_certificate(binary_form=True) if not derCert: return pemCert = ssl.DER_cert_to_PEM_cert(derCert) chain = X509Chain() chain.loadChainFromString(pemCert) result = chain.getCredentials() if not result['OK']: self.log.error("Could not get client credentials %s" % result['Message']) return self.__credDict = result['Value']
def __checkPath(self, setup, group, route): """ Check the request, auth, credentials and DISET config """ if route[-1] == "/": methodName = "index" handlerRoute = route else: iP = route.rfind("/") methodName = route[iP + 1:] handlerRoute = route[:iP] if not setup: setup = Conf.setup() self.__setup = setup if not self.__auth(handlerRoute, group): return WErr(401) DN = self.getUserDN() if DN: self.__disetConfig.setDN(DN) group = self.getUserGroup() if group: self.__disetConfig.setGroup(group) self.__disetConfig.setSetup(setup) return WOK(methodName)
def getData(self): DN = self.__disetConfig.getDN() group = self.__disetConfig.getGroup() credDict = self.__getCredDict(DN, group) data = { 'menu': self.__getGroupMenu(credDict, group), 'user': credDict, 'validGroups': [], 'setup': self.__disetConfig.getSetup() or gConfig.getValue("/DIRAC/Setup", ""), 'validSetups': gConfig.getSections("/DIRAC/Setups")['Value'], 'extensions': self.__extensions, 'extVersion': self.getExtJSVersion() } if 'properties' in credDict: credDict.pop('properties') #Add valid groups if known if DN: result = Registry.getGroupsForDN(DN) if result['OK']: data['validGroups'] = result['Value'] #Calculate baseURL baseURL = [ Conf.rootURL().strip("/"), "s:%s" % data['setup'], "g:%s" % credDict.get('group', 'anon') ] data['baseURL'] = "/%s" % "/".join(baseURL) return data
def __change(self, setup=None, group=None): if not setup: setup = self.getUserSetup() if not group: group = self.getUserGroup() or 'anon' url = [Conf.rootURL().strip("/"), "s:%s" % setup, "g:%s" % group] self.redirect("/%s" % "/".join(url))
def web_sendRequest(self): typeAuth = str(self.request.arguments["typeauth"][0]) loadValue = self.request.arguments["value"] addresses = Conf.getCSValue('AdminsEmails') NotificationClient().sendMail( addresses, subject="Request from %s %s" % (loadValue[0], loadValue[1]), body='Type auth: %s, details: %s' % (typeAuth, loadValue))
def web_getAuthCFG(self): typeAuth = str(self.request.arguments["typeauth"][0]) loadValue = self.request.arguments["value"][0] res = {} if Conf.getCSSections("TypeAuths")['OK']: if typeAuth: if loadValue: if loadValue == 'all': res = Conf.getCSOptionsDict("TypeAuths/%s" % typeAuth).get('Value') else: res = Conf.getCSValue( "TypeAuths/%s/%s" % (typeAuth, loadValue), None) else: res = Conf.getCSOptions("TypeAuths/%s" % typeAuth) else: res = Conf.getCSSections("TypeAuths") self.write(res)
def __isGroupAuthApp( self, appLoc ): handlerLoc = "/".join( List.fromChar( appLoc, "." )[1:] ) if not handlerLoc: return False if handlerLoc not in self.__handlers: gLogger.error( "Handler %s required by %s does not exist!" % ( handlerLoc, appLoc ) ) return False handler = self.__handlers[ handlerLoc ] auth = AuthManager( Conf.getAuthSectionForHandler( handlerLoc ) ) return auth.authQuery( "", dict( self.__credDict ), handler.AUTH_PROPS )
def get( self, setup, group, route ): if self.__action == "addSlash": self.redirect( "%s/" % self.request.uri, permanent = True ) elif self.__action == "sendToRoot": dest = "/" rootURL = Conf.rootURL() if rootURL: dest += "%s/" % rootURL.strip( "/" ) if setup and group: dest += "s:%s/g:%s/" % ( setup, group ) self.redirect( dest )
def __isGroupAuthApp(self, appLoc, credDict): handlerLoc = "/".join(List.fromChar(appLoc, ".")[1:]) if not handlerLoc: return False if handlerLoc not in self.__handlers: gLogger.error("Handler %s required by %s does not exist!" % (handlerLoc, appLoc)) return False handler = self.__handlers[handlerLoc] auth = AuthManager(Conf.getAuthSectionForHandler(handlerLoc)) return auth.authQuery("", credDict, handler.AUTH_PROPS)
def __change(self, setup=None, group=None): if not setup: setup = self.getUserSetup() if not group: group = self.getUserGroup() or 'anon' qs = False if 'Referer' in self.request.headers: o = urlparse.urlparse(self.request.headers['Referer']) qs = '?%s' % o.query url = [Conf.rootURL().strip("/"), "s:%s" % setup, "g:%s" % group] self.redirect("/%s%s" % ("/".join(url), qs))
def run( self ): """ Start web servers """ bu = Conf.rootURL().strip( "/" ) urls = [] for proto, port in self.__servers: urls.append("%s://0.0.0.0:%s/%s/" % ( proto, port, bu ) ) self.log.always( "Listening on %s" % " and ".join( urls ) ) tornado.autoreload.add_reload_hook( self.__reloadAppCB ) tornado.ioloop.IOLoop.instance().start()
def run(self): """ Start web servers """ bu = Conf.rootURL().strip("/") urls = [] for proto, port in self.__servers: urls.append("%s://0.0.0.0:%s/%s/" % (proto, port, bu)) self.log.always("Listening on %s" % " and ".join(urls)) tornado.autoreload.add_reload_hook(self.__reloadAppCB) tornado.ioloop.IOLoop.instance().start()
def __change( self, setup = None, group = None ): if not setup: setup = self.getUserSetup() if not group: group = self.getUserGroup() or 'anon' qs = False if 'Referer' in self.request.headers: o = urlparse.urlparse( self.request.headers[ 'Referer' ] ) qs = '?%s' % o.query url = [ Conf.rootURL().strip( "/" ), "s:%s" % setup, "g:%s" % group ] self.redirect( "/%s%s" % ( "/".join( url ), qs ) )
def get(self, setup, group, route): if self.__action == "addSlash": self.redirect("%s/" % self.request.uri, permanent=True) elif self.__action == "sendToRoot": dest = "/" rootURL = Conf.rootURL() if rootURL: dest += "%s/" % rootURL.strip("/") if setup and group: dest += "s:%s/g:%s/" % (setup, group) self.redirect(dest)
def web_index(self): # Render base template data = self.getSessionData() url_state = "" if self.request.arguments.has_key("url_state") and len(self.request.arguments["url_state"][0]) > 0: url_state = self.request.arguments["url_state"][0] view_name = "desktop" if self.request.arguments.has_key("view") and len(self.request.arguments["view"][0]) > 0: view_name = self.request.arguments["view"][0] theme_name = "ext-all-gray" if self.request.arguments.has_key("theme") and len(self.request.arguments["theme"][0]) > 0: if self.request.arguments["theme"][0] == "Neptune": theme_name = "ext-all-neptune" if self.request.arguments["theme"][0] == "Classic": theme_name = "ext-all" open_app = "" if self.request.arguments.has_key("open_app") and len(self.request.arguments["open_app"][0]) > 0: open_app = self.request.arguments["open_app"][0].strip() self.render( "root.tpl", base_url=data["baseURL"], _dev=Conf.devMode(), ext_version=data["extVersion"], url_state=url_state, extensions=data["extensions"], credentials=data["user"], title=Conf.getTitle(), theme=theme_name, root_url=Conf.rootURL(), view=view_name, open_app=open_app, )
def __init__(self, *args, **kwargs): """ Initialize the handler """ super(WebHandler, self).__init__(*args, **kwargs) if not WebHandler.__log: WebHandler.__log = gLogger.getSubLogger(self.__class__.__name__) self.__credDict = {} self.__setup = Conf.setup() self.__processCredentials() self.__disetConfig.reset() self.__disetConfig.setDecorator(self.__disetBlockDecor) self.__disetDump = self.__disetConfig.dump() match = self.PATH_RE.match(self.request.path) self._pathResult = self.__checkPath(*match.groups()) self.__sessionData = SessionData(self.__credDict, self.__setup)
def __init__( self, *args, **kwargs ): """ Initialize the handler """ super( WebHandler, self ).__init__( *args, **kwargs ) if not WebHandler.__log: WebHandler.__log = gLogger.getSubLogger( self.__class__.__name__ ) self.__credDict = {} self.__setup = Conf.setup() self.__processCredentials() self.__disetConfig.reset() self.__disetConfig.setDecorator( self.__disetBlockDecor ) self.__disetDump = self.__disetConfig.dump() match = self.PATH_RE.match( self.request.path ) self._pathResult = self.__checkPath( *match.groups() ) self.__sessionData = SessionData( self.__credDict, self.__setup )
def __auth(self, handlerRoute, group): """ Authenticate request """ userDN = self.getUserDN() if group: self.__credDict['group'] = group else: if userDN: result = Registry.findDefaultGroupForDN(userDN) if result['OK']: self.__credDict['group'] = result['Value'] auth = AuthManager(Conf.getAuthSectionForHandler(handlerRoute)) ok = auth.authQuery("", self.__credDict, self.AUTH_PROPS) if ok and userDN: self.__credDict['validGroup'] = True return ok
def __auth( self, handlerRoute, group ): """ Authenticate request """ userDN = self.getUserDN() if group: self.__credDict[ 'group' ] = group else: if userDN: result = Registry.findDefaultGroupForDN( userDN ) if result[ 'OK' ]: self.__credDict[ 'group' ] = result[ 'Value' ] auth = AuthManager( Conf.getAuthSectionForHandler( handlerRoute ) ) ok = auth.authQuery( "", self.__credDict, self.AUTH_PROPS ) if ok and userDN: self.__credDict[ 'validGroup' ] = True return ok
def web_index(self): # Render base template data = self.getSessionData() url_state = "" if self.request.arguments.has_key("url_state") and len(self.request.arguments["url_state"][0]) > 0: url_state = xss_filter( self.request.arguments["url_state"][0] ) view_name = Conf.getTheme() if self.request.arguments.has_key("view") and len(self.request.arguments["view"][0]) > 0: view_name = xss_filter( self.request.arguments["view"][0] ) theme_name = "ext-all-gray" if self.request.arguments.has_key("theme") and len(self.request.arguments["theme"][0]) > 0: if self.request.arguments["theme"][0]=="Neptune": theme_name = "ext-all-neptune" if self.request.arguments["theme"][0]=="Classic": theme_name = "ext-all" open_app = "" if self.request.arguments.has_key("open_app") and len(self.request.arguments["open_app"][0]) > 0: open_app = xss_filter( self.request.arguments["open_app"][0].strip() ) icon = data[ 'baseURL' ] + Conf.getIcon() background = data[ 'baseURL' ] + Conf.getBackgroud() logo = data[ 'baseURL' ] + Conf.getLogo() welcomeFile = Conf.getWelcome() welcome = '' if welcomeFile: try: with open(welcomeFile, 'r') as f: welcome = f.read().replace('\n', '') except: gLogger.warn('Welcome page not found here: %s' % welcomeFile) level = str(gLogger.getLevel()).lower() self.render( "root.tpl", iconUrl=icon, base_url = data[ 'baseURL' ], _dev = Conf.devMode(), ext_version = data[ 'extVersion' ], url_state = url_state, extensions = data[ 'extensions' ], credentials = data[ 'user' ], title = Conf.getTitle(), theme = theme_name, root_url = Conf.rootURL(), view = view_name, open_app = open_app, debug_level = level, welcome = welcome, backgroundImage = background, logo = logo )
def get( self, setup, group, route ): if self.__action == "addSlash": o = urlparse.urlparse( self.request.uri ) proto = self.request.protocol if 'X-Scheme' in self.request.headers: proto = self.request.headers[ 'X-Scheme' ] nurl = "%s://%s%s/" % ( proto, self.request.host, o.path ) if o.query: nurl = "%s?%s" % ( nurl, o.query ) self.redirect( nurl, permanent = True ) elif self.__action == "sendToRoot": dest = "/" rootURL = Conf.rootURL() if rootURL: dest += "%s/" % rootURL.strip( "/" ) if setup and group: dest += "s:%s/g:%s/" % ( setup, group ) self.redirect( dest )
def get(self, setup, group, route): if self.__action == "addSlash": o = urlparse.urlparse(self.request.uri) proto = self.request.protocol if 'X-Scheme' in self.request.headers: proto = self.request.headers['X-Scheme'] nurl = "%s://%s%s/" % (proto, self.request.host, o.path) if o.query: nurl = "%s?%s" % (nurl, o.query) self.redirect(nurl, permanent=True) elif self.__action == "sendToRoot": dest = "/" rootURL = Conf.rootURL() if rootURL: dest += "%s/" % rootURL.strip("/") if setup and group: dest += "s:%s/g:%s/" % (setup, group) self.redirect(dest)
def __isGroupAuthApp( self, appLoc ): """ The method checks if the application is authorized for a certain user group :param str appLoc It is the application name for example: DIRAC.JobMonitor :return bool if the handler is authorized to the user returns True otherwise False """ handlerLoc = "/".join( List.fromChar( appLoc, "." )[1:] ) if not handlerLoc: gLogger.error( "Application handler does not exists:", appLoc ) return False if handlerLoc not in self.__handlers: gLogger.error( "Handler %s required by %s does not exist!" % ( handlerLoc, appLoc ) ) return False handler = self.__handlers[ handlerLoc ] auth = AuthManager( Conf.getAuthSectionForHandler( handlerLoc ) ) gLogger.info( "Authorization: %s -> %s" % ( dict( self.__credDict ), handler.AUTH_PROPS ) ) return auth.authQuery( "", dict( self.__credDict ), handler.AUTH_PROPS )
def getData( self ): data = { 'menu' : self.__getGroupMenu(), 'user' : self.__credDict, 'validGroups' : [], 'setup' : self.__setup, 'validSetups' : gConfig.getSections( "/DIRAC/Setups" )[ 'Value' ], 'extensions' : self.__extensions, 'extVersion' : self.getExtJSVersion() } #Add valid groups if known DN = self.__credDict.get( "DN", "" ) if DN: result = Registry.getGroupsForDN( DN ) if result[ 'OK' ]: data[ 'validGroups' ] = result[ 'Value' ] #Calculate baseURL baseURL = [ Conf.rootURL().strip( "/" ), "s:%s" % data[ 'setup' ], "g:%s" % self.__credDict.get( 'group', '' ) ] data[ 'baseURL' ] = "/%s" % "/".join( baseURL ) return data
def oAuth2(): if self.get_secure_cookie("AccessToken"): access_token = self.get_secure_cookie("AccessToken") url = Conf.getCSValue("TypeAuths/%s/authority" % typeAuth) + '/userinfo' heads = {'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/json'} if 'error' in requests.get(url, headers=heads, verify=False).json(): self.log.error('OIDC request error: %s' % requests.get(url, headers=heads, verify=False).json()['error']) return ID = requests.get(url, headers=heads, verify=False).json()['sub'] result = getUsernameForID(ID) if result['OK']: self.__credDict['username'] = result['Value'] result = getDNForUsername(self.__credDict['username']) if result['OK']: self.__credDict['validDN'] = True self.__credDict['DN'] = result['Value'][0] result = getCAForUsername(self.__credDict['username']) if result['OK']: self.__credDict['issuer'] = result['Value'][0] return
def __auth(self, handlerRoute, group, method): """ Authenticate request :param str handlerRoute: the name of the handler :param str group: DIRAC group :param str method: the name of the method :return: bool """ userDN = self.getUserDN() if group: self.__credDict['group'] = group else: if userDN: result = Registry.findDefaultGroupForDN(userDN) if result['OK']: self.__credDict['group'] = result['Value'] self.__credDict['validGroup'] = False if type(self.AUTH_PROPS) not in (types.ListType, types.TupleType): self.AUTH_PROPS = [ p.strip() for p in self.AUTH_PROPS.split(",") if p.strip() ] auth = AuthManager(Conf.getAuthSectionForHandler(handlerRoute)) ok = auth.authQuery(method, self.__credDict, self.AUTH_PROPS) if ok: if userDN: self.__credDict['validGroup'] = True self.log.info("AUTH OK: %s by %s@%s (%s)" % (handlerRoute, self.__credDict['username'], self.__credDict['group'], userDN)) else: self.__credDict['validDN'] = False self.log.info("AUTH OK: %s by visitor" % (handlerRoute)) elif self.isTrustedHost(self.__credDict.get('DN')): self.log.info("Request is coming from Trusted host") return True else: self.log.info("AUTH KO: %s by %s@%s" % (handlerRoute, userDN, group)) return ok
def __auth(self, handlerRoute, group): """ Authenticate request """ userDN = self.getUserDN() if group: self.__credDict['group'] = group else: if userDN: result = Registry.findDefaultGroupForDN(userDN) if result['OK']: self.__credDict['group'] = result['Value'] self.__credDict['validGroup'] = False if type(self.AUTH_PROPS) not in (types.ListType, types.TupleType): self.AUTH_PROPS = [ p.strip() for p in self.AUTH_PROPS.split(",") if p.strip() ] allAllowed = False for p in self.AUTH_PROPS: if p.lower() in ('all', 'any'): allAllowed = True auth = AuthManager(Conf.getAuthSectionForHandler(handlerRoute)) ok = auth.authQuery("", self.__credDict, self.AUTH_PROPS) if ok: if userDN: self.__credDict['validGroup'] = True self.log.info("AUTH OK: %s by %s@%s (%s)" % (handlerRoute, self.__credDict['username'], self.__credDict['group'], userDN)) else: self.__credDict['validDN'] = False self.log.info("AUTH OK: %s by visitor" % (handlerRoute)) elif allAllowed: self.log.info("AUTH ALL: %s by %s" % (handlerRoute, userDN)) ok = True else: self.log.info("AUTH KO: %s by %s@%s" % (handlerRoute, userDN, group)) return ok
def __auth( self, handlerRoute, methodName, group ): """ Authenticate request """ userDN = self.getUserDN() if group: self.__credDict[ 'group' ] = group else: if userDN: result = Registry.findDefaultGroupForDN( userDN ) if result[ 'OK' ]: self.__credDict[ 'group' ] = result[ 'Value' ] auth = AuthManager( Conf.getAuthSectionForRoute( handlerRoute ) ) try: defProps = getattr( self, "auth_%s" % methodName ) except AttributeError: defProps = [ 'all' ] ok = auth.authQuery( methodName, self.__credDict, defProps ) if ok and userDN: self.__credDict[ 'validGroup' ] = True return ok
def __auth(self, handlerRoute, methodName, group): """ Authenticate request """ userDN = self.getUserDN() if group: self.__credDict['group'] = group else: if userDN: result = Registry.findDefaultGroupForDN(userDN) if result['OK']: self.__credDict['group'] = result['Value'] auth = AuthManager(Conf.getAuthSectionForRoute(handlerRoute)) try: defProps = getattr(self, "auth_%s" % methodName) except AttributeError: defProps = ['all'] ok = auth.authQuery(methodName, self.__credDict, defProps) if ok and userDN: self.__credDict['validGroup'] = True return ok
def __isGroupAuthApp(self, appLoc): """ The method checks if the application is authorized for a certain user group :param str appLoc It is the application name for example: DIRAC.JobMonitor :return bool if the handler is authorized to the user returns True otherwise False """ handlerLoc = "/".join(List.fromChar(appLoc, ".")[1:]) if not handlerLoc: gLogger.error("Application handler does not exists:", appLoc) return False if handlerLoc not in self.__handlers: gLogger.error("Handler %s required by %s does not exist!" % (handlerLoc, appLoc)) return False handler = self.__handlers[handlerLoc] auth = AuthManager(Conf.getAuthSectionForHandler(handlerLoc)) gLogger.info("Authorization: %s -> %s" % (dict(self.__credDict), handler.AUTH_PROPS)) return auth.authQuery("", dict(self.__credDict), handler.AUTH_PROPS)
def bootstrap( self ): """ Configure and create web app """ self.log.always( "\n ====== Starting DIRAC web app ====== \n" ) #Load required CFG files self.__loadWebAppCFGFiles() #Debug mode? devMode = Conf.devMode() if devMode: self.log.info( "Configuring in developer mode..." ) #Calculating routes result = self.__handlerMgr.getRoutes() if not result[ 'OK' ]: return result routes = result[ 'Value' ] #Initialize the session data SessionData.setHandlers( self.__handlerMgr.getHandlers()[ 'Value' ] ) #Create the app tLoader = TemplateLoader( self.__handlerMgr.getPaths( "template" ) ) kw = dict( devMode = devMode, template_loader = tLoader, cookie_secret = Conf.cookieSecret(), log_function = self._logRequest ) #Check processes if we're under a load balancert if Conf.balancer() and Conf.numProcesses() not in ( 0, 1 ): tornado.process.fork_processes( Conf.numProcesses(), max_restarts=0 ) kw[ 'devMode' ] = False #Configure tornado app self.__app = tornado.web.Application( routes, **kw ) self.log.notice( "Configuring HTTP on port %s" % ( Conf.HTTPPort() ) ) #Create the web servers srv = tornado.httpserver.HTTPServer( self.__app ) port = Conf.HTTPPort() srv.listen( port ) self.__servers[ ( 'http', port ) ] = srv if Conf.HTTPS(): self.log.notice( "Configuring HTTPS on port %s" % Conf.HTTPSPort() ) sslops = dict( certfile = Conf.HTTPSCert(), keyfile = Conf.HTTPSKey(), cert_reqs = ssl.CERT_OPTIONAL, ca_certs = Conf.generateCAFile() ) self.log.debug( " - %s" % "\n - ".join( [ "%s = %s" % ( k, sslops[k] ) for k in sslops ] ) ) srv = tornado.httpserver.HTTPServer( self.__app, ssl_options = sslops ) port = Conf.HTTPSPort() srv.listen( port ) self.__servers[ ( 'https', port ) ] = srv return result
def __auth(self, handlerRoute, group, method): """ Authenticate request :param str handlerRoute: the name of the handler :param str group: DIRAC group :param str method: the name of the method :return: bool """ userDN = self.getUserDN() if group: self.__credDict['group'] = group else: if userDN: result = Registry.findDefaultGroupForDN(userDN) if result['OK']: self.__credDict['group'] = result['Value'] self.__credDict['validGroup'] = False if type(self.AUTH_PROPS) not in (types.ListType, types.TupleType): self.AUTH_PROPS = [p.strip() for p in self.AUTH_PROPS.split(",") if p.strip()] auth = AuthManager(Conf.getAuthSectionForHandler(handlerRoute)) ok = auth.authQuery(method, self.__credDict, self.AUTH_PROPS) if ok: if userDN: self.__credDict['validGroup'] = True self.log.info("AUTH OK: %s by %s@%s (%s)" % (handlerRoute, self.__credDict['username'], self.__credDict['group'], userDN)) else: self.__credDict['validDN'] = False self.log.info("AUTH OK: %s by visitor" % (handlerRoute)) elif self.isTrustedHost(self.__credDict.get('DN')): self.log.info("Request is coming from Trusted host") return True else: self.log.info("AUTH KO: %s by %s@%s" % (handlerRoute, userDN, group)) return ok
def getData( self ): DN = self.__disetConfig.getDN() group = self.__disetConfig.getGroup() credDict = self.__getCredDict( DN, group ) data = { 'menu' : self.__getGroupMenu( credDict, group ), 'user' : credDict, 'validGroups' : [], 'setup' : self.__disetConfig.getSetup() or gConfig.getValue( "/DIRAC/Setup", "" ), 'validSetups' : gConfig.getSections( "/DIRAC/Setups" )[ 'Value' ], 'extensions' : self.__extensions, 'extVersion' : self.getExtJSVersion() } if 'properties' in credDict: credDict.pop( 'properties' ) #Add valid groups if known if DN: result = Registry.getGroupsForDN( DN ) if result[ 'OK' ]: data[ 'validGroups' ] = result[ 'Value' ] #Calculate baseURL baseURL = [ Conf.rootURL().strip( "/" ), "s:%s" % data[ 'setup' ], "g:%s" % credDict.get( 'group', 'anon' ) ] data[ 'baseURL' ] = "/%s" % "/".join( baseURL ) return data
def __auth( self, handlerRoute, group ): """ Authenticate request """ userDN = self.getUserDN() if group: self.__credDict[ 'group' ] = group else: if userDN: result = Registry.findDefaultGroupForDN( userDN ) if result[ 'OK' ]: self.__credDict[ 'group' ] = result[ 'Value' ] self.__credDict[ 'validGroup' ] = False if type( self.AUTH_PROPS ) not in ( types.ListType, types.TupleType ): self.AUTH_PROPS = [ p.strip() for p in self.AUTH_PROPS.split( "," ) if p.strip() ] allAllowed = False for p in self.AUTH_PROPS: if p.lower() in ( 'all', 'any' ): allAllowed = True auth = AuthManager( Conf.getAuthSectionForHandler( handlerRoute ) ) ok = auth.authQuery( "", self.__credDict, self.AUTH_PROPS ) if ok: if userDN: self.__credDict[ 'validGroup' ] = True self.log.info( "AUTH OK: %s by %s@%s (%s)" % ( handlerRoute, self.__credDict[ 'username' ], self.__credDict[ 'group' ], userDN ) ) else: self.__credDict[ 'validDN' ] = False self.log.info( "AUTH OK: %s by visitor" % ( handlerRoute ) ) elif allAllowed: self.log.info( "AUTH ALL: %s by %s" % ( handlerRoute, userDN ) ) ok = True else: self.log.info( "AUTH KO: %s by %s@%s" % ( handlerRoute, userDN, group ) ) return ok
def getData(self): data = { 'menu': self.__getGroupMenu(), 'user': self.__credDict, 'validGroups': [], 'setup': self.__setup, 'validSetups': gConfig.getSections("/DIRAC/Setups")['Value'], 'extensions': self.__extensions, 'extVersion': self.getExtJSVersion() } #Add valid groups if known DN = self.__credDict.get("DN", "") if DN: result = Registry.getGroupsForDN(DN) if result['OK']: data['validGroups'] = result['Value'] #Calculate baseURL baseURL = [ Conf.rootURL().strip("/"), "s:%s" % data['setup'], "g:%s" % self.__credDict.get('group', '') ] data['baseURL'] = "/%s" % "/".join(baseURL) return data
def bootstrap( self ): """ Configure and create web app """ self.log.always( "\n ====== Starting DIRAC web app ====== \n" ) # Load required CFG files if not self._loadDefaultWebCFG(): # if we have a web.cfg under etc directory we use it, otherwise we use the configuration file defined by the developer self._loadWebAppCFGFiles() # Calculating routes result = self.__handlerMgr.getRoutes() if not result[ 'OK' ]: return result routes = result[ 'Value' ] # Initialize the session data SessionData.setHandlers( self.__handlerMgr.getHandlers()[ 'Value' ] ) # Create the app tLoader = TemplateLoader( self.__handlerMgr.getPaths( "template" ) ) kw = dict( debug = Conf.devMode(), template_loader = tLoader, cookie_secret = Conf.cookieSecret(), log_function = self._logRequest, autoreload = Conf.numProcesses() < 2 ) #please do no move this lines. The lines must be before the fork_processes signal.signal(signal.SIGTERM, self.stopChildProcesses) signal.signal(signal.SIGINT, self.stopChildProcesses) # Check processes if we're under a load balancert if Conf.balancer() and Conf.numProcesses() not in ( 0, 1 ): tornado.process.fork_processes( Conf.numProcesses(), max_restarts = 0 ) kw[ 'debug' ] = False # Debug mode? if kw[ 'debug' ]: self.log.info( "Configuring in developer mode..." ) # Configure tornado app self.__app = tornado.web.Application( routes, **kw ) self.log.notice( "Configuring HTTP on port %s" % ( Conf.HTTPPort() ) ) # Create the web servers srv = tornado.httpserver.HTTPServer( self.__app, xheaders = True ) port = Conf.HTTPPort() srv.listen( port ) self.__servers[ ( 'http', port ) ] = srv Conf.generateRevokedCertsFile() # it is used by nginx.... if Conf.HTTPS(): self.log.notice( "Configuring HTTPS on port %s" % Conf.HTTPSPort() ) sslops = dict( certfile = Conf.HTTPSCert(), keyfile = Conf.HTTPSKey(), cert_reqs = ssl.CERT_OPTIONAL, ca_certs = Conf.generateCAFile(), ssl_version = ssl.PROTOCOL_TLSv1 ) sslprotocol = str( Conf.SSLProrocol() ) aviableProtocols = [ i for i in dir( ssl ) if i.find( 'PROTOCOL' ) == 0] if sslprotocol and sslprotocol != "": if ( sslprotocol in aviableProtocols ): sslops['ssl_version'] = getattr( ssl, sslprotocol ) else: message = "%s protocol is not provided. The following protocols are provided: %s" % ( sslprotocol, str( aviableProtocols ) ) gLogger.warn( message ) self.log.debug( " - %s" % "\n - ".join( [ "%s = %s" % ( k, sslops[k] ) for k in sslops ] ) ) srv = tornado.httpserver.HTTPServer( self.__app, ssl_options = sslops, xheaders = True ) port = Conf.HTTPSPort() srv.listen( port ) self.__servers[ ( 'https', port ) ] = srv else: #when NGINX is used then the Conf.HTTPS return False, it means tornado does not have to be configured using 443 port Conf.generateCAFile() # if we use Nginx we have to generate the cas as well... return result
def __calculateRoutes( self ): """ Load all handlers and generate the routes """ ol = ObjectLoader() origin = "WebApp.handler" result = ol.getObjects( origin, parentClass = WebHandler, recurse = True ) if not result[ 'OK' ]: return result self.__handlers = result[ 'Value' ] staticPaths = self.getPaths( "static" ) self.log.verbose( "Static paths found:\n - %s" % "\n - ".join( staticPaths ) ) self.__routes = [] # Add some standard paths for static files statDirectories = [ 'defaults', 'demo' ] + Conf.getStaticDirs() self.log.info( "The following static directories are used:%s" % str( statDirectories ) ) for stdir in statDirectories: pattern = '/%s/(.*)' % stdir self.__routes.append( ( pattern, StaticHandler, dict( pathList = ['%s/webRoot/www/%s' % ( rootPath, stdir ) ] ) ) ) self.log.debug( " - Static route: %s" % pattern ) for pattern in ( ( r"/static/(.*)", r"/(favicon\.ico)", r"/(robots\.txt)" ) ): pattern = r"%s%s" % ( self.__shySetupGroupRE, pattern ) if self.__baseURL: pattern = "/%s%s" % ( self.__baseURL, pattern ) self.__routes.append( ( pattern, StaticHandler, dict( pathList = staticPaths ) ) ) self.log.debug( " - Static route: %s" % pattern ) for hn in self.__handlers: self.log.info( "Found handler %s" % hn ) handler = self.__handlers[ hn ] #CHeck it has AUTH_PROPS if type( handler.AUTH_PROPS ) == None: return S_ERROR( "Handler %s does not have AUTH_PROPS defined. Fix it!" % hn ) #Get the root for the handler if handler.LOCATION: handlerRoute = handler.LOCATION.strip( "/") else: handlerRoute = hn[ len( origin ): ].replace( ".", "/" ).replace( "Handler", "" ) #Add the setup group RE before baseRoute = self.__setupGroupRE #IF theres a base url like /DIRAC add it if self.__baseURL: baseRoute = "/%s%s" % ( self.__baseURL, baseRoute ) #Set properly the LOCATION after calculating where it is with helpers to add group and setup later handler.LOCATION = handlerRoute handler.PATH_RE = re.compile( "%s(%s/.*)" % ( baseRoute, handlerRoute ) ) handler.URLSCHEMA = "/%s%%(setup)s%%(group)s%%(location)s/%%(action)s" % ( self.__baseURL ) if issubclass( handler, WebSocketHandler ): handler.PATH_RE = re.compile( "%s(%s)" % ( baseRoute, handlerRoute ) ) route = "%s(%s)" % ( baseRoute, handlerRoute ) self.__routes.append( ( route, handler ) ) self.log.verbose( " - WebSocket %s -> %s" % ( handlerRoute, hn ) ) self.log.debug( " * %s" % route ) continue #Look for methods that are exported for mName, mObj in inspect.getmembers( handler ): if inspect.ismethod( mObj ) and mName.find( "web_" ) == 0: if mName == "web_index": #Index methods have the bare url self.log.verbose( " - Route %s -> %s.web_index" % ( handlerRoute, hn ) ) route = "%s(%s/)" % ( baseRoute, handlerRoute ) self.__routes.append( ( route, handler ) ) self.__routes.append( ( "%s(%s)" % ( baseRoute, handlerRoute ), CoreHandler, dict( action = 'addSlash' ) ) ) else: #Normal methods get the method appended without web_ self.log.verbose( " - Route %s/%s -> %s.%s" % ( handlerRoute, mName[4:], hn, mName ) ) route = "%s(%s/%s)" % ( baseRoute, handlerRoute, mName[4:] ) self.__routes.append( ( route, handler ) ) self.log.debug( " * %s" % route ) #Send to root self.__routes.append( ( "%s(/?)" % self.__setupGroupRE, CoreHandler, dict( action = "sendToRoot" ) ) ) if self.__baseURL: self.__routes.append( ( "/%s%s()" % ( self.__baseURL, self.__setupGroupRE ), CoreHandler, dict( action = "sendToRoot" ) ) ) return S_OK()
def __processCredentials(self): """ Extract the user credentials based on the certificate or what comes from the balancer """ if not self.request.protocol == "https": return # OIDC auth method def oAuth2(): if self.get_secure_cookie("AccessToken"): access_token = self.get_secure_cookie("AccessToken") url = Conf.getCSValue( "TypeAuths/%s/authority" % typeAuth) + '/userinfo' heads = { 'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/json' } if 'error' in requests.get(url, headers=heads, verify=False).json(): self.log.error('OIDC request error: %s' % requests.get( url, headers=heads, verify=False).json()['error']) return ID = requests.get(url, headers=heads, verify=False).json()['sub'] result = getUsernameForID(ID) if result['OK']: self.__credDict['username'] = result['Value'] result = getDNForUsername(self.__credDict['username']) if result['OK']: self.__credDict['validDN'] = True self.__credDict['DN'] = result['Value'][0] result = getCAForUsername(self.__credDict['username']) if result['OK']: self.__credDict['issuer'] = result['Value'][0] return # Type of Auth if not self.get_secure_cookie("TypeAuth"): self.set_secure_cookie("TypeAuth", 'Certificate') typeAuth = self.get_secure_cookie("TypeAuth") self.log.info("Type authentication: %s" % str(typeAuth)) if typeAuth == "Visitor": return retVal = Conf.getCSSections("TypeAuths") if retVal['OK']: if typeAuth in retVal.get("Value"): method = Conf.getCSValue("TypeAuths/%s/method" % typeAuth, 'default') if method == "oAuth2": oAuth2() # NGINX if Conf.balancer() == "nginx": headers = self.request.headers if headers['X-Scheme'] == "https" and headers[ 'X-Ssl_client_verify'] == 'SUCCESS': DN = headers['X-Ssl_client_s_dn'] if not DN.startswith('/'): items = DN.split(',') items.reverse() DN = '/' + '/'.join(items) self.__credDict['DN'] = DN self.__credDict['issuer'] = headers['X-Ssl_client_i_dn'] result = Registry.getUsernameForDN(DN) if not result['OK']: self.__credDict['validDN'] = False else: self.__credDict['validDN'] = True self.__credDict['username'] = result['Value'] return # TORNADO derCert = self.request.get_ssl_certificate(binary_form=True) if not derCert: return pemCert = ssl.DER_cert_to_PEM_cert(derCert) chain = X509Chain() chain.loadChainFromString(pemCert) result = chain.getCredentials() if not result['OK']: self.log.error("Could not get client credentials %s" % result['Message']) return self.__credDict = result['Value'] # Hack. Data coming from OSSL directly and DISET difer in DN/subject try: self.__credDict['DN'] = self.__credDict['subject'] except KeyError: pass
def __processCredentials(self): """ Extract the user credentials based on the certificate or what comes from the balancer """ if not self.request.protocol == "https": return # OIDC auth method def oAuth2(): if self.get_secure_cookie("AccessToken"): access_token = self.get_secure_cookie("AccessToken") url = Conf.getCSValue("TypeAuths/%s/authority" % typeAuth) + '/userinfo' heads = {'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/json'} if 'error' in requests.get(url, headers=heads, verify=False).json(): self.log.error('OIDC request error: %s' % requests.get(url, headers=heads, verify=False).json()['error']) return ID = requests.get(url, headers=heads, verify=False).json()['sub'] result = getUsernameForID(ID) if result['OK']: self.__credDict['username'] = result['Value'] result = getDNForUsername(self.__credDict['username']) if result['OK']: self.__credDict['validDN'] = True self.__credDict['DN'] = result['Value'][0] result = getCAForUsername(self.__credDict['username']) if result['OK']: self.__credDict['issuer'] = result['Value'][0] return # Type of Auth if not self.get_secure_cookie("TypeAuth"): self.set_secure_cookie("TypeAuth", 'Certificate') typeAuth = self.get_secure_cookie("TypeAuth") self.log.info("Type authentication: %s" % str(typeAuth)) if typeAuth == "Visitor": return retVal = Conf.getCSSections("TypeAuths") if retVal['OK']: if typeAuth in retVal.get("Value"): method = Conf.getCSValue("TypeAuths/%s/method" % typeAuth, 'default') if method == "oAuth2": oAuth2() # NGINX if Conf.balancer() == "nginx": headers = self.request.headers if headers['X-Scheme'] == "https" and headers['X-Ssl_client_verify'] == 'SUCCESS': DN = headers['X-Ssl_client_s_dn'] if not DN.startswith('/'): items = DN.split(',') items.reverse() DN = '/' + '/'.join(items) self.__credDict['DN'] = DN self.__credDict['issuer'] = headers['X-Ssl_client_i_dn'] result = Registry.getUsernameForDN(DN) if not result['OK']: self.__credDict['validDN'] = False else: self.__credDict['validDN'] = True self.__credDict['username'] = result['Value'] return # TORNADO derCert = self.request.get_ssl_certificate(binary_form=True) if not derCert: return pemCert = ssl.DER_cert_to_PEM_cert(derCert) chain = X509Chain() chain.loadChainFromString(pemCert) result = chain.getCredentials() if not result['OK']: self.log.error("Could not get client credentials %s" % result['Message']) return self.__credDict = result['Value'] # Hack. Data coming from OSSL directly and DISET difer in DN/subject try: self.__credDict['DN'] = self.__credDict['subject'] except KeyError: pass
def bootstrap( self ): """ Configure and create web app """ self.log.always( "\n ====== Starting DIRAC web app ====== \n" ) debug = Conf.debug() if debug: self.log.info( "Configuring in debug mode..." ) #Calculating routes result = self.__routes.getRoutes() if not result[ 'OK' ]: return result routes = result[ 'Value' ] #Create the app tLoader = TemplateLoader( self.__routes.getPaths( "template" ) ) kw = dict( debug = debug, template_loader = tLoader, cookie_secret = Conf.cookieSecret(), log_function = self._logRequest ) #Check processes if we're under a load balancert if Conf.balancer() and Conf.numProcesses() not in ( 0, 1 ): tornado.process.fork_processes( Conf.numProcesses(), max_restarts=0 ) kw[ 'debug' ] = False #Configure tornado app self.__app = tornado.web.Application( routes, **kw ) self.log.notice( "Configuring HTTP on port %s" % ( Conf.HTTPPort() ) ) #Create the web servers srv = tornado.httpserver.HTTPServer( self.__app ) port = Conf.HTTPPort() srv.listen( port ) self.__servers[ ( 'http', port ) ] = srv if Conf.HTTPS(): self.log.notice( "Configuring HTTPS on port %s" % Conf.HTTPSPort() ) sslops = dict( certfile = Conf.HTTPSCert(), keyfile = Conf.HTTPSKey(), cert_reqs = ssl.CERT_OPTIONAL, ca_certs = Conf.generateCAFile() ) self.log.debug( " - %s" % "\n - ".join( [ "%s = %s" % ( k, sslops[k] ) for k in sslops ] ) ) srv = tornado.httpserver.HTTPServer( self.__app, ssl_options = sslops ) port = Conf.HTTPSPort() srv.listen( port ) self.__servers[ ( 'https', port ) ] = srv return result
def __init__( self ): self.__routes = Routes( Conf.rootURL() ) self.__servers = {} self.log = gLogger.getSubLogger( "Web" )
def bootstrap(self): """ Configure and create web app """ self.log.always("\n ====== Starting DIRAC web app ====== \n") # Load required CFG files if not self._loadDefaultWebCFG( ): # if we have a web.cfg under etc directory we use it, otherwise we use the configuration file defined by the developer self._loadWebAppCFGFiles() # Calculating routes result = self.__handlerMgr.getRoutes() if not result['OK']: return result routes = result['Value'] # Initialize the session data SessionData.setHandlers(self.__handlerMgr.getHandlers()['Value']) # Create the app tLoader = TemplateLoader(self.__handlerMgr.getPaths("template")) kw = dict(debug=Conf.devMode(), template_loader=tLoader, cookie_secret=Conf.cookieSecret(), log_function=self._logRequest, autoreload=Conf.numProcesses() < 2) #please do no move this lines. The lines must be before the fork_processes signal.signal(signal.SIGTERM, self.stopChildProcesses) signal.signal(signal.SIGINT, self.stopChildProcesses) # Check processes if we're under a load balancert if Conf.balancer() and Conf.numProcesses() not in (0, 1): tornado.process.fork_processes(Conf.numProcesses(), max_restarts=0) kw['debug'] = False # Debug mode? if kw['debug']: self.log.info("Configuring in developer mode...") # Configure tornado app self.__app = tornado.web.Application(routes, **kw) self.log.notice("Configuring HTTP on port %s" % (Conf.HTTPPort())) # Create the web servers srv = tornado.httpserver.HTTPServer(self.__app, xheaders=True) port = Conf.HTTPPort() srv.listen(port) self.__servers[('http', port)] = srv Conf.generateRevokedCertsFile() # it is used by nginx.... if Conf.HTTPS(): self.log.notice("Configuring HTTPS on port %s" % Conf.HTTPSPort()) sslops = dict(certfile=Conf.HTTPSCert(), keyfile=Conf.HTTPSKey(), cert_reqs=ssl.CERT_OPTIONAL, ca_certs=Conf.generateCAFile(), ssl_version=ssl.PROTOCOL_TLSv1) sslprotocol = str(Conf.SSLProrocol()) aviableProtocols = [i for i in dir(ssl) if i.find('PROTOCOL') == 0] if sslprotocol and sslprotocol != "": if (sslprotocol in aviableProtocols): sslops['ssl_version'] = getattr(ssl, sslprotocol) else: message = "%s protocol is not provided. The following protocols are provided: %s" % ( sslprotocol, str(aviableProtocols)) gLogger.warn(message) self.log.debug( " - %s" % "\n - ".join(["%s = %s" % (k, sslops[k]) for k in sslops])) srv = tornado.httpserver.HTTPServer(self.__app, ssl_options=sslops, xheaders=True) port = Conf.HTTPSPort() srv.listen(port) self.__servers[('https', port)] = srv else: #when NGINX is used then the Conf.HTTPS return False, it means tornado does not have to be configured using 443 port Conf.generateCAFile( ) # if we use Nginx we have to generate the cas as well... return result
def __init__(self): self.__handlerMgr = HandlerMgr(Conf.rootURL()) self.__servers = {} self.log = gLogger.getSubLogger("Web")
def web_index(self): # Render base template data = SessionData().getData() self.render( "root.tpl", base_url = data["baseURL"], _dev = Conf.devMode(), ext_version = data[ 'extVersion' ] )
def __init__( self ): self.__handlerMgr = HandlerMgr( Conf.rootURL() ) self.__servers = {} self.log = gLogger.getSubLogger( "Web" )
def __calculateRoutes(self): """ Load all handlers and generate the routes """ ol = ObjectLoader() origin = "WebApp.handler" result = ol.getObjects(origin, parentClass=WebHandler, recurse=True) if not result['OK']: return result self.__handlers = result['Value'] staticPaths = self.getPaths("static") self.log.verbose("Static paths found:\n - %s" % "\n - ".join(staticPaths)) self.__routes = [] # Add some standard paths for static files statDirectories = ['defaults', 'demo'] + Conf.getStaticDirs() self.log.info("The following static directories are used:%s" % str(statDirectories)) for stdir in statDirectories: pattern = '/%s/(.*)' % stdir self.__routes.append( (pattern, StaticHandler, dict(pathList=['%s/webRoot/www/%s' % (rootPath, stdir)]))) self.log.debug(" - Static route: %s" % pattern) for pattern in ((r"/static/(.*)", r"/(favicon\.ico)", r"/(robots\.txt)")): pattern = r"%s%s" % (self.__shySetupGroupRE, pattern) if self.__baseURL: pattern = "/%s%s" % (self.__baseURL, pattern) self.__routes.append( (pattern, StaticHandler, dict(pathList=staticPaths))) self.log.debug(" - Static route: %s" % pattern) for hn in self.__handlers: self.log.info("Found handler %s" % hn) handler = self.__handlers[hn] #CHeck it has AUTH_PROPS if type(handler.AUTH_PROPS) == None: return S_ERROR( "Handler %s does not have AUTH_PROPS defined. Fix it!" % hn) #Get the root for the handler if handler.LOCATION: handlerRoute = handler.LOCATION.strip("/") else: handlerRoute = hn[len(origin):].replace(".", "/").replace( "Handler", "") #Add the setup group RE before baseRoute = self.__setupGroupRE #IF theres a base url like /DIRAC add it if self.__baseURL: baseRoute = "/%s%s" % (self.__baseURL, baseRoute) #Set properly the LOCATION after calculating where it is with helpers to add group and setup later handler.LOCATION = handlerRoute handler.PATH_RE = re.compile("%s(%s/.*)" % (baseRoute, handlerRoute)) handler.URLSCHEMA = "/%s%%(setup)s%%(group)s%%(location)s/%%(action)s" % ( self.__baseURL) if issubclass(handler, WebSocketHandler): handler.PATH_RE = re.compile("%s(%s)" % (baseRoute, handlerRoute)) route = "%s(%s)" % (baseRoute, handlerRoute) self.__routes.append((route, handler)) self.log.verbose(" - WebSocket %s -> %s" % (handlerRoute, hn)) self.log.debug(" * %s" % route) continue #Look for methods that are exported for mName, mObj in inspect.getmembers(handler): if inspect.ismethod(mObj) and mName.find("web_") == 0: if mName == "web_index": #Index methods have the bare url self.log.verbose(" - Route %s -> %s.web_index" % (handlerRoute, hn)) route = "%s(%s/)" % (baseRoute, handlerRoute) self.__routes.append((route, handler)) self.__routes.append( ("%s(%s)" % (baseRoute, handlerRoute), CoreHandler, dict(action='addSlash'))) else: #Normal methods get the method appended without web_ self.log.verbose(" - Route %s/%s -> %s.%s" % (handlerRoute, mName[4:], hn, mName)) route = "%s(%s/%s)" % (baseRoute, handlerRoute, mName[4:]) self.__routes.append((route, handler)) self.log.debug(" * %s" % route) #Send to root self.__routes.append(("%s(/?)" % self.__setupGroupRE, CoreHandler, dict(action="sendToRoot"))) if self.__baseURL: self.__routes.append( ("/%s%s()" % (self.__baseURL, self.__setupGroupRE), CoreHandler, dict(action="sendToRoot"))) return S_OK()