@@ -952,6 +952,35 @@ def determine_language(self):
952952 language ,
953953 tracker_home = self .instance .config ["TRACKER_HOME" ]))
954954
955+ def authenticate_bearer_token (self , challenge ):
956+ ''' authenticate the bearer token. Refactored from determine_user()
957+ to alow it to be overridden if needed.
958+ '''
959+ try : # will jwt import?
960+ import jwt
961+ except ImportError :
962+ # no support for jwt, this is fine.
963+ self .setHeader ("WWW-Authenticate" , "Basic" )
964+ raise LoginError ('Support for jwt disabled.' )
965+
966+ secret = self .db .config .WEB_JWT_SECRET
967+ if len (secret ) < 32 :
968+ # no support for jwt, this is fine.
969+ self .setHeader ("WWW-Authenticate" , "Basic" )
970+ raise LoginError ('Support for jwt disabled by admin.' )
971+
972+ try : # handle jwt exceptions
973+ token = jwt .decode (challenge , secret ,
974+ algorithms = ['HS256' ],
975+ audience = self .db .config .TRACKER_WEB ,
976+ issuer = self .db .config .TRACKER_WEB )
977+ except jwt .exceptions .InvalidTokenError as err :
978+ self .setHeader ("WWW-Authenticate" , "Basic, Bearer" )
979+ self .make_user_anonymous ()
980+ raise LoginError (str (err ))
981+
982+ return (token )
983+
955984 def determine_user (self ):
956985 """Determine who the user is"""
957986 self .opendb ('admin' )
@@ -1011,48 +1040,29 @@ def determine_user(self):
10111040 # this is a no-op.
10121041 random_ .seed ("%s%s" % (password ,time .time ()))
10131042 elif scheme .lower () == 'bearer' :
1014- try : # will jwt import?
1015- import jwt
1016- from roundup .hyperdb import iter_roles
1017- try : # handle jwt exceptions
1018- secret = self .db .config .WEB_JWT_SECRET
1019- if len (secret ) < 32 :
1020- # no support for jwt, this is fine.
1021- self .setHeader ("WWW-Authenticate" , "Basic" )
1022- raise LoginError ('Support for jwt disabled by admin.' )
1023- token = jwt .decode (challenge , secret ,
1024- algorithms = ['HS256' ],
1025- audience = self .db .config .TRACKER_WEB ,
1026- issuer = self .db .config .TRACKER_WEB )
1027- except jwt .exceptions .InvalidTokenError as err :
1028- self .setHeader ("WWW-Authenticate" , "Basic, Bearer" )
1029- self .make_user_anonymous ()
1030- raise LoginError (str (err ))
1031-
1032- # if we got here token is valid, use the role
1033- # and sub claims.
1034- try :
1035- # make sure to str(token['sub']) the subject. As decoded
1036- # by json, it is unicode which thows an error when used
1037- # with 'nodeid in db' down the call chain.
1038- user = self .db .user .get (str (token ['sub' ]), 'username' )
1039- except IndexError :
1040- raise LoginError ("Token subject is invalid." )
1041-
1042- # validate roles
1043- all_rolenames = [ role [0 ] for role in self .db .security .role .items () ]
1044- for r in token ['roles' ]:
1045- if r .lower () not in all_rolenames :
1046- raise LoginError ("Token roles are invalid." )
1043+ token = self .authenticate_bearer_token (challenge )
1044+
1045+ from roundup .hyperdb import iter_roles
1046+
1047+ # if we got here token is valid, use the role
1048+ # and sub claims.
1049+ try :
1050+ # make sure to str(token['sub']) the subject. As decoded
1051+ # by json, it is unicode which thows an error when used
1052+ # with 'nodeid in db' down the call chain.
1053+ user = self .db .user .get (str (token ['sub' ]), 'username' )
1054+ except IndexError :
1055+ raise LoginError ("Token subject is invalid." )
1056+
1057+ # validate roles
1058+ all_rolenames = [ role [0 ] for role in self .db .security .role .items () ]
1059+ for r in token ['roles' ]:
1060+ if r .lower () not in all_rolenames :
1061+ raise LoginError ("Token roles are invalid." )
10471062
1048- # will be used later to override the get_roles method
1049- override_get_roles = \
1050- lambda self : iter_roles (',' .join (token ['roles' ]))
1051-
1052- except ImportError :
1053- # no support for jwt, this is fine.
1054- self .setHeader ("WWW-Authenticate" , "Basic" )
1055- raise LoginError ('Support for jwt disabled.' )
1063+ # will be used later to override the get_roles method
1064+ override_get_roles = \
1065+ lambda self : iter_roles (',' .join (token ['roles' ]))
10561066
10571067 # if user was not set by http authorization, try session lookup
10581068 if not user :
0 commit comments