Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
douban-api-proxy
Project
Project
Details
Activity
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
captainwong
douban-api-proxy
Commits
c1ef1bcd
Commit
c1ef1bcd
authored
Feb 09, 2019
by
Ozzieisaacs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
User and admin pages are working again
parent
1fc4bc52
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
107 additions
and
42 deletions
+107
-42
admin.py
cps/admin.py
+3
-3
ldap.py
cps/ldap.py
+39
-0
oauth_bb.py
cps/oauth_bb.py
+23
-6
ub.py
cps/ub.py
+17
-5
web.py
cps/web.py
+25
-28
No files found.
cps/admin.py
View file @
c1ef1bcd
...
@@ -38,7 +38,7 @@ from sqlalchemy.exc import IntegrityError
...
@@ -38,7 +38,7 @@ from sqlalchemy.exc import IntegrityError
from
gdriveutils
import
is_gdrive_ready
,
gdrive_support
,
downloadFile
,
deleteDatabaseOnChange
,
listRootFolders
from
gdriveutils
import
is_gdrive_ready
,
gdrive_support
,
downloadFile
,
deleteDatabaseOnChange
,
listRootFolders
import
helper
import
helper
from
werkzeug.security
import
generate_password_hash
from
werkzeug.security
import
generate_password_hash
from
sqlalchemy.sql.expression
import
text
from
oauth_bb
import
oauth_check
try
:
try
:
from
goodreads.client
import
GoodreadsClient
from
goodreads.client
import
GoodreadsClient
...
@@ -591,7 +591,7 @@ def new_user():
...
@@ -591,7 +591,7 @@ def new_user():
content
.
sidebar_view
=
config
.
config_default_show
content
.
sidebar_view
=
config
.
config_default_show
content
.
mature_content
=
bool
(
config
.
config_default_show
&
ub
.
MATURE_CONTENT
)
content
.
mature_content
=
bool
(
config
.
config_default_show
&
ub
.
MATURE_CONTENT
)
return
render_title_template
(
"user_edit.html"
,
new_user
=
1
,
content
=
content
,
translations
=
translations
,
return
render_title_template
(
"user_edit.html"
,
new_user
=
1
,
content
=
content
,
translations
=
translations
,
languages
=
languages
,
title
=
_
(
u"Add new user"
),
page
=
"newuser"
)
languages
=
languages
,
title
=
_
(
u"Add new user"
),
page
=
"newuser"
,
registered_oauth
=
oauth_check
)
@
admi
.
route
(
"/admin/mailsettings"
,
methods
=
[
"GET"
,
"POST"
])
@
admi
.
route
(
"/admin/mailsettings"
,
methods
=
[
"GET"
,
"POST"
])
...
@@ -767,7 +767,7 @@ def edit_user(user_id):
...
@@ -767,7 +767,7 @@ def edit_user(user_id):
flash
(
_
(
u"An unknown error occured."
),
category
=
"error"
)
flash
(
_
(
u"An unknown error occured."
),
category
=
"error"
)
return
render_title_template
(
"user_edit.html"
,
translations
=
translations
,
languages
=
languages
,
new_user
=
0
,
return
render_title_template
(
"user_edit.html"
,
translations
=
translations
,
languages
=
languages
,
new_user
=
0
,
content
=
content
,
downloads
=
downloads
,
title
=
_
(
u"Edit User
%(nick)
s"
,
content
=
content
,
downloads
=
downloads
,
title
=
_
(
u"Edit User
%(nick)
s"
,
nick
=
content
.
nickname
),
page
=
"edituser"
)
nick
=
content
.
nickname
),
page
=
"edituser"
,
registered_oauth
=
oauth_check
)
@
admi
.
route
(
"/admin/resetpassword/<int:user_id>"
)
@
admi
.
route
(
"/admin/resetpassword/<int:user_id>"
)
...
...
cps/ldap.py
0 → 100644
View file @
c1ef1bcd
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
# Copyright (C) 2018-2019 Krakinou
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
ldap
from
cps
import
ub
,
app
,
request
from
flask
import
flash
,
url_for
from
redirect
import
redirect_back
from
flask_login
import
login_user
from
flask_babel
import
gettext
as
_
def
login
(
form
,
user
):
try
:
ub
.
User
.
try_login
(
form
[
'username'
],
form
[
'password'
])
login_user
(
user
,
remember
=
True
)
flash
(
_
(
u"you are now logged in as: '
%(nickname)
s'"
,
nickname
=
user
.
nickname
),
category
=
"success"
)
return
redirect_back
(
url_for
(
"web.index"
))
except
ldap
.
INVALID_CREDENTIALS
:
ipAdress
=
request
.
headers
.
get
(
'X-Forwarded-For'
,
request
.
remote_addr
)
app
.
logger
.
info
(
'LDAP Login failed for user "'
+
form
[
'username'
]
+
'" IP-adress: '
+
ipAdress
)
flash
(
_
(
u"Wrong Username or Password"
),
category
=
"error"
)
def
logout
():
pass
cps/oauth_bb.py
View file @
c1ef1bcd
...
@@ -25,16 +25,33 @@ from flask_dance.contrib.google import make_google_blueprint, google
...
@@ -25,16 +25,33 @@ from flask_dance.contrib.google import make_google_blueprint, google
from
flask_dance.consumer
import
oauth_authorized
,
oauth_error
from
flask_dance.consumer
import
oauth_authorized
,
oauth_error
from
sqlalchemy.orm.exc
import
NoResultFound
from
sqlalchemy.orm.exc
import
NoResultFound
from
oauth
import
OAuthBackend
from
oauth
import
OAuthBackend
from
flask
import
flash
,
session
,
redirect
,
url_for
,
request
from
flask
import
flash
,
session
,
redirect
,
url_for
,
request
,
make_response
,
abort
import
json
from
cps
import
config
,
app
from
cps
import
config
,
app
import
ub
import
ub
from
flask_login
import
login_user
,
login_required
,
current_user
from
flask_login
import
login_user
,
login_required
,
current_user
from
flask_babel
import
gettext
as
_
from
flask_babel
import
gettext
as
_
from
web
import
github_oauth_required
# from web import github_oauth_required
from
functools
import
wraps
oauth_check
=
{}
oauth_check
=
{}
def
github_oauth_required
(
f
):
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
if
config
.
config_use_github_oauth
:
return
f
(
*
args
,
**
kwargs
)
if
request
.
is_xhr
:
data
=
{
'status'
:
'error'
,
'message'
:
'Not Found'
}
response
=
make_response
(
json
.
dumps
(
data
,
ensure_ascii
=
False
))
response
.
headers
[
"Content-Type"
]
=
"application/json; charset=utf-8"
return
response
,
404
abort
(
404
)
return
inner
def
register_oauth_blueprint
(
blueprint
,
show_name
):
def
register_oauth_blueprint
(
blueprint
,
show_name
):
if
blueprint
.
name
!=
""
:
if
blueprint
.
name
!=
""
:
oauth_check
[
blueprint
.
name
]
=
show_name
oauth_check
[
blueprint
.
name
]
=
show_name
...
@@ -246,7 +263,7 @@ def github_error(blueprint, error, error_description=None, error_uri=None):
...
@@ -246,7 +263,7 @@ def github_error(blueprint, error, error_description=None, error_uri=None):
)
)
flash
(
msg
,
category
=
"error"
)
flash
(
msg
,
category
=
"error"
)
'''
@oauth.route('/github')
@oauth.route('/github')
@github_oauth_required
@github_oauth_required
def github_login():
def github_login():
...
@@ -277,7 +294,7 @@ def google_login():
...
@@ -277,7 +294,7 @@ def google_login():
return bind_oauth_or_register(google_blueprint.name, account_info_json['id'], 'google.login')
return bind_oauth_or_register(google_blueprint.name, account_info_json['id'], 'google.login')
flash(_(u"Google Oauth error, please retry later."), category="error")
flash(_(u"Google Oauth error, please retry later."), category="error")
return redirect(url_for('login'))
return redirect(url_for('login'))
'''
@
oauth_error
.
connect_via
(
google_blueprint
)
@
oauth_error
.
connect_via
(
google_blueprint
)
def
google_error
(
blueprint
,
error
,
error_description
=
None
,
error_uri
=
None
):
def
google_error
(
blueprint
,
error
,
error_description
=
None
,
error_uri
=
None
):
...
@@ -292,8 +309,8 @@ def google_error(blueprint, error, error_description=None, error_uri=None):
...
@@ -292,8 +309,8 @@ def google_error(blueprint, error, error_description=None, error_uri=None):
)
)
flash
(
msg
,
category
=
"error"
)
flash
(
msg
,
category
=
"error"
)
'''
@oauth.route('/unlink/google', methods=["GET"])
@oauth.route('/unlink/google', methods=["GET"])
@login_required
@login_required
def google_login_unlink():
def google_login_unlink():
return
unlink_oauth
(
google_blueprint
.
name
)
return unlink_oauth(google_blueprint.name)
'''
cps/ub.py
View file @
c1ef1bcd
...
@@ -23,6 +23,7 @@ from sqlalchemy import exc
...
@@ -23,6 +23,7 @@ from sqlalchemy import exc
from
sqlalchemy.ext.declarative
import
declarative_base
from
sqlalchemy.ext.declarative
import
declarative_base
from
sqlalchemy.orm
import
*
from
sqlalchemy.orm
import
*
from
flask_login
import
AnonymousUserMixin
from
flask_login
import
AnonymousUserMixin
from
flask_dance.consumer.backend.sqla
import
OAuthConsumerMixin
import
sys
import
sys
import
os
import
os
import
logging
import
logging
...
@@ -32,6 +33,11 @@ import datetime
...
@@ -32,6 +33,11 @@ import datetime
from
binascii
import
hexlify
from
binascii
import
hexlify
import
cli
import
cli
try
:
import
ldap
except
ImportError
:
pass
engine
=
create_engine
(
'sqlite:///{0}'
.
format
(
cli
.
settingspath
),
echo
=
False
)
engine
=
create_engine
(
'sqlite:///{0}'
.
format
(
cli
.
settingspath
),
echo
=
False
)
Base
=
declarative_base
()
Base
=
declarative_base
()
...
@@ -176,13 +182,12 @@ class UserBase:
...
@@ -176,13 +182,12 @@ class UserBase:
return
'<User
%
r>'
%
self
.
nickname
return
'<User
%
r>'
%
self
.
nickname
#Login via LDAP method
#Login via LDAP method
''''
@staticmethod
@
staticmethod
def
try_login
(
username
,
password
):
def
try_login
(
username
,
password
):
conn
=
get_ldap_connection
()
conn
=
get_ldap_connection
()
conn
.
simple_bind_s
(
conn
.
simple_bind_s
(
config
.
config_ldap_dn
.
replace
(
"
%
s"
,
username
),
config
.
config_ldap_dn
.
replace
(
"
%
s"
,
username
),
password
password
)
)'''
# Baseclass for Users in Calibre-Web, settings which are depending on certain users are stored here. It is derived from
# Baseclass for Users in Calibre-Web, settings which are depending on certain users are stored here. It is derived from
# User Base (all access methods are declared there)
# User Base (all access methods are declared there)
...
@@ -202,11 +207,11 @@ class User(UserBase, Base):
...
@@ -202,11 +207,11 @@ class User(UserBase, Base):
default_language
=
Column
(
String
(
3
),
default
=
"all"
)
default_language
=
Column
(
String
(
3
),
default
=
"all"
)
mature_content
=
Column
(
Boolean
,
default
=
True
)
mature_content
=
Column
(
Boolean
,
default
=
True
)
'''
class
OAuth
(
OAuthConsumerMixin
,
Base
):
class
OAuth
(
OAuthConsumerMixin
,
Base
):
provider_user_id
=
Column
(
String
(
256
))
provider_user_id
=
Column
(
String
(
256
))
user_id
=
Column
(
Integer
,
ForeignKey
(
User
.
id
))
user_id
=
Column
(
Integer
,
ForeignKey
(
User
.
id
))
user = relationship(User)
'''
user
=
relationship
(
User
)
# Class for anonymous user is derived from User base and completly overrides methods and properties for the
# Class for anonymous user is derived from User base and completly overrides methods and properties for the
...
@@ -776,6 +781,13 @@ def clean_database():
...
@@ -776,6 +781,13 @@ def clean_database():
session
.
query
(
RemoteAuthToken
)
.
filter
(
now
>
RemoteAuthToken
.
expiration
)
.
delete
()
session
.
query
(
RemoteAuthToken
)
.
filter
(
now
>
RemoteAuthToken
.
expiration
)
.
delete
()
#get LDAP connection
def
get_ldap_connection
():
conn
=
ldap
.
initialize
(
'ldap://{}'
.
format
(
config
.
config_ldap_provider_url
))
return
conn
def
create_default_config
():
def
create_default_config
():
settings
=
Settings
()
settings
=
Settings
()
settings
.
mail_server
=
"mail.example.com"
settings
.
mail_server
=
"mail.example.com"
...
...
cps/web.py
View file @
c1ef1bcd
...
@@ -26,8 +26,6 @@ from flask import render_template, request, redirect, url_for, send_from_directo
...
@@ -26,8 +26,6 @@ from flask import render_template, request, redirect, url_for, send_from_directo
from
werkzeug.exceptions
import
default_exceptions
from
werkzeug.exceptions
import
default_exceptions
import
helper
import
helper
import
os
import
os
# from sqlalchemy.sql.expression import func
# from sqlalchemy.sql.expression import false
from
sqlalchemy.exc
import
IntegrityError
from
sqlalchemy.exc
import
IntegrityError
from
flask_login
import
login_user
,
logout_user
,
login_required
,
current_user
from
flask_login
import
login_user
,
logout_user
,
login_required
,
current_user
from
flask_babel
import
gettext
as
_
from
flask_babel
import
gettext
as
_
...
@@ -36,21 +34,31 @@ from werkzeug.datastructures import Headers
...
@@ -36,21 +34,31 @@ from werkzeug.datastructures import Headers
from
babel
import
Locale
as
LC
from
babel
import
Locale
as
LC
from
babel.dates
import
format_date
from
babel.dates
import
format_date
from
babel.core
import
UnknownLocaleError
from
babel.core
import
UnknownLocaleError
from
functools
import
wraps
import
base64
import
base64
from
sqlalchemy.sql
import
*
from
sqlalchemy.sql
import
*
import
json
import
json
import
datetime
import
datetime
from
iso639
import
languages
as
isoLanguages
from
iso639
import
languages
as
isoLanguages
import
os.path
import
re
import
re
import
db
import
db
import
gdriveutils
import
gdriveutils
from
redirect
import
redirect_back
from
redirect
import
redirect_back
from
cps
import
lm
,
babel
,
ub
,
config
,
get_locale
,
language_table
,
app
from
cps
import
lm
,
babel
,
ub
,
config
,
get_locale
,
language_table
,
app
from
pagination
import
Pagination
from
pagination
import
Pagination
# from admin import check_valid_domain
from
sqlalchemy.sql.expression
import
text
# from oauth_bb import oauth_check, register_user_with_oauth
from
oauth_bb
import
oauth_check
,
register_user_with_oauth
,
logout_oauth_user
,
get_oauth_status
'''try:
oauth_support = True
except ImportError:
oauth_support = False'''
try
:
import
ldap
ldap_support
=
True
except
ImportError
:
ldap_support
=
False
try
:
try
:
from
googleapiclient.errors
import
HttpError
from
googleapiclient.errors
import
HttpError
...
@@ -70,7 +78,7 @@ except ImportError:
...
@@ -70,7 +78,7 @@ except ImportError:
levenshtein_support
=
False
levenshtein_support
=
False
try
:
try
:
from
functools
import
reduce
from
functools
import
reduce
,
wraps
except
ImportError
:
except
ImportError
:
pass
# We're not using Python 3
pass
# We're not using Python 3
...
@@ -169,21 +177,6 @@ def remote_login_required(f):
...
@@ -169,21 +177,6 @@ def remote_login_required(f):
return
inner
return
inner
def
github_oauth_required
(
f
):
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
if
config
.
config_use_github_oauth
:
return
f
(
*
args
,
**
kwargs
)
if
request
.
is_xhr
:
data
=
{
'status'
:
'error'
,
'message'
:
'Not Found'
}
response
=
make_response
(
json
.
dumps
(
data
,
ensure_ascii
=
False
))
response
.
headers
[
"Content-Type"
]
=
"application/json; charset=utf-8"
return
response
,
404
abort
(
404
)
return
inner
def
google_oauth_required
(
f
):
def
google_oauth_required
(
f
):
@
wraps
(
f
)
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
def
inner
(
*
args
,
**
kwargs
):
...
@@ -1299,7 +1292,8 @@ def register():
...
@@ -1299,7 +1292,8 @@ def register():
try
:
try
:
ub
.
session
.
add
(
content
)
ub
.
session
.
add
(
content
)
ub
.
session
.
commit
()
ub
.
session
.
commit
()
# register_user_with_oauth(content)
if
oauth_support
:
register_user_with_oauth
(
content
)
helper
.
send_registration_mail
(
to_save
[
"email"
],
to_save
[
"nickname"
],
password
)
helper
.
send_registration_mail
(
to_save
[
"email"
],
to_save
[
"nickname"
],
password
)
except
Exception
:
except
Exception
:
ub
.
session
.
rollback
()
ub
.
session
.
rollback
()
...
@@ -1316,7 +1310,8 @@ def register():
...
@@ -1316,7 +1310,8 @@ def register():
flash
(
_
(
u"This username or e-mail address is already in use."
),
category
=
"error"
)
flash
(
_
(
u"This username or e-mail address is already in use."
),
category
=
"error"
)
return
render_title_template
(
'register.html'
,
title
=
_
(
u"register"
),
page
=
"register"
)
return
render_title_template
(
'register.html'
,
title
=
_
(
u"register"
),
page
=
"register"
)
# register_user_with_oauth()
if
oauth_support
:
register_user_with_oauth
()
return
render_title_template
(
'register.html'
,
config
=
config
,
title
=
_
(
u"register"
),
page
=
"register"
)
return
render_title_template
(
'register.html'
,
config
=
config
,
title
=
_
(
u"register"
),
page
=
"register"
)
...
@@ -1330,7 +1325,7 @@ def login():
...
@@ -1330,7 +1325,7 @@ def login():
form
=
request
.
form
.
to_dict
()
form
=
request
.
form
.
to_dict
()
user
=
ub
.
session
.
query
(
ub
.
User
)
.
filter
(
func
.
lower
(
ub
.
User
.
nickname
)
==
form
[
'username'
]
.
strip
()
.
lower
())
\
user
=
ub
.
session
.
query
(
ub
.
User
)
.
filter
(
func
.
lower
(
ub
.
User
.
nickname
)
==
form
[
'username'
]
.
strip
()
.
lower
())
\
.
first
()
.
first
()
if
config
.
config_use_ldap
and
user
:
'''
if config.config_use_ldap and user:
import ldap
import ldap
try:
try:
ub.User.try_login(form['username'], form['password'])
ub.User.try_login(form['username'], form['password'])
...
@@ -1341,7 +1336,8 @@ def login():
...
@@ -1341,7 +1336,8 @@ def login():
ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr)
ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr)
app.logger.info('LDAP Login failed for user "' + form['username'] + '" IP-adress: ' + ipAdress)
app.logger.info('LDAP Login failed for user "' + form['username'] + '" IP-adress: ' + ipAdress)
flash(_(u"Wrong Username or Password"), category="error")
flash(_(u"Wrong Username or Password"), category="error")
elif
user
and
check_password_hash
(
user
.
password
,
form
[
'password'
])
and
user
.
nickname
is
not
"Guest"
:
el'''
if
user
and
check_password_hash
(
user
.
password
,
form
[
'password'
])
and
user
.
nickname
is
not
"Guest"
:
login_user
(
user
,
remember
=
True
)
login_user
(
user
,
remember
=
True
)
flash
(
_
(
u"you are now logged in as: '
%(nickname)
s'"
,
nickname
=
user
.
nickname
),
category
=
"success"
)
flash
(
_
(
u"you are now logged in as: '
%(nickname)
s'"
,
nickname
=
user
.
nickname
),
category
=
"success"
)
return
redirect_back
(
url_for
(
"web.index"
))
return
redirect_back
(
url_for
(
"web.index"
))
...
@@ -1362,7 +1358,8 @@ def login():
...
@@ -1362,7 +1358,8 @@ def login():
def
logout
():
def
logout
():
if
current_user
is
not
None
and
current_user
.
is_authenticated
:
if
current_user
is
not
None
and
current_user
.
is_authenticated
:
logout_user
()
logout_user
()
# logout_oauth_user()
if
oauth_support
:
logout_oauth_user
()
return
redirect
(
url_for
(
'web.login'
))
return
redirect
(
url_for
(
'web.login'
))
...
@@ -1475,7 +1472,7 @@ def profile():
...
@@ -1475,7 +1472,7 @@ def profile():
downloads
=
list
()
downloads
=
list
()
languages
=
speaking_language
()
languages
=
speaking_language
()
translations
=
babel
.
list_translations
()
+
[
LC
(
'en'
)]
translations
=
babel
.
list_translations
()
+
[
LC
(
'en'
)]
oauth_status
=
None
# oauth_status =
get_oauth_status()
oauth_status
=
get_oauth_status
()
for
book
in
content
.
downloads
:
for
book
in
content
.
downloads
:
downloadBook
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
downloadBook
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
if
downloadBook
:
if
downloadBook
:
...
...
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