예제 #1
0
 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)
예제 #2
0
  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)
예제 #3
0
    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)
예제 #4
0
  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 )
예제 #5
0
 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'])
예제 #6
0
 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' ]
예제 #7
0
 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
예제 #8
0
 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 ) )
예제 #9
0
 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']
예제 #10
0
    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)
예제 #11
0
 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
예제 #12
0
 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))
예제 #13
0
 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))
예제 #14
0
 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)
예제 #15
0
 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 )
예제 #16
0
 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 )
예제 #17
0
 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)
예제 #18
0
 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))
예제 #19
0
 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()
예제 #20
0
 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()
예제 #21
0
 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 ) )
예제 #22
0
 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)
예제 #23
0
    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,
        )
예제 #24
0
 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)
예제 #25
0
 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 )
예제 #26
0
 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
예제 #27
0
 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
예제 #28
0
  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 )
예제 #29
0
 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 )
예제 #30
0
 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)
예제 #31
0
 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 )
예제 #32
0
 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
예제 #33
0
 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
예제 #34
0
    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
예제 #35
0
    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
예제 #36
0
 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
예제 #37
0
 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
예제 #38
0
    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)
예제 #39
0
 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
예제 #40
0
  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
예제 #41
0
 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
예제 #42
0
  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
예제 #43
0
 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
예제 #44
0
파일: App.py 프로젝트: zmathe/WebAppDIRAC
  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
예제 #45
0
  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()
예제 #46
0
    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
예제 #47
0
  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
예제 #48
0
 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
예제 #49
0
 def __init__( self ):
   self.__routes = Routes( Conf.rootURL() )
   self.__servers = {}
   self.log = gLogger.getSubLogger( "Web" )
예제 #50
0
    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
예제 #51
0
 def __init__(self):
     self.__handlerMgr = HandlerMgr(Conf.rootURL())
     self.__servers = {}
     self.log = gLogger.getSubLogger("Web")
예제 #52
0
 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' ] )
예제 #53
0
 def __init__( self ):
   self.__handlerMgr = HandlerMgr( Conf.rootURL() )
   self.__servers = {}
   self.log = gLogger.getSubLogger( "Web" )
예제 #54
0
    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()