mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-30 23:03:02 +00:00 
			
		
		
		
	Merge pull request #17 from cervinko/feature-rights-management
add user-permission management
This commit is contained in:
		| @@ -60,6 +60,7 @@ TITLE_REGEX = check_setting_str(CFG, 'Advanced', 'TITLE_REGEX', '^(A|The|An|Der| | |||||||
| DEVELOPMENT = bool(check_setting_int(CFG, 'Advanced', 'DEVELOPMENT', 0)) | DEVELOPMENT = bool(check_setting_int(CFG, 'Advanced', 'DEVELOPMENT', 0)) | ||||||
| PUBLIC_REG = bool(check_setting_int(CFG, 'Advanced', 'PUBLIC_REG', 0)) | PUBLIC_REG = bool(check_setting_int(CFG, 'Advanced', 'PUBLIC_REG', 0)) | ||||||
| UPLOADING = bool(check_setting_int(CFG, 'Advanced', 'UPLOADING', 0)) | UPLOADING = bool(check_setting_int(CFG, 'Advanced', 'UPLOADING', 0)) | ||||||
|  | ANO_SHOW_BOOKS = bool(check_setting_int(CFG, 'Advanced', 'ANO_SHOW_BOOKS', 0)) | ||||||
|  |  | ||||||
| SYS_ENCODING="UTF-8" | SYS_ENCODING="UTF-8" | ||||||
|  |  | ||||||
| @@ -78,6 +79,8 @@ configval["DEVELOPMENT"] = DEVELOPMENT | |||||||
| configval["TITLE_REGEX"] = TITLE_REGEX | configval["TITLE_REGEX"] = TITLE_REGEX | ||||||
| configval["PUBLIC_REG"] = PUBLIC_REG | configval["PUBLIC_REG"] = PUBLIC_REG | ||||||
| configval["UPLOADING"] = UPLOADING | configval["UPLOADING"] = UPLOADING | ||||||
|  | configval["ANO_SHOW_BOOKS"] = ANO_SHOW_BOOKS | ||||||
|  |  | ||||||
|  |  | ||||||
| def save_config(configval): | def save_config(configval): | ||||||
|     new_config = ConfigObj() |     new_config = ConfigObj() | ||||||
| @@ -94,6 +97,7 @@ def save_config(configval): | |||||||
|     new_config['Advanced']['DEVELOPMENT'] = int(configval["DEVELOPMENT"]) |     new_config['Advanced']['DEVELOPMENT'] = int(configval["DEVELOPMENT"]) | ||||||
|     new_config['Advanced']['PUBLIC_REG'] = int(configval["PUBLIC_REG"]) |     new_config['Advanced']['PUBLIC_REG'] = int(configval["PUBLIC_REG"]) | ||||||
|     new_config['Advanced']['UPLOADING'] = int(configval["UPLOADING"]) |     new_config['Advanced']['UPLOADING'] = int(configval["UPLOADING"]) | ||||||
|  |     new_config['Advanced']['ANO_SHOW_BOOKS'] = int(configval["ANO_SHOW_BOOKS"]) | ||||||
|     new_config.write() |     new_config.write() | ||||||
|     return "Saved" |     return "Saved" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -154,7 +154,7 @@ | |||||||
|       </div> |       </div> | ||||||
|       {% endif %} |       {% endif %} | ||||||
|  |  | ||||||
|       {% if g.user.role %} |       {% if g.user.role_edit() %} | ||||||
|       <div class="btn-toolbar" role="toolbar"> |       <div class="btn-toolbar" role="toolbar"> | ||||||
|         <div class="btn-group" role="group" aria-label="Edit/Delete book"> |         <div class="btn-group" role="group" aria-label="Edit/Delete book"> | ||||||
|           <a href="{{ url_for('edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" role="button"><span class="glyphicon glyphicon-edit"></span> Edit metadata</a> |           <a href="{{ url_for('edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" role="button"><span class="glyphicon glyphicon-edit"></span> Edit metadata</a> | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ | |||||||
|           </ul> |           </ul> | ||||||
|           <ul class="nav navbar-nav navbar-right" id="main-nav"> |           <ul class="nav navbar-nav navbar-right" id="main-nav"> | ||||||
|             {% if g.user.is_authenticated() %} |             {% if g.user.is_authenticated() %} | ||||||
|               {% if g.user.role %} |               {% if g.user.role_upload() or g.user.role_admin()%} | ||||||
|               {% if g.allow_upload %} |               {% if g.allow_upload %} | ||||||
|                   <li> |                   <li> | ||||||
|                     <form id="form-upload" class="navbar-form" action="{{ url_for('upload') }}" method="post" enctype="multipart/form-data"> |                     <form id="form-upload" class="navbar-form" action="{{ url_for('upload') }}" method="post" enctype="multipart/form-data"> | ||||||
| @@ -74,7 +74,7 @@ | |||||||
|                   </li> |                   </li> | ||||||
|               {% endif %} |               {% endif %} | ||||||
|               {% endif %} |               {% endif %} | ||||||
|               {% if g.user.role %} |               {% if g.user.role_admin() %} | ||||||
|                 <li><a href="{{url_for('user_list')}}"><span class="glyphicon glyphicon-dashboard"></span> Admin</a></li> |                 <li><a href="{{url_for('user_list')}}"><span class="glyphicon glyphicon-dashboard"></span> Admin</a></li> | ||||||
|               {% endif %} |               {% endif %} | ||||||
|               <li><a href="{{url_for('profile')}}"><span class="glyphicon glyphicon-user"></span> {{g.user.nickname}}</a></li> |               <li><a href="{{url_for('profile')}}"><span class="glyphicon glyphicon-user"></span> {{g.user.nickname}}</a></li> | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| <div class="discover"> | <div class="discover"> | ||||||
|   <h1>{{title}}</h1> |   <h1>{{title}}</h1> | ||||||
|   <form role="form" method="POST"> |   <form role="form" method="POST"> | ||||||
|     {% if g.user and g.user.role and new_user %} |     {% if g.user and g.user.role_admin() and new_user %} | ||||||
|     <div class="form-group required"> |     <div class="form-group required"> | ||||||
|       <label for="nickname">Username</label> |       <label for="nickname">Username</label> | ||||||
|       <input type="text" class="form-control" name="nickname" id="nickname" value="{{ content.nickname if content.nickname != None }}"> |       <input type="text" class="form-control" name="nickname" id="nickname" value="{{ content.nickname if content.nickname != None }}"> | ||||||
| @@ -13,21 +13,39 @@ | |||||||
|       <label for="email">Email address</label> |       <label for="email">Email address</label> | ||||||
|       <input type="email" class="form-control" name="email" id="email" value="{{ content.email if content.email != None }}" required>  |       <input type="email" class="form-control" name="email" id="email" value="{{ content.email if content.email != None }}" required>  | ||||||
|     </div> |     </div> | ||||||
|  |     {% if g.user and g.user.role_passwd() or g.user.role_admin()%} | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="password">Password</label> |       <label for="password">Password</label> | ||||||
|       <input type="password" class="form-control" name="password" id="password" value=""> |       <input type="password" class="form-control" name="password" id="password" value=""> | ||||||
|     </div> |     </div> | ||||||
|  |     {% endif %} | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="kindle_mail">Kindle E-Mail</label> |       <label for="kindle_mail">Kindle E-Mail</label> | ||||||
|       <input type="text" class="form-control" name="kindle_mail" id="kindle_mail" value="{{ content.kindle_mail if content.kindle_mail != None }}"> |       <input type="text" class="form-control" name="kindle_mail" id="kindle_mail" value="{{ content.kindle_mail if content.kindle_mail != None }}"> | ||||||
|     </div> |     </div> | ||||||
|     {% if g.user and g.user.role and not profile %} |     {% if g.user and g.user.role_admin() and not profile %} | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="user_role">Admin user</label> |       <label for="admin_role">Admin user</label> | ||||||
|       <input type="checkbox" name="admin_user" id="admin_user" {% if content.role %}checked{% endif %}> |       <input type="checkbox" name="admin_role" id="admin_role" {% if content.role_admin() %}checked{% endif %}> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="download_role">Allow Downloads</label> | ||||||
|  |       <input type="checkbox" name="download_role" id="download_role" {% if content.role_download() %}checked{% endif %}> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="upload_role">Allow Uploads</label> | ||||||
|  |       <input type="checkbox" name="upload_role" id="upload_role" {% if content.role_upload() %}checked{% endif %}> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="edit_role">Allow Edit</label> | ||||||
|  |       <input type="checkbox" name="edit_role" id="edit_role" {% if content.role_edit() %}checked{% endif %}> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="passwd_role">Allow Changing Password</label> | ||||||
|  |       <input type="checkbox" name="passwd_role" id="passwd_role" {% if content.role_passwd() %}checked{% endif %}> | ||||||
|     </div> |     </div> | ||||||
|     {% endif %} |     {% endif %} | ||||||
|     {% if g.user and g.user.role and not profile and not new_user %} |     {% if g.user and g.user.role_admin() and not profile and not new_user %} | ||||||
|     <div class="checkbox"> |     <div class="checkbox"> | ||||||
|       <label> |       <label> | ||||||
|         <input type="checkbox" name="delete"> Delete this user |         <input type="checkbox" name="delete"> Delete this user | ||||||
|   | |||||||
| @@ -9,6 +9,11 @@ | |||||||
|         <th>Kindle</th> |         <th>Kindle</th> | ||||||
|         <th>DLS</th> |         <th>DLS</th> | ||||||
|         <th>Admin</th> |         <th>Admin</th> | ||||||
|  |         <th>Download</th> | ||||||
|  |         <th>Upload</th> | ||||||
|  |         <th>Edit</th> | ||||||
|  |         <th>Passwd</th> | ||||||
|  |  | ||||||
|     </tr> |     </tr> | ||||||
|     {% for user in content %} |     {% for user in content %} | ||||||
|       <tr> |       <tr> | ||||||
| @@ -16,7 +21,12 @@ | |||||||
|         <td>{{user.email}}</td> |         <td>{{user.email}}</td> | ||||||
|         <td>{{user.kindle_mail}}</td> |         <td>{{user.kindle_mail}}</td> | ||||||
|         <td>{{user.downloads.count()}}</td> |         <td>{{user.downloads.count()}}</td> | ||||||
|         <td>{% if user.role %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> |         <td>{% if user.role_admin() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> | ||||||
|  |         <td>{% if user.role_download() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> | ||||||
|  |         <td>{% if user.role_upload() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> | ||||||
|  |         <td>{% if user.role_edit() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> | ||||||
|  |         <td>{% if user.role_passwd() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td> | ||||||
|  |  | ||||||
|     {% endfor %} |     {% endfor %} | ||||||
|   </table> |   </table> | ||||||
|     <div class="btn btn-default"><a href="{{url_for('new_user')}}">Add new user</a></div> |     <div class="btn btn-default"><a href="{{url_for('new_user')}}">Add new user</a></div> | ||||||
|   | |||||||
							
								
								
									
										227
									
								
								cps/ub.py
									
									
									
									
									
								
							
							
						
						
									
										227
									
								
								cps/ub.py
									
									
									
									
									
								
							| @@ -14,157 +14,186 @@ Base = declarative_base() | |||||||
|  |  | ||||||
| ROLE_USER = 0 | ROLE_USER = 0 | ||||||
| ROLE_ADMIN = 1 | ROLE_ADMIN = 1 | ||||||
|  | ROLE_DOWNLOAD = 2 | ||||||
|  | ROLE_UPLOAD = 4  | ||||||
|  | ROLE_EDIT = 8 | ||||||
|  | ROLE_PASSWD = 16 | ||||||
| DEFAULT_PASS = "admin123" | DEFAULT_PASS = "admin123" | ||||||
|  |  | ||||||
| class User(Base): | class User(Base): | ||||||
| 	__tablename__ = 'user' |     __tablename__ = 'user' | ||||||
|  |  | ||||||
| 	id = Column(Integer, primary_key = True) |     id = Column(Integer, primary_key = True) | ||||||
| 	nickname = Column(String(64), unique = True) |     nickname = Column(String(64), unique = True) | ||||||
| 	email = Column(String(120), unique = True, default = "") |     email = Column(String(120), unique = True, default = "") | ||||||
| 	role = Column(SmallInteger, default = ROLE_USER) |     role = Column(SmallInteger, default = ROLE_USER) | ||||||
| 	password = Column(String) |     password = Column(String) | ||||||
| 	kindle_mail = Column(String(120), default="") |     kindle_mail = Column(String(120), default="") | ||||||
| 	shelf = relationship('Shelf', backref = 'user', lazy = 'dynamic') |     shelf = relationship('Shelf', backref = 'user', lazy = 'dynamic') | ||||||
| 	whislist = relationship('Whislist', backref = 'user', lazy = 'dynamic') |     whislist = relationship('Whislist', backref = 'user', lazy = 'dynamic') | ||||||
| 	downloads = relationship('Downloads', backref= 'user', lazy = 'dynamic') |     downloads = relationship('Downloads', backref= 'user', lazy = 'dynamic') | ||||||
|  |  | ||||||
| 	def is_authenticated(self): |     def is_authenticated(self): | ||||||
| 		return True |         return True | ||||||
|  |     def role_admin(self): | ||||||
|  |         if self.role is not None: | ||||||
|  |             return True if self.role & ROLE_ADMIN == ROLE_ADMIN else False | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  |     def role_download(self): | ||||||
|  |         if self.role is not None: | ||||||
|  |             return True if self.role & ROLE_DOWNLOAD == ROLE_DOWNLOAD else False | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  |     def role_upload(self): | ||||||
|  |         if self.role is not None: | ||||||
|  |             return True if self.role & ROLE_UPLOAD == ROLE_UPLOAD else False | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  |     def role_edit(self): | ||||||
|  |         if self.role is not None: | ||||||
|  |             return True if self.role & ROLE_EDIT == ROLE_EDIT else False | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  |     def role_passwd(self): | ||||||
|  |         if self.role is not None: | ||||||
|  |             return True if self.role & ROLE_PASSWD == ROLE_PASSWD else False | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  |  | ||||||
| 	def is_active(self): |     def is_active(self): | ||||||
| 		return True |         return True | ||||||
|  |  | ||||||
| 	def is_anonymous(self): |     def is_anonymous(self): | ||||||
| 		return False |         return False | ||||||
|  |  | ||||||
| 	def get_id(self): |     def get_id(self): | ||||||
| 		return unicode(self.id) |         return unicode(self.id) | ||||||
|  |  | ||||||
| 	def __repr__(self): |     def __repr__(self): | ||||||
| 		return '<User %r>' % (self.nickname) |         return '<User %r>' % (self.nickname) | ||||||
|  |  | ||||||
| class Shelf(Base): | class Shelf(Base): | ||||||
| 	__tablename__ = 'shelf' |     __tablename__ = 'shelf' | ||||||
|  |  | ||||||
| 	id = Column(Integer, primary_key = True) |     id = Column(Integer, primary_key = True) | ||||||
| 	name = Column(String) |     name = Column(String) | ||||||
| 	is_public = Column(Integer, default=0) |     is_public = Column(Integer, default=0) | ||||||
| 	user_id = Column(Integer, ForeignKey('user.id')) |     user_id = Column(Integer, ForeignKey('user.id')) | ||||||
|  |  | ||||||
| 	def __repr__(self): |     def __repr__(self): | ||||||
| 		return '<Shelf %r>' % (self.name) |         return '<Shelf %r>' % (self.name) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Whislist(Base): | class Whislist(Base): | ||||||
| 	__tablename__ = "wishlist" |     __tablename__ = "wishlist" | ||||||
|  |  | ||||||
| 	id = Column(Integer, primary_key=True) |     id = Column(Integer, primary_key=True) | ||||||
| 	name = Column(String) |     name = Column(String) | ||||||
| 	is_public = Column(String) |     is_public = Column(String) | ||||||
| 	user_id = Column(Integer, ForeignKey('user.id')) |     user_id = Column(Integer, ForeignKey('user.id')) | ||||||
|  |  | ||||||
| 	def __init__(self): |     def __init__(self): | ||||||
| 		pass |         pass | ||||||
|  |  | ||||||
| 	def __repr__(self): |     def __repr__(self): | ||||||
| 		return '<Whislist %r>' % (self.name) |         return '<Whislist %r>' % (self.name) | ||||||
|  |  | ||||||
|  |  | ||||||
| class BookShelf(Base): | class BookShelf(Base): | ||||||
| 	__tablename__ = 'book_shelf_link' |     __tablename__ = 'book_shelf_link' | ||||||
|  |  | ||||||
| 	id = Column(Integer, primary_key=True) |     id = Column(Integer, primary_key=True) | ||||||
| 	book_id = Column(Integer) |     book_id = Column(Integer) | ||||||
| 	shelf = Column(Integer, ForeignKey('shelf.id')) |     shelf = Column(Integer, ForeignKey('shelf.id')) | ||||||
|  |  | ||||||
| 	def __repr__(self): |     def __repr__(self): | ||||||
| 		return '<Book %r>' % (self.id) |         return '<Book %r>' % (self.id) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Downloads(Base): | class Downloads(Base): | ||||||
| 	__tablename__ = 'downloads' |     __tablename__ = 'downloads' | ||||||
|  |  | ||||||
| 	id = Column(Integer, primary_key=True) |     id = Column(Integer, primary_key=True) | ||||||
| 	book_id = Column(Integer) |     book_id = Column(Integer) | ||||||
| 	user_id = Column(Integer, ForeignKey('user.id')) |     user_id = Column(Integer, ForeignKey('user.id')) | ||||||
|  |  | ||||||
| 	def __repr__(self): |     def __repr__(self): | ||||||
| 		return '<Download %r' % (self.book_id) |         return '<Download %r' % (self.book_id) | ||||||
|  |  | ||||||
| class Whish(Base): | class Whish(Base): | ||||||
| 	__tablename__ = 'whish' |     __tablename__ = 'whish' | ||||||
|  |  | ||||||
| 	id = Column(Integer, primary_key=True) |     id = Column(Integer, primary_key=True) | ||||||
| 	title = Column(String) |     title = Column(String) | ||||||
| 	url = Column(String) |     url = Column(String) | ||||||
| 	wishlist = Column(Integer, ForeignKey('wishlist.id')) |     wishlist = Column(Integer, ForeignKey('wishlist.id')) | ||||||
|  |  | ||||||
| 	def __repr__(self): |     def __repr__(self): | ||||||
| 		return '<Whish %r>' % (self.title) |         return '<Whish %r>' % (self.title) | ||||||
|  |  | ||||||
| class Settings(Base): | class Settings(Base): | ||||||
| 	__tablename__ = 'settings' |     __tablename__ = 'settings' | ||||||
|  |  | ||||||
| 	id = Column(Integer, primary_key=True) |     id = Column(Integer, primary_key=True) | ||||||
| 	mail_server = Column(String) |     mail_server = Column(String) | ||||||
| 	mail_port = Column(Integer, default = 25) |     mail_port = Column(Integer, default = 25) | ||||||
| 	mail_use_ssl = Column(SmallInteger, default = 0) |     mail_use_ssl = Column(SmallInteger, default = 0) | ||||||
| 	mail_login = Column(String) |     mail_login = Column(String) | ||||||
| 	mail_password = Column(String) |     mail_password = Column(String) | ||||||
| 	mail_from = Column(String) |     mail_from = Column(String) | ||||||
|  |  | ||||||
| 	def __repr__(self): |     def __repr__(self): | ||||||
| 		#return '<Smtp %r>' % (self.mail_server) |         #return '<Smtp %r>' % (self.mail_server) | ||||||
| 		pass |         pass | ||||||
|  |  | ||||||
| def create_default_config(): | def create_default_config(): | ||||||
| 	settings = Settings() |     settings = Settings() | ||||||
| 	settings.mail_server = "mail.example.com" |     settings.mail_server = "mail.example.com" | ||||||
| 	settings.mail_port = 25 |     settings.mail_port = 25 | ||||||
| 	settings.mail_use_ssl = 0 |     settings.mail_use_ssl = 0 | ||||||
| 	settings.mail_login = "mail@example.com" |     settings.mail_login = "mail@example.com" | ||||||
| 	settings.mail_password = "mypassword" |     settings.mail_password = "mypassword" | ||||||
| 	settings.mail_from = "automailer <mail@example.com>" |     settings.mail_from = "automailer <mail@example.com>" | ||||||
|  |  | ||||||
| 	session.add(settings) |     session.add(settings) | ||||||
| 	session.commit() |     session.commit() | ||||||
|  |  | ||||||
| def get_mail_settings(): | def get_mail_settings(): | ||||||
| 	settings = session.query(Settings).first() |     settings = session.query(Settings).first() | ||||||
|  |  | ||||||
| 	if not settings: |     if not settings: | ||||||
| 	  return {} |       return {} | ||||||
|  |  | ||||||
| 	data = { |     data = { | ||||||
| 	  'mail_server': settings.mail_server, |       'mail_server': settings.mail_server, | ||||||
| 	  'mail_port': settings.mail_port, |       'mail_port': settings.mail_port, | ||||||
| 	  'mail_use_ssl': settings.mail_use_ssl, |       'mail_use_ssl': settings.mail_use_ssl, | ||||||
| 	  'mail_login': settings.mail_login, |       'mail_login': settings.mail_login, | ||||||
| 	  'mail_password': settings.mail_password, |       'mail_password': settings.mail_password, | ||||||
| 	  'mail_from': settings.mail_from |       'mail_from': settings.mail_from | ||||||
| 	} |     } | ||||||
|  |  | ||||||
| 	return data |     return data | ||||||
|  |  | ||||||
| def create_admin_user(): | def create_admin_user(): | ||||||
| 	user = User() |     user = User() | ||||||
| 	user.nickname = "admin" |     user.nickname = "admin" | ||||||
| 	user.role = 1 |     user.role = ROLE_USER + ROLE_ADMIN + ROLE_DOWNLOAD + ROLE_UPLOAD + ROLE_EDIT + ROLE_PASSWD | ||||||
| 	user.password = generate_password_hash(DEFAULT_PASS) |     user.password = generate_password_hash(DEFAULT_PASS) | ||||||
|  |  | ||||||
| 	session.add(user) |     session.add(user) | ||||||
| 	session.commit() |     session.commit() | ||||||
|  |  | ||||||
| Session = sessionmaker() | Session = sessionmaker() | ||||||
| Session.configure(bind=engine) | Session.configure(bind=engine) | ||||||
| session = Session() | session = Session() | ||||||
|  |  | ||||||
| if not os.path.exists(dbpath): | if not os.path.exists(dbpath): | ||||||
| 	try: |     try: | ||||||
| 		Base.metadata.create_all(engine) |         Base.metadata.create_all(engine) | ||||||
| 		create_default_config() |         create_default_config() | ||||||
| 		create_admin_user() |         create_admin_user() | ||||||
| 	except Exception: |     except Exception: | ||||||
| 		pass |         pass | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										138
									
								
								cps/web.py
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								cps/web.py
									
									
									
									
									
								
							| @@ -14,7 +14,7 @@ from sqlalchemy.sql.expression import func | |||||||
| from sqlalchemy.sql.expression import false | from sqlalchemy.sql.expression import false | ||||||
| from sqlalchemy.exc import IntegrityError | from sqlalchemy.exc import IntegrityError | ||||||
| from math import ceil | from math import ceil | ||||||
| from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user | from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user, AnonymousUserMixin | ||||||
| from flask.ext.principal import Principal, Identity, AnonymousIdentity, identity_changed | from flask.ext.principal import Principal, Identity, AnonymousIdentity, identity_changed | ||||||
| import requests, zipfile | import requests, zipfile | ||||||
| from werkzeug.security import generate_password_hash, check_password_hash | from werkzeug.security import generate_password_hash, check_password_hash | ||||||
| @@ -43,9 +43,23 @@ app.logger.info('Starting Calibre Web...') | |||||||
|  |  | ||||||
| Principal(app) | Principal(app) | ||||||
|  |  | ||||||
|  | class Anonymous(AnonymousUserMixin): | ||||||
|  |     def __init__(self): | ||||||
|  |         self.nickname = 'Guest' | ||||||
|  |         self.role = -1 | ||||||
|  |     def role_admin(self): | ||||||
|  |         return False | ||||||
|  |     def role_download(self): | ||||||
|  |         return False | ||||||
|  |     def role_upload(self): | ||||||
|  |         return False | ||||||
|  |     def role_edit(self): | ||||||
|  |         return False | ||||||
|  |  | ||||||
| lm = LoginManager(app) | lm = LoginManager(app) | ||||||
| lm.init_app(app) | lm.init_app(app) | ||||||
| lm.login_view = 'login' | lm.login_view = 'login' | ||||||
|  | lm.anonymous_user = Anonymous | ||||||
|  |  | ||||||
| app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' | app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' | ||||||
|  |  | ||||||
| @@ -82,12 +96,13 @@ def authenticate(): | |||||||
|     'You have to login with proper credentials', 401, |     'You have to login with proper credentials', 401, | ||||||
|     {'WWW-Authenticate': 'Basic realm="Login Required"'}) |     {'WWW-Authenticate': 'Basic realm="Login Required"'}) | ||||||
|  |  | ||||||
| def requires_basic_auth(f): | def requires_basic_auth_if_no_ano(f): | ||||||
|     @wraps(f) |     @wraps(f) | ||||||
|     def decorated(*args, **kwargs): |     def decorated(*args, **kwargs): | ||||||
|         auth = request.authorization |         auth = request.authorization | ||||||
|         if not auth or not check_auth(auth.username, auth.password): |         if config.ANO_SHOW_BOOKS != 1: | ||||||
|             return authenticate() |             if not auth or not check_auth(auth.username, auth.password): | ||||||
|  |                 return authenticate() | ||||||
|         return f(*args, **kwargs) |         return f(*args, **kwargs) | ||||||
|     return decorated |     return decorated | ||||||
|  |  | ||||||
| @@ -132,6 +147,11 @@ def url_for_other_page(page): | |||||||
|  |  | ||||||
| app.jinja_env.globals['url_for_other_page'] = url_for_other_page | app.jinja_env.globals['url_for_other_page'] = url_for_other_page | ||||||
|  |  | ||||||
|  | def login_required_if_no_ano(func): | ||||||
|  |     if config.ANO_SHOW_BOOKS == 1: | ||||||
|  |         return func | ||||||
|  |     return login_required(func) | ||||||
|  |  | ||||||
| ## custom jinja filters | ## custom jinja filters | ||||||
| @app.template_filter('shortentitle') | @app.template_filter('shortentitle') | ||||||
| def shortentitle_filter(s): | def shortentitle_filter(s): | ||||||
| @@ -147,7 +167,29 @@ def admin_required(f): | |||||||
|     """ |     """ | ||||||
|     @wraps(f) |     @wraps(f) | ||||||
|     def inner(*args, **kwargs): |     def inner(*args, **kwargs): | ||||||
|         if int(current_user.role) == 1: |         if current_user.role_admin(): | ||||||
|  |             return f(*args, **kwargs) | ||||||
|  |         abort(403) | ||||||
|  |     return inner | ||||||
|  |  | ||||||
|  | def download_required(f): | ||||||
|  |     @wraps(f) | ||||||
|  |     def inner(*args, **kwargs): | ||||||
|  |         if current_user.role_download() or current_user.role_admin(): | ||||||
|  |             return f(*args, **kwargs) | ||||||
|  |         abort(403) | ||||||
|  |     return inner | ||||||
|  | def upload_required(f): | ||||||
|  |     @wraps(f) | ||||||
|  |     def inner(*args, **kwargs): | ||||||
|  |         if current_user.role_upload() or current_user.role_admin(): | ||||||
|  |             return f(*args, **kwargs) | ||||||
|  |         abort(403) | ||||||
|  |     return inner | ||||||
|  | def edit_required(f): | ||||||
|  |     @wraps(f) | ||||||
|  |     def inner(*args, **kwargs): | ||||||
|  |         if current_user.role_edit() or current_user.role_admin(): | ||||||
|             return f(*args, **kwargs) |             return f(*args, **kwargs) | ||||||
|         abort(403) |         abort(403) | ||||||
|     return inner |     return inner | ||||||
| @@ -160,6 +202,7 @@ def before_request(): | |||||||
|     g.allow_upload = config.UPLOADING |     g.allow_upload = config.UPLOADING | ||||||
|  |  | ||||||
| @app.route("/feed") | @app.route("/feed") | ||||||
|  | @requires_basic_auth_if_no_ano | ||||||
| def feed_index(): | def feed_index(): | ||||||
|     xml = render_template('index.xml') |     xml = render_template('index.xml') | ||||||
|     response= make_response(xml) |     response= make_response(xml) | ||||||
| @@ -167,6 +210,7 @@ def feed_index(): | |||||||
|     return response |     return response | ||||||
|  |  | ||||||
| @app.route("/feed/osd") | @app.route("/feed/osd") | ||||||
|  | @requires_basic_auth_if_no_ano | ||||||
| def feed_osd(): | def feed_osd(): | ||||||
|     xml = render_template('osd.xml') |     xml = render_template('osd.xml') | ||||||
|     response= make_response(xml) |     response= make_response(xml) | ||||||
| @@ -174,6 +218,7 @@ def feed_osd(): | |||||||
|     return response |     return response | ||||||
|  |  | ||||||
| @app.route("/feed/search", methods=["GET"]) | @app.route("/feed/search", methods=["GET"]) | ||||||
|  | @requires_basic_auth_if_no_ano | ||||||
| def feed_search(): | def feed_search(): | ||||||
|     term = request.args.get("query") |     term = request.args.get("query") | ||||||
|     if term: |     if term: | ||||||
| @@ -187,6 +232,7 @@ def feed_search(): | |||||||
|     return response |     return response | ||||||
|  |  | ||||||
| @app.route("/feed/new") | @app.route("/feed/new") | ||||||
|  | @requires_basic_auth_if_no_ano | ||||||
| def feed_new(): | def feed_new(): | ||||||
|     off = request.args.get("start_index") |     off = request.args.get("start_index") | ||||||
|     if off: |     if off: | ||||||
| @@ -201,6 +247,7 @@ def feed_new(): | |||||||
|  |  | ||||||
|  |  | ||||||
| @app.route("/feed/discover") | @app.route("/feed/discover") | ||||||
|  | @requires_basic_auth_if_no_ano | ||||||
| def feed_discover(): | def feed_discover(): | ||||||
|     off = request.args.get("start_index") |     off = request.args.get("start_index") | ||||||
|     if off: |     if off: | ||||||
| @@ -214,6 +261,7 @@ def feed_discover(): | |||||||
|     return response |     return response | ||||||
|  |  | ||||||
| @app.route("/feed/hot") | @app.route("/feed/hot") | ||||||
|  | @requires_basic_auth_if_no_ano | ||||||
| def feed_hot(): | def feed_hot(): | ||||||
|     off = request.args.get("start_index") |     off = request.args.get("start_index") | ||||||
|     if off: |     if off: | ||||||
| @@ -228,7 +276,8 @@ def feed_hot(): | |||||||
|     return response |     return response | ||||||
|  |  | ||||||
| @app.route("/feed/download/<int:book_id>/<format>") | @app.route("/feed/download/<int:book_id>/<format>") | ||||||
| @requires_basic_auth | @requires_basic_auth_if_no_ano | ||||||
|  | @download_required | ||||||
| def get_opds_download_link(book_id, format): | def get_opds_download_link(book_id, format): | ||||||
|     format = format.split(".")[0] |     format = format.split(".")[0] | ||||||
|     book = db.session.query(db.Books).filter(db.Books.id == book_id).first() |     book = db.session.query(db.Books).filter(db.Books.id == book_id).first() | ||||||
| @@ -244,6 +293,7 @@ def get_opds_download_link(book_id, format): | |||||||
|     return response |     return response | ||||||
|      |      | ||||||
| @app.route("/get_authors_json", methods = ['GET', 'POST']) | @app.route("/get_authors_json", methods = ['GET', 'POST']) | ||||||
|  | @login_required_if_no_ano | ||||||
| def get_authors_json():  | def get_authors_json():  | ||||||
|     if request.method == "GET": |     if request.method == "GET": | ||||||
|         query = request.args.get('q') |         query = request.args.get('q') | ||||||
| @@ -252,6 +302,7 @@ def get_authors_json(): | |||||||
|         return json_dumps |         return json_dumps | ||||||
|  |  | ||||||
| @app.route("/get_tags_json", methods = ['GET', 'POST']) | @app.route("/get_tags_json", methods = ['GET', 'POST']) | ||||||
|  | @login_required_if_no_ano | ||||||
| def get_tags_json():  | def get_tags_json():  | ||||||
|     if request.method == "GET": |     if request.method == "GET": | ||||||
|         query = request.args.get('q') |         query = request.args.get('q') | ||||||
| @@ -260,6 +311,7 @@ def get_tags_json(): | |||||||
|         return json_dumps |         return json_dumps | ||||||
|          |          | ||||||
| @app.route("/get_series_json", methods = ['GET', 'POST']) | @app.route("/get_series_json", methods = ['GET', 'POST']) | ||||||
|  | @login_required_if_no_ano | ||||||
| def get_series_json():  | def get_series_json():  | ||||||
|     if request.method == "GET": |     if request.method == "GET": | ||||||
|         query = request.args.get('q') |         query = request.args.get('q') | ||||||
| @@ -269,6 +321,7 @@ def get_series_json(): | |||||||
|  |  | ||||||
| @app.route("/", defaults={'page': 1}) | @app.route("/", defaults={'page': 1}) | ||||||
| @app.route('/page/<int:page>') | @app.route('/page/<int:page>') | ||||||
|  | @login_required_if_no_ano | ||||||
| def index(page): | def index(page): | ||||||
|     random = db.session.query(db.Books).order_by(func.random()).limit(config.RANDOM_BOOKS) |     random = db.session.query(db.Books).order_by(func.random()).limit(config.RANDOM_BOOKS) | ||||||
|     if page == 1: |     if page == 1: | ||||||
| @@ -281,6 +334,7 @@ def index(page): | |||||||
|  |  | ||||||
| @app.route("/hot", defaults={'page': 1}) | @app.route("/hot", defaults={'page': 1}) | ||||||
| @app.route('/hot/page/<int:page>') | @app.route('/hot/page/<int:page>') | ||||||
|  | @login_required_if_no_ano | ||||||
| def hot_books(page): | def hot_books(page): | ||||||
|     random = db.session.query(db.Books).filter(false()) |     random = db.session.query(db.Books).filter(false()) | ||||||
|     off = int(int(6) * (page - 1)) |     off = int(int(6) * (page - 1)) | ||||||
| @@ -298,12 +352,14 @@ def hot_books(page): | |||||||
|         return render_template('index.html', random=random, entries=entries, title="Hot Books (most downloaded)") |         return render_template('index.html', random=random, entries=entries, title="Hot Books (most downloaded)") | ||||||
|  |  | ||||||
| @app.route("/stats") | @app.route("/stats") | ||||||
|  | @login_required | ||||||
| def stats(): | def stats(): | ||||||
|     counter = len(db.session.query(db.Books).all()) |     counter = len(db.session.query(db.Books).all()) | ||||||
|     return render_template('stats.html', counter=counter, title="Statistics") |     return render_template('stats.html', counter=counter, title="Statistics") | ||||||
|  |  | ||||||
| @app.route("/discover", defaults={'page': 1}) | @app.route("/discover", defaults={'page': 1}) | ||||||
| @app.route('/discover/page/<int:page>') | @app.route('/discover/page/<int:page>') | ||||||
|  | @login_required_if_no_ano | ||||||
| def discover(page): | def discover(page): | ||||||
|     if page == 1: |     if page == 1: | ||||||
|         entries = db.session.query(db.Books).order_by(func.randomblob(2)).limit(config.NEWEST_BOOKS) |         entries = db.session.query(db.Books).order_by(func.randomblob(2)).limit(config.NEWEST_BOOKS) | ||||||
| @@ -314,6 +370,7 @@ def discover(page): | |||||||
|     return render_template('discover.html', entries=entries, pagination=pagination, title="Random Books") |     return render_template('discover.html', entries=entries, pagination=pagination, title="Random Books") | ||||||
|  |  | ||||||
| @app.route("/book/<int:id>") | @app.route("/book/<int:id>") | ||||||
|  | @login_required_if_no_ano | ||||||
| def show_book(id): | def show_book(id): | ||||||
|     entries = db.session.query(db.Books).filter(db.Books.id == id).first() |     entries = db.session.query(db.Books).filter(db.Books.id == id).first() | ||||||
|     cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() |     cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() | ||||||
| @@ -324,11 +381,13 @@ def show_book(id): | |||||||
|     return render_template('detail.html', entry=entries,  cc=cc, title=entries.title, books_shelfs=book_in_shelfs) |     return render_template('detail.html', entry=entries,  cc=cc, title=entries.title, books_shelfs=book_in_shelfs) | ||||||
|  |  | ||||||
| @app.route("/category") | @app.route("/category") | ||||||
|  | @login_required_if_no_ano | ||||||
| def category_list(): | def category_list(): | ||||||
|     entries = db.session.query(db.Tags).order_by(db.Tags.name).all() |     entries = db.session.query(db.Tags).order_by(db.Tags.name).all() | ||||||
|     return render_template('categories.html', entries=entries, title="Category list") |     return render_template('categories.html', entries=entries, title="Category list") | ||||||
|  |  | ||||||
| @app.route("/category/<name>") | @app.route("/category/<name>") | ||||||
|  | @login_required_if_no_ano | ||||||
| def category(name): | def category(name): | ||||||
|     random = db.session.query(db.Books).filter(false()) |     random = db.session.query(db.Books).filter(false()) | ||||||
|     if name != "all": |     if name != "all": | ||||||
| @@ -338,6 +397,7 @@ def category(name): | |||||||
|     return render_template('index.html', random=random, entries=entries, title="Category: %s" % name) |     return render_template('index.html', random=random, entries=entries, title="Category: %s" % name) | ||||||
|  |  | ||||||
| @app.route("/series/<name>") | @app.route("/series/<name>") | ||||||
|  | @login_required_if_no_ano | ||||||
| def series(name): | def series(name): | ||||||
|     random = db.session.query(db.Books).filter(false()) |     random = db.session.query(db.Books).filter(false()) | ||||||
|     entries = db.session.query(db.Books).filter(db.Books.series.any(db.Series.name.like("%" +name + "%" ))).order_by(db.Books.series_index).all() |     entries = db.session.query(db.Books).filter(db.Books.series.any(db.Series.name.like("%" +name + "%" ))).order_by(db.Books.series_index).all() | ||||||
| @@ -345,12 +405,14 @@ def series(name): | |||||||
|  |  | ||||||
|  |  | ||||||
| @app.route("/admin/") | @app.route("/admin/") | ||||||
|  | @login_required | ||||||
| def admin(): | def admin(): | ||||||
|     #return "Admin ONLY!" |     #return "Admin ONLY!" | ||||||
|     abort(403) |     abort(403) | ||||||
|  |  | ||||||
|  |  | ||||||
| @app.route("/search", methods=["GET"]) | @app.route("/search", methods=["GET"]) | ||||||
|  | @login_required_if_no_ano | ||||||
| def search(): | def search(): | ||||||
|     term = request.args.get("query") |     term = request.args.get("query") | ||||||
|     if term: |     if term: | ||||||
| @@ -361,17 +423,20 @@ def search(): | |||||||
|         return render_template('search.html', searchterm="") |         return render_template('search.html', searchterm="") | ||||||
|  |  | ||||||
| @app.route("/author") | @app.route("/author") | ||||||
|  | @login_required_if_no_ano | ||||||
| def author_list(): | def author_list(): | ||||||
|     entries = db.session.query(db.Authors).order_by(db.Authors.sort).all() |     entries = db.session.query(db.Authors).order_by(db.Authors.sort).all() | ||||||
|     return render_template('authors.html', entries=entries, title="Author list") |     return render_template('authors.html', entries=entries, title="Author list") | ||||||
|  |  | ||||||
| @app.route("/author/<name>") | @app.route("/author/<name>") | ||||||
|  | @login_required_if_no_ano | ||||||
| def author(name): | def author(name): | ||||||
|     random = db.session.query(db.Books).filter(false()) |     random = db.session.query(db.Books).filter(false()) | ||||||
|     entries = db.session.query(db.Books).filter(db.Books.authors.any(db.Authors.name.like("%" +  name + "%"))).all() |     entries = db.session.query(db.Books).filter(db.Books.authors.any(db.Authors.name.like("%" +  name + "%"))).all() | ||||||
|     return render_template('index.html', random=random, entries=entries, title="Author: %s" % name) |     return render_template('index.html', random=random, entries=entries, title="Author: %s" % name) | ||||||
|  |  | ||||||
| @app.route("/cover/<path:cover_path>") | @app.route("/cover/<path:cover_path>") | ||||||
|  | @login_required_if_no_ano | ||||||
| def get_cover(cover_path): | def get_cover(cover_path): | ||||||
|     return send_from_directory(os.path.join(config.DB_ROOT, cover_path), "cover.jpg") |     return send_from_directory(os.path.join(config.DB_ROOT, cover_path), "cover.jpg") | ||||||
|  |  | ||||||
| @@ -399,6 +464,7 @@ def read_book(book_id): | |||||||
|  |  | ||||||
| @app.route("/download/<int:book_id>/<format>") | @app.route("/download/<int:book_id>/<format>") | ||||||
| @login_required | @login_required | ||||||
|  | @download_required | ||||||
| def get_download_link(book_id, format): | def get_download_link(book_id, format): | ||||||
|     format = format.split(".")[0] |     format = format.split(".")[0] | ||||||
|     book = db.session.query(db.Books).filter(db.Books.id == book_id).first() |     book = db.session.query(db.Books).filter(db.Books.id == book_id).first() | ||||||
| @@ -486,6 +552,7 @@ def logout(): | |||||||
|  |  | ||||||
| @app.route('/send/<int:book_id>') | @app.route('/send/<int:book_id>') | ||||||
| @login_required | @login_required | ||||||
|  | @download_required | ||||||
| def send_to_kindle(book_id): | def send_to_kindle(book_id): | ||||||
|     settings = ub.get_mail_settings() |     settings = ub.get_mail_settings() | ||||||
|     if settings.get("mail_server", "mail.example.com") == "mail.example.com": |     if settings.get("mail_server", "mail.example.com") == "mail.example.com": | ||||||
| @@ -583,8 +650,9 @@ def profile(): | |||||||
|         downloads.append(db.session.query(db.Books).filter(db.Books.id == book.book_id).first()) |         downloads.append(db.session.query(db.Books).filter(db.Books.id == book.book_id).first()) | ||||||
|     if request.method == "POST": |     if request.method == "POST": | ||||||
|         to_save = request.form.to_dict() |         to_save = request.form.to_dict() | ||||||
|         if to_save["password"]: |         if current_user.role_passwd() or current_user.role_admin(): | ||||||
|             content.password = generate_password_hash(to_save["password"]) |             if to_save["password"]: | ||||||
|  |                 content.password = generate_password_hash(to_save["password"]) | ||||||
|         if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail: |         if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail: | ||||||
|             content.kindle_mail = to_save["kindle_mail"] |             content.kindle_mail = to_save["kindle_mail"] | ||||||
|         if to_save["email"] and to_save["email"] != content.email: |         if to_save["email"] and to_save["email"] != content.email: | ||||||
| @@ -619,10 +687,17 @@ def new_user(): | |||||||
|         content.password = generate_password_hash(to_save["password"]) |         content.password = generate_password_hash(to_save["password"]) | ||||||
|         content.nickname = to_save["nickname"] |         content.nickname = to_save["nickname"] | ||||||
|         content.email = to_save["email"] |         content.email = to_save["email"] | ||||||
|         if "admin_user" in to_save: |         content.role = 0 | ||||||
|             content.role = 1 |         if "admin_role" in to_save: | ||||||
|         else: |             content.role = content.role + ub.ROLE_ADMIN | ||||||
|             content.role = 0 |         if "download_role" in to_save: | ||||||
|  |             content.role = content.role + ub.ROLE_DOWNLOAD | ||||||
|  |         if "upload_role" in to_save: | ||||||
|  |             content.role = content.role + ub.ROLE_UPLOAD | ||||||
|  |         if "edit_role" in to_save: | ||||||
|  |             content.role = content.role + ub.ROLE_EDIT | ||||||
|  |         if "passwd_role" in to_save: | ||||||
|  |             content.role = content.role + ub.ROLE_PASSWD | ||||||
|         try: |         try: | ||||||
|             ub.session.add(content) |             ub.session.add(content) | ||||||
|             ub.session.commit() |             ub.session.commit() | ||||||
| @@ -673,10 +748,32 @@ def edit_user(user_id): | |||||||
|         else: |         else: | ||||||
|             if to_save["password"]: |             if to_save["password"]: | ||||||
|                 content.password = generate_password_hash(to_save["password"]) |                 content.password = generate_password_hash(to_save["password"]) | ||||||
|             if "admin_user" in to_save and content.role != 1: |             | ||||||
|                 content.role = 1 |             if "admin_role" in to_save and not content.role_admin(): | ||||||
|             elif not "admin_user" in to_save and content.role == 1: |                 content.role = content.role + ub.ROLE_ADMIN | ||||||
|                 content.role = 0 |             elif not "admin_role" in to_save and content.role_admin(): | ||||||
|  |                 content.role = content.role - ub.ROLE_ADMIN | ||||||
|  |              | ||||||
|  |             if "download_role" in to_save and not content.role_download(): | ||||||
|  |                 content.role = content.role + ub.ROLE_DOWNLOAD | ||||||
|  |             elif not "download_role" in to_save and content.role_download(): | ||||||
|  |                 content.role = content.role - ub.ROLE_DOWNLOAD | ||||||
|  |              | ||||||
|  |             if "upload_role" in to_save and not content.role_upload(): | ||||||
|  |                 content.role = content.role + ub.ROLE_UPLOAD | ||||||
|  |             elif not "upload_role" in to_save and content.role_upload(): | ||||||
|  |                 content.role = content.role - ub.ROLE_UPLOAD | ||||||
|  |              | ||||||
|  |             if "edit_role" in to_save and not content.role_edit(): | ||||||
|  |                 content.role = content.role + ub.ROLE_EDIT | ||||||
|  |             elif not "edit_role" in to_save and content.role_edit(): | ||||||
|  |                 content.role = content.role - ub.ROLE_EDIT | ||||||
|  |              | ||||||
|  |             if "passwd_role" in to_save and not content.role_passwd(): | ||||||
|  |                 content.role = content.role + ub.ROLE_PASSWD | ||||||
|  |             elif not "passwd_role" in to_save and content.role_passwd(): | ||||||
|  |                 content.role = content.role - ub.ROLE_PASSWD | ||||||
|  |             | ||||||
|             if to_save["email"] and to_save["email"] != content.email: |             if to_save["email"] and to_save["email"] != content.email: | ||||||
|                 content.email = to_save["email"] |                 content.email = to_save["email"] | ||||||
|             if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail: |             if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail: | ||||||
| @@ -691,7 +788,7 @@ def edit_user(user_id): | |||||||
|  |  | ||||||
| @app.route("/admin/book/<int:book_id>", methods=['GET', 'POST']) | @app.route("/admin/book/<int:book_id>", methods=['GET', 'POST']) | ||||||
| @login_required | @login_required | ||||||
| @admin_required | @edit_required | ||||||
| def edit_book(book_id): | def edit_book(book_id): | ||||||
|     ## create the function for sorting... |     ## create the function for sorting... | ||||||
|     db.session.connection().connection.connection.create_function("title_sort",1,db.title_sort) |     db.session.connection().connection.connection.create_function("title_sort",1,db.title_sort) | ||||||
| @@ -933,7 +1030,7 @@ def edit_book(book_id): | |||||||
|  |  | ||||||
| @app.route("/upload", methods = ["GET", "POST"]) | @app.route("/upload", methods = ["GET", "POST"]) | ||||||
| @login_required | @login_required | ||||||
| @admin_required | @upload_required | ||||||
| def upload(): | def upload(): | ||||||
|     if not config.UPLOADING: |     if not config.UPLOADING: | ||||||
|         abort(404) |         abort(404) | ||||||
| @@ -996,4 +1093,7 @@ def upload(): | |||||||
|         for author in db_book.authors: |         for author in db_book.authors: | ||||||
|             author_names.append(author.name) |             author_names.append(author.name) | ||||||
|     cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() |     cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() | ||||||
|     return render_template('edit_book.html', book=db_book, authors=author_names, cc=cc) |     if current_user.role_edit() or current_user.role_admin(): | ||||||
|  |         return render_template('edit_book.html', book=db_book, authors=author_names, cc=cc) | ||||||
|  |     book_in_shelfs = [] | ||||||
|  |     return render_template('detail.html', entry=db_book,  cc=cc, title=db_book.title, books_shelfs=book_in_shelfs) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jan B
					Jan B