Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
be7e367a
Commit
be7e367a
authored
Jul 08, 2023
by
crazywoola
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add passport services
parent
1f9fa549
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
109 additions
and
4 deletions
+109
-4
__init__.py
api/controllers/web/__init__.py
+1
-1
passport.py
api/controllers/web/passport.py
+66
-0
wraps.py
api/controllers/web/wraps.py
+28
-2
passport.py
api/libs/passport.py
+13
-0
requirements.txt
api/requirements.txt
+1
-1
No files found.
api/controllers/web/__init__.py
View file @
be7e367a
...
...
@@ -7,4 +7,4 @@ bp = Blueprint('web', __name__, url_prefix='/api')
api
=
ExternalApi
(
bp
)
from
.
import
completion
,
app
,
conversation
,
message
,
site
,
saved_message
,
audio
from
.
import
completion
,
app
,
conversation
,
message
,
site
,
saved_message
,
audio
,
passport
api/controllers/web/passport.py
0 → 100644
View file @
be7e367a
# -*- coding:utf-8 -*-
import
uuid
from
controllers.web
import
api
from
flask_restful
import
Resource
from
flask
import
current_app
,
request
from
werkzeug.exceptions
import
Unauthorized
,
NotFound
from
models.model
import
Site
,
EndUser
,
App
from
extensions.ext_database
import
db
from
libs.passport
import
PassportService
class
PassportResource
(
Resource
):
"""Base resource for passport."""
def
get
(
self
):
app_id
=
request
.
headers
.
get
(
'X-Site-Code'
)
if
app_id
is
None
:
raise
Unauthorized
(
'X-Site-Code header is missing.'
)
sk
=
current_app
.
config
.
get
(
'SECRET_KEY'
)
# get site from db and check if it is normal
site
=
db
.
session
.
query
(
Site
)
.
filter
(
Site
.
code
==
app_id
,
Site
.
status
==
'normal'
)
.
first
()
if
not
site
:
raise
NotFound
()
# get app from db and check if it is normal and enable_site
app_model
=
db
.
session
.
query
(
App
)
.
filter
(
App
.
id
==
site
.
app_id
)
.
first
()
if
not
app_model
or
app_model
.
status
!=
'normal'
or
not
app_model
.
enable_site
:
raise
NotFound
()
end_user
=
EndUser
(
tenant_id
=
app_model
.
tenant_id
,
app_id
=
app_model
.
id
,
type
=
'browser'
,
is_anonymous
=
True
,
session_id
=
generate_session_id
(),
)
db
.
session
.
add
(
end_user
)
db
.
session
.
commit
()
payload
=
{
"iss"
:
site
.
app_id
,
'sub'
:
'Web API Passport'
,
"aud"
:
end_user
.
id
,
'app_id'
:
site
.
app_id
,
'end_user_id'
:
end_user
.
id
,
}
tk
=
PassportService
(
sk
,
payload
)
.
get_token
()
return
{
'access_token'
:
tk
,
}
api
.
add_resource
(
PassportResource
,
'/passport'
)
def
generate_session_id
():
"""
Generate a unique session ID.
"""
while
True
:
session_id
=
str
(
uuid
.
uuid4
())
existing_count
=
db
.
session
.
query
(
EndUser
)
\
.
filter
(
EndUser
.
session_id
==
session_id
)
.
count
()
if
existing_count
==
0
:
return
session_id
api/controllers/web/wraps.py
View file @
be7e367a
...
...
@@ -9,7 +9,27 @@ from werkzeug.exceptions import NotFound, Unauthorized
from
extensions.ext_database
import
db
from
models.model
import
App
,
Site
,
EndUser
def
validate_jwt_token
(
view
=
None
):
def
decorator
(
view
):
@
wraps
(
view
)
def
decorated
(
*
args
,
**
kwargs
):
site
=
get_site_from_jwt_token
()
app_model
=
db
.
session
.
query
(
App
)
.
filter
(
App
.
id
==
site
.
app_id
)
.
first
()
if
not
app_model
:
raise
NotFound
()
if
app_model
.
status
!=
'normal'
:
raise
NotFound
()
if
not
app_model
.
enable_site
:
raise
NotFound
()
end_user
=
get_end_user_from_jwt_token
()
return
view
(
app_model
,
end_user
,
*
args
,
**
kwargs
)
return
decorated
def
validate_token
(
view
=
None
):
def
decorator
(
view
):
@
wraps
(
view
)
...
...
@@ -47,9 +67,9 @@ def validate_and_get_site():
if
' '
not
in
auth_header
:
raise
Unauthorized
(
'Invalid Authorization header format. Expected
\'
Bearer <api-key>
\'
format.'
)
auth_scheme
,
auth_token
=
auth_header
.
split
(
None
,
1
)
auth_scheme
,
auth_token
s
=
auth_header
.
split
(
None
,
1
)
auth_scheme
=
auth_scheme
.
lower
()
auth_token
,
jwt_token
=
[
token
.
strip
()
for
token
in
auth_tokens
.
split
(
','
)]
if
auth_scheme
!=
'bearer'
:
raise
Unauthorized
(
'Invalid Authorization header format. Expected
\'
Bearer <api-key>
\'
format.'
)
...
...
@@ -104,5 +124,11 @@ def generate_session_id():
return
session_id
def
get_site_from_jwt_token
():
return
"site"
def
get_end_user_from_jwt_token
():
return
"end_user"
class
WebApiResource
(
Resource
):
method_decorators
=
[
validate_token
]
api/libs/passport.py
0 → 100644
View file @
be7e367a
# -*- coding:utf-8 -*-
import
jwt
class
PassportService
:
def
__init__
(
self
,
sk
,
payload
):
self
.
sk
=
sk
self
.
payload
=
payload
def
get_token
(
self
):
return
jwt
.
encode
(
self
.
payload
,
self
.
sk
,
algorithm
=
'HS256'
)
def
verify_token
(
self
,
token
):
return
jwt
.
decode
(
token
,
self
.
sk
,
algorithms
=
[
'HS256'
])
api/requirements.txt
View file @
be7e367a
...
...
@@ -33,4 +33,4 @@ openpyxl==3.1.2
chardet~=5.1.0
docx2txt==0.8
pypdfium2==4.16.0
flask-jwt-extended==4.5.2
\ No newline at end of file
pyjwt~=2.6.0
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment