Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Simone Rossi
main
Commits
f5d74f8a
Commit
f5d74f8a
authored
Jan 27, 2017
by
qhoangxuan
Browse files
move oauth2 store to postgres, simplify oauth2 rest api
parent
dc1f388f
Changes
7
Hide whitespace changes
Inline
Side-by-side
zoe_api/auth/oauth2/postgresql.py
0 → 100644
View file @
f5d74f8a
# Copyright (c) 2017, Quang-Nhat HOANG-XUAN
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Store adapters to read/write data to from/to PostgresSQL. """
import
datetime
,
time
import
zoe_lib.state
from
zoe_lib.config
import
get_conf
from
oauth2.store
import
AccessTokenStore
,
AuthCodeStore
,
ClientStore
from
oauth2.datatype
import
AccessToken
,
AuthorizationCode
,
Client
from
oauth2.error
import
AccessTokenNotFound
,
AuthCodeNotFound
,
ClientNotFoundError
class
AccessTokenStore
(
AccessTokenStore
):
def
fetch_by_refresh_token
(
self
,
refresh_token
):
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
data
=
sql
.
fetch_by_refresh_token
(
refresh_token
)
if
data
is
None
:
raise
AccessTokenNotFound
return
AccessToken
(
client_id
=
data
[
"client_id"
],
grant_type
=
data
[
"grant_type"
],
token
=
data
[
"token"
],
data
=
data
[
"data"
],
expires_at
=
data
[
"expires_at"
].
timestamp
(),
refresh_token
=
data
[
"refresh_token"
],
refresh_expires_at
=
data
[
"refresh_token_expires_at"
].
timestamp
(),
scopes
=
data
[
"scopes"
])
def
delete_refresh_token
(
self
,
refresh_token
):
"""
Deletes (invalidates) an old refresh token after use
:param refresh_token: The refresh token.
"""
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
res
=
sql
.
delete_refresh_token
(
refresh_token
)
return
res
def
get_client_id_by_access_token
(
self
,
access_token
):
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
data
=
sql
.
get_client_id_by_access_token
(
access_token
)
return
data
def
fetch_existing_token_of_user
(
self
,
client_id
,
grant_type
,
user_id
):
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
data
=
sql
.
fetch_existing_token_of_user
(
client_id
,
grant_type
,
user_id
)
if
data
is
None
:
raise
AccessTokenNotFound
return
AccessToken
(
client_id
=
data
[
"client_id"
],
grant_type
=
data
[
"grant_type"
],
token
=
data
[
"token"
],
data
=
data
[
"data"
],
expires_at
=
data
[
"expires_at"
].
timestamp
(),
refresh_token
=
data
[
"refresh_token"
],
refresh_expires_at
=
data
[
"refresh_token_expires_at"
].
timestamp
(),
scopes
=
data
[
"scopes"
],
user_id
=
data
[
"user_id"
])
def
save_token
(
self
,
access_token
):
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
sql
.
save_token
(
access_token
.
client_id
,
access_token
.
grant_type
,
access_token
.
token
,
access_token
.
data
,
access_token
.
expires_at
,
access_token
.
refresh_token
,
access_token
.
refresh_expires_at
,
access_token
.
scopes
,
access_token
.
user_id
)
return
True
class
ClientStore
(
ClientStore
):
def
save_client
(
self
,
identifier
,
secret
,
role
,
redirect_uris
,
authorized_grants
,
authorized_response_types
):
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
sql
.
save_client
(
identifier
,
secret
,
role
,
redirect_uris
,
authorized_grants
,
authorized_response_types
)
return
True
def
fetch_by_client_id
(
self
,
client_id
):
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
client_data
=
sql
.
fetch_by_client_id
(
client_id
)
client_data_grants
=
client_data
[
"authorized_grants"
].
split
(
':'
)
if
client_data
is
None
:
raise
ClientNotFoundError
return
Client
(
identifier
=
client_data
[
"identifier"
],
secret
=
client_data
[
"secret"
],
redirect_uris
=
client_data
[
"redirect_uris"
],
authorized_grants
=
client_data_grants
,
authorized_response_types
=
client_data
[
"authorized_response_types"
])
def
get_role_by_client_id
(
self
,
client_id
):
sql
=
zoe_lib
.
state
.
SQLManager
(
get_conf
())
client_data
=
sql
.
fetch_by_client_id
(
client_id
)
if
client_data
is
None
:
raise
ClientNotFoundError
return
client_data
[
"role"
]
zoe_api/auth/oauth2/tokengenerator.py
0 → 100644
View file @
f5d74f8a
# Copyright (c) 2016, Quang-Nhat HOANG-XUAN
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Token generator for oauth2."""
import
base64
import
hashlib
import
os
import
uuid
class
TokenGenerator
(
object
):
"""
Base class of every token generator.
"""
def
__init__
(
self
):
"""
Create a new instance of a token generator.
"""
self
.
expires_in
=
{}
self
.
refresh_expires_in
=
3600
def
create_access_token_data
(
self
,
grant_type
):
"""
Create data needed by an access token.
:param grant_type:
:type grant_type: str
:return: A ``dict`` containing he ``access_token`` and the
``token_type``. If the value of ``TokenGenerator.expires_in``
is larger than 0, a ``refresh_token`` will be generated too.
:rtype: dict
"""
if
grant_type
==
'password'
:
self
.
expires_in
[
'password'
]
=
36000
result
=
{
"access_token"
:
self
.
generate
(),
"token_type"
:
"Bearer"
}
if
self
.
expires_in
.
get
(
grant_type
,
0
)
>
0
:
result
[
"refresh_token"
]
=
self
.
generate
()
result
[
"expires_in"
]
=
self
.
expires_in
[
grant_type
]
return
result
def
generate
(
self
):
"""
Implemented by generators extending this base class.
:raises NotImplementedError:
"""
raise
NotImplementedError
class
URandomTokenGenerator
(
TokenGenerator
):
"""
Create a token using ``os.urandom()``.
"""
def
__init__
(
self
,
length
=
40
):
self
.
token_length
=
length
TokenGenerator
.
__init__
(
self
)
def
generate
(
self
):
"""
:return: A new token
:rtype: str
"""
random_data
=
os
.
urandom
(
100
)
hash_gen
=
hashlib
.
new
(
"sha512"
)
hash_gen
.
update
(
random_data
)
return
hash_gen
.
hexdigest
()[:
self
.
token_length
]
class
Uuid4
(
TokenGenerator
):
"""
Generate a token using uuid4.
"""
def
generate
(
self
):
"""
:return: A new token
:rtype: str
"""
return
str
(
uuid
.
uuid4
())
zoe_api/db_init.py
View file @
f5d74f8a
...
...
@@ -78,7 +78,26 @@ def create_tables(cur):
ip_address CIDR NULL DEFAULT NULL,
essential BOOLEAN NOT NULL DEFAULT FALSE
)'''
)
#Create oauth_client and oauth_token tables for oAuth2
cur
.
execute
(
'''CREATE TABLE oauth_client (
identifier TEXT PRIMARY KEY,
secret TEXT,
role TEXT,
redirect_uris TEXT,
authorized_grants TEXT,
authorized_response_types TEXT
)'''
)
cur
.
execute
(
'''CREATE TABLE oauth_token (
client_id TEXT PRIMARY KEY,
grant_type TEXT,
token TEXT,
data TEXT,
expires_at TIMESTAMP,
refresh_token TEXT,
refresh_token_expires_at TIMESTAMP,
scopes TEXT,
user_id TEXT
)'''
)
def
init
():
"""DB init entrypoint."""
...
...
zoe_api/rest_api/oauth.py
View file @
f5d74f8a
...
...
@@ -13,24 +13,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""The
Execution
API endpoints."""
"""The
oAuth2
API endpoints."""
from
tornado.web
import
RequestHandler
import
tornado.escape
import
logging
import
zoe_lib.config
as
config
from
zoe_api.rest_api.utils
import
catch_exceptions
,
get_auth
from
zoe_api.rest_api.oauth_utils
import
auth_controller
,
mongo
,
get_username_password
import
zoe_api.exceptions
from
zoe_api.api_endpoint
import
APIEndpoint
# pylint: disable=unused-import
import
oauth2.grant
import
json
import
requests
import
pymongo
import
psycopg2
from
zoe_api.rest_api.utils
import
catch_exceptions
,
get_auth
from
zoe_api.rest_api.oauth_utils
import
auth_controller
,
client_store
,
token_store
from
zoe_api.api_endpoint
import
APIEndpoint
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -38,26 +37,16 @@ log = logging.getLogger(__name__)
Example of using:
-Two kind of request token:
(1) with an access token and a refresh token
(2) with only an access token
*To request a new token of type:
(1):
Input: curl -u 'admin:admin' http://localhost:5001/api/0.6/oauth/token -X POST -H 'Content-Type: application/json' -d '{"client_id": "admin", "client_secret": "admin", "grant_type": "password", "username": "admin", "password": "admin", "scope": ""}'
Input: curl -u 'admin:admin' http://localhost:5001/api/0.6/oauth/token -X POST -H 'Content-Type: application/json' -d '{"grant_type": "password"}'
Output: {"token_type": "Bearer", "access_token": "3ddbe9ba-6a21-4e4d-993b-70556390c5d3", "refresh_token": "9bab190f-e211-42aa-917e-20ce987e355e", "expires_in": 36000}
(2):
Input: curl -u 'admin:admin' http://localhost:5001/api/0.6/oauth/token -X POST -H 'Content-Type: application/json' -d '{"client_id": "admin", "client_secret": "admin", "grant_type": "client_credentials", "scope": ""}'
Output: {"token_type": "Bearer", "access_token": "e6ab7c66-777b-4b64-91e0-2f501d28fe6e", "expires_in": 3600}
*To refresh a token, only apply for type-1 request token
Input: curl -u 'admin:admin' http://localhost:5001/api/0.6/oauth/token -X POST -H 'Content-Type: application/json' -d '{"client_id": "admin", "client_secret": "admin", "grant_type": "refresh_token", "refresh_token": "9bab190f-e211-42aa-917e-20ce987e355e", "username": "admin", "password": "admin", "scope": ""}'
*To refresh a token
Input: curl -u 'admin:admin' http://localhost:5001/api/0.6/oauth/token -X POST -H 'Content-Type: application/json' -d '{"grant_type": "refresh_token", "refresh_token": "9bab190f-e211-42aa-917e-20ce987e355e"}'
Output: {"token_type": "Bearer", "access_token": "378f8d5f-2eb5-4181-b632-ad23c4534d32", "expires_in": 36000}
*To revoke a token,
apply for two types of token requested
curl
-i --verbose
-u 'admin:admin' -X DELETE http://localhost:5001/api/0.6/oauth/revoke/
e6ab7c66-777b-4b64-91e0-2f501d28fe6e
*To revoke a token,
the passed token could be the access token or refresh token
curl -u 'admin:admin' -X DELETE http://localhost:5001/api/0.6/oauth/revoke/
378f8d5f-2eb5-4181-b632-ad23c4534d32
*To authenticate with other rest api services, using a header with: "Authorization: Bearer access_token"
curl -H 'Authorization: Bearer 378f8d5f-2eb5-4181-b632-ad23c4534d32' http://localhost:5001/api/0.6/execution
...
...
@@ -71,34 +60,35 @@ class OAuthGetAPI(RequestHandler):
"""Initializes the request handler."""
self
.
api_endpoint
=
kwargs
[
'api_endpoint'
]
# type: APIEndpoint
self
.
auth_controller
=
auth_controller
self
.
mongo
=
mongo
self
.
client_store
=
client_store
@
catch_exceptions
def
post
(
self
):
"""REQUEST/REFRESH token"""
username
,
password
=
get_username_password
(
self
)
uid
,
role
=
get_auth
(
self
)
grant_type
=
oauth2
.
grant
.
RefreshToken
.
grant_type
+
':'
+
oauth2
.
grant
.
ResourceOwnerGrant
.
grant_type
try
:
self
.
mongo
[
'db'
][
'oauth_clients'
].
insert
(
{
'identifier'
:
username
,
'secret'
:
password
,
'redirect_uris'
:
[],
'authorized_grants'
:
[
oauth2
.
grant
.
RefreshToken
.
grant_type
,
oauth2
.
grant
.
ResourceOwnerGrant
.
grant_type
,
oauth2
.
grant
.
ClientCredentialsGrant
.
grant_type
]})
except
pymongo
.
errors
.
DuplicateKeyError
as
e
:
log
.
warn
(
"Already had this user in db, skip adding..."
)
self
.
client_store
.
save_client
(
uid
,
''
,
role
,
''
,
grant_type
,
''
)
except
psycopg2
.
IntegrityError
as
e
:
log
.
warn
(
'User is already had'
)
response
=
self
.
_dispatch_request
()
response
=
self
.
_dispatch_request
(
uid
)
self
.
_map_response
(
response
)
def
_dispatch_request
(
self
):
def
_dispatch_request
(
self
,
uid
):
request
=
self
.
request
request
.
post_param
=
lambda
key
:
json
.
loads
(
request
.
body
.
decode
())[
key
]
params
=
json
.
loads
(
request
.
body
.
decode
())
params
[
'password'
]
=
''
params
[
'username'
]
=
''
params
[
'client_secret'
]
=
''
params
[
'scope'
]
=
''
params
[
'client_id'
]
=
uid
request
.
post_param
=
lambda
key
:
params
[
key
]
return
self
.
auth_controller
.
dispatch
(
request
,
environ
=
{})
def
_map_response
(
self
,
response
):
for
name
,
value
in
list
(
response
.
headers
.
items
()):
...
...
@@ -119,17 +109,17 @@ class OAuthRevokeAPI(RequestHandler):
"""Initializes the request handler."""
self
.
api_endpoint
=
kwargs
[
'api_endpoint'
]
# type: APIEndpoint
self
.
auth_controller
=
auth_controller
self
.
token_store
=
token_store
@
catch_exceptions
def
delete
(
self
,
token
):
"""DELETE token (logout)"""
uid
,
role
=
get_auth
(
self
)
key
=
'oauth2_{}'
.
format
(
token
)
res
=
self
.
auth_controller
.
access_token_store
.
rs
.
delete
(
key
)
res
=
self
.
token_store
.
delete_refresh_token
(
token
)
if
res
==
0
:
r
aise
zoe_api
.
exceptions
.
ZoeRestAPIException
(
'No token found in database
'
)
ret
=
{
'res'
:
'Revoked token.'
}
r
et
=
{
'ret'
:
'No token found in database
.'
}
else
:
ret
=
{
'res'
:
'Revoked token.'
}
self
.
write
(
ret
)
zoe_api/rest_api/oauth_utils.py
View file @
f5d74f8a
# Copyright (c) 201
6
, Quang-Nhat HOANG-XUAN
# Copyright (c) 201
7
, Quang-Nhat HOANG-XUAN
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
...
...
@@ -13,30 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Utility functions needed by the Zoe REST API
."""
"""
Authentication controller for oauth2
."""
import
base64
import
logging
from
zoe_lib.config
import
get_conf
from
zoe_api.exceptions
import
ZoeRestAPIException
import
tornado.web
import
oauth2
import
oauth2.tokengenerator
import
oauth2.web
import
oauth2.grant
import
oauth2.store.redisdb
import
oauth2.
s
to
re.mongodb
from
zoe_api.auth.oauth2.postgresql
import
AccessTokenStore
,
ClientStore
from
zoe_api.auth.
oauth2.to
kengenerator
import
Uuid4
import
time
import
json
import
fakeredis
import
mongomock
import
hashlib
import
os
import
uuid
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -44,101 +31,8 @@ class OAuthSiteAdapter(oauth2.web.ResourceOwnerGrantSiteAdapter):
def
authenticate
(
self
,
request
,
environ
,
scopes
,
client
):
return
{}
class
TokenGenerator
(
object
):
"""
Base class of every token generator.
"""
def
__init__
(
self
):
"""
Create a new instance of a token generator.
"""
self
.
expires_in
=
{}
self
.
refresh_expires_in
=
0
def
create_access_token_data
(
self
,
grant_type
):
"""
Create data needed by an access token.
:param grant_type:
:type grant_type: str
:return: A ``dict`` containing he ``access_token`` and the
``token_type``. If the value of ``TokenGenerator.expires_in``
is larger than 0, a ``refresh_token`` will be generated too.
:rtype: dict
"""
if
grant_type
==
'password'
:
self
.
expires_in
[
'password'
]
=
36000
result
=
{
"access_token"
:
self
.
generate
(),
"token_type"
:
"Bearer"
}
if
self
.
expires_in
.
get
(
grant_type
,
0
)
>
0
:
result
[
"refresh_token"
]
=
self
.
generate
()
result
[
"expires_in"
]
=
self
.
expires_in
[
grant_type
]
return
result
def
generate
(
self
):
"""
Implemented by generators extending this base class.
:raises NotImplementedError:
"""
raise
NotImplementedError
class
URandomTokenGenerator
(
TokenGenerator
):
"""
Create a token using ``os.urandom()``.
"""
def
__init__
(
self
,
length
=
40
):
self
.
token_length
=
length
TokenGenerator
.
__init__
(
self
)
def
generate
(
self
):
"""
:return: A new token
:rtype: str
"""
random_data
=
os
.
urandom
(
100
)
hash_gen
=
hashlib
.
new
(
"sha512"
)
hash_gen
.
update
(
random_data
)
return
hash_gen
.
hexdigest
()[:
self
.
token_length
]
class
Uuid4
(
TokenGenerator
):
"""
Generate a token using uuid4.
"""
def
generate
(
self
):
"""
:return: A new token
:rtype: str
"""
return
str
(
uuid
.
uuid4
())
def
get_username_password
(
handler
:
tornado
.
web
.
RequestHandler
):
"""Get username, password"""
auth_header
=
handler
.
request
.
headers
.
get
(
'Authorization'
)
if
auth_header
is
None
or
not
(
auth_header
.
startswith
(
'Basic '
)
or
auth_header
.
startswith
(
'Bearer '
)):
raise
ZoeRestAPIException
(
'missing or wrong authentication information'
,
401
,
{
'WWW-Authenticate'
:
'Basic realm="Login Required"'
})
auth_decoded
=
base64
.
decodebytes
(
bytes
(
auth_header
[
6
:],
'ascii'
)).
decode
(
'utf-8'
)
username
,
password
=
auth_decoded
.
split
(
':'
,
2
)
return
username
,
password
mongo
=
mongomock
.
MongoClient
()
mongo
[
'db'
][
'oauth_clients'
].
ensure_index
(
"identifier"
,
unique
=
True
)
client_store
=
oauth2
.
store
.
mongodb
.
ClientStore
(
mongo
[
'db'
][
'oauth_clients'
])
token_store
=
oauth2
.
store
.
redisdb
.
TokenStore
(
rs
=
fakeredis
.
FakeStrictRedis
())
client_store
=
ClientStore
()
token_store
=
AccessTokenStore
()
token_generator
=
Uuid4
()
token_generator
.
expires_in
[
oauth2
.
grant
.
ClientCredentialsGrant
.
grant_type
]
=
3600
...
...
@@ -152,7 +46,7 @@ auth_controller = oauth2.Provider(
site_adapter
=
OAuthSiteAdapter
()
auth_controller
.
token_path
=
'/api/0.
6
/oauth/token'
auth_controller
.
token_path
=
'/api/0.
7
/oauth/token'
auth_controller
.
add_grant
(
oauth2
.
grant
.
ClientCredentialsGrant
())
auth_controller
.
add_grant
(
oauth2
.
grant
.
RefreshToken
(
expires_in
=
3600
))
auth_controller
.
add_grant
(
oauth2
.
grant
.
ResourceOwnerGrant
(
site_adapter
=
site_adapter
))
...
...
zoe_api/rest_api/utils.py
View file @
f5d74f8a
...
...
@@ -27,9 +27,8 @@ from zoe_api.exceptions import ZoeRestAPIException, ZoeNotFoundException, ZoeAut
from
zoe_api.auth.ldap
import
LDAPAuthenticator
from
zoe_api.auth.file
import
PlainTextAuthenticator
from
zoe_api.auth.ldapsasl
import
LDAPSASLAuthenticator
from
zoe_api.auth.base
import
BaseAuthenticator
# pylint: disable=unused-import
from
zoe_api.rest_api.oauth_utils
import
auth_controller
,
mongo
from
zoe_api.auth.base
import
BaseAuthenticator
from
zoe_api.rest_api.oauth_utils
import
auth_controller
,
client_store
,
token_store
import
json
import
time
...
...
@@ -86,21 +85,19 @@ def get_auth(handler: tornado.web.RequestHandler):
#Process for authentication with token
if
"Bearer"
in
auth_header
:
token
=
auth_header
[
7
:]
key
=
'oauth2_{}'
.
format
(
token
)
access
=
auth_controller
.
access_token_store
.
rs
.
get
(
key
)
if
access
:
access
=
json
.
loads
(
access
.
decode
())
username
=
access
[
'client_id'
]
passwords
=
mongo
[
'db'
][
'oauth_clients'
].
find
({
'identifier'
:
username
})
password
=
''
for
p
in
passwords
:
password
=
p
[
'secret'
]
data
=
token_store
.
get_client_id_by_access_token
(
token
)
if
data
:
uid
=
data
[
"client_id"
]
role
=
client_store
.
get_role_by_client_id
(
uid
)
else
:
raise
ZoeRestAPIException
(
'Invalid Token'
,
401
,
{
'WWW-Authenticate'
:
'Basic realm="Login Required"'
})
if
access
[
'expires_at'
]
<=
int
(
time
.
time
()):
if
int
(
data
[
'expires_at'
]
.
timestamp
())
<=
int
(
time
.
time
()):
raise
ZoeRestAPIException
(
'Expired token'
,
401
,
{
'WWW-Authenticate'
:
'Basic realm="Login Required"'
})
return
uid
,
role
#Process for authentication with username, password
else
:
auth_decoded
=
base64
.
decodebytes
(
bytes
(
auth_header
[
6
:],
'ascii'
)).
decode
(
'utf-8'
)
...
...
zoe_lib/state/sql_manager.py
View file @
f5d74f8a
...
...
@@ -180,3 +180,63 @@ class SQLManager:
cur
.
execute
(
query
)
self
.
conn
.
commit
()
return
cur
.
fetchone
()[
0
]
""" The above section is used for Oauth2 authentication mechanism """
def
fetch_by_refresh_token
(
self
,
refresh_token
):
cur
=
self
.
_cursor
()
query
=
'SELECT * FROM oauth_token WHERE refresh_token = %s'
cur
.
execute
(
query
,
(
refresh_token
,))
return
cur
.
fetchone
()
def
delete_refresh_token
(
self
,
refresh_token
):
cur
=
self
.
_cursor
()
check_exists
=
'SELECT * FROM oauth_token WHERE refresh_token = %s OR token = %s'
cur
.
execute
(
check_exists
,
(
refresh_token
,
refresh_token
))
res
=
0
if
cur
.
fetchone
():
res
=
1
query
=
'DELETE FROM oauth_token WHERE refresh_token = %s OR token = %s'
cur
.
execute
(
query
,
(
refresh_token
,
refresh_token
))
self
.
conn
.
commit
()
return
res
def
fetch_existing_token_of_user
(
self
,
client_id
,
grant_type
,
user_id
):
cur
=
self
.
_cursor
()
query
=
'SELECT * FROM oauth_token WHERE client_id = %s AND grant_type = %s AND user_id = %s'
cur
.
execute
(
quer