mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-03 20:02:47 +00:00 
			
		
		
		
	corpus permission decorator + sidenav update
This commit is contained in:
		
							
								
								
									
										37
									
								
								app/corpora/decorators.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/corpora/decorators.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					from flask import abort, current_app
 | 
				
			||||||
 | 
					from flask_login import current_user
 | 
				
			||||||
 | 
					from functools import wraps
 | 
				
			||||||
 | 
					from app.models import Corpus, CorpusFollowerAssociation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def corpus_follower_permission_required(permissions):
 | 
				
			||||||
 | 
					    def decorator(f):
 | 
				
			||||||
 | 
					        @wraps(f)
 | 
				
			||||||
 | 
					        def decorated_function(*args, **kwargs):
 | 
				
			||||||
 | 
					            corpus_id = kwargs.get('corpus_id')
 | 
				
			||||||
 | 
					            corpus = Corpus.query.get_or_404(corpus_id)
 | 
				
			||||||
 | 
					            if current_user == corpus.user or current_user.is_administrator():
 | 
				
			||||||
 | 
					                print('user or admin')
 | 
				
			||||||
 | 
					                return f(*args, **kwargs)
 | 
				
			||||||
 | 
					            if not current_user.is_following_corpus(corpus):
 | 
				
			||||||
 | 
					                print('not following corpus')
 | 
				
			||||||
 | 
					                abort(403)
 | 
				
			||||||
 | 
					            corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=current_user.id).first_or_404()
 | 
				
			||||||
 | 
					            for permission in permissions:
 | 
				
			||||||
 | 
					                if not corpus_follower_association.role.has_permission(permission):
 | 
				
			||||||
 | 
					                    abort(403)
 | 
				
			||||||
 | 
					            return f(*args, **kwargs)
 | 
				
			||||||
 | 
					        return decorated_function
 | 
				
			||||||
 | 
					    return decorator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def owner_or_admin_required():
 | 
				
			||||||
 | 
					    def decorator(f):
 | 
				
			||||||
 | 
					        @wraps(f)
 | 
				
			||||||
 | 
					        def decorated_function(*args, **kwargs):
 | 
				
			||||||
 | 
					            corpus_id = kwargs.get('corpus_id')
 | 
				
			||||||
 | 
					            corpus = Corpus.query.get_or_404(corpus_id)
 | 
				
			||||||
 | 
					            if current_user == corpus.user or current_user.is_administrator():
 | 
				
			||||||
 | 
					                return f(*args, **kwargs)
 | 
				
			||||||
 | 
					            abort(403)
 | 
				
			||||||
 | 
					        return decorated_function
 | 
				
			||||||
 | 
					    return decorator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,6 +15,7 @@ from flask_login import current_user, login_required
 | 
				
			|||||||
from threading import Thread
 | 
					from threading import Thread
 | 
				
			||||||
import jwt
 | 
					import jwt
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					from .decorators import corpus_follower_permission_required, owner_or_admin_required
 | 
				
			||||||
from app import db, hashids
 | 
					from app import db, hashids
 | 
				
			||||||
from app.models import (
 | 
					from app.models import (
 | 
				
			||||||
    Corpus,
 | 
					    Corpus,
 | 
				
			||||||
@@ -32,6 +33,11 @@ from .forms import (
 | 
				
			|||||||
    UpdateCorpusFileForm
 | 
					    UpdateCorpusFileForm
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@bp.route('/<hashid:corpus_id>/test')
 | 
				
			||||||
 | 
					@login_required
 | 
				
			||||||
 | 
					@corpus_follower_permission_required(['VIEW', 'ADD_CORPUS_FILE'])
 | 
				
			||||||
 | 
					def test(corpus_id):
 | 
				
			||||||
 | 
					    return 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@bp.route('/fake-add')
 | 
					@bp.route('/fake-add')
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
@@ -45,10 +51,9 @@ def fake_add():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@bp.route('/<hashid:corpus_id>/is_public/enable', methods=['POST'])
 | 
					@bp.route('/<hashid:corpus_id>/is_public/enable', methods=['POST'])
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
 | 
					@owner_or_admin_required()
 | 
				
			||||||
def enable_corpus_is_public(corpus_id):
 | 
					def enable_corpus_is_public(corpus_id):
 | 
				
			||||||
    corpus = Corpus.query.get_or_404(corpus_id)
 | 
					    corpus = Corpus.query.get_or_404(corpus_id)
 | 
				
			||||||
    if not (corpus.user == current_user or current_user.is_administrator()):
 | 
					 | 
				
			||||||
        abort(403)
 | 
					 | 
				
			||||||
    corpus.is_public = True
 | 
					    corpus.is_public = True
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
    return '', 204
 | 
					    return '', 204
 | 
				
			||||||
@@ -56,10 +61,9 @@ def enable_corpus_is_public(corpus_id):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@bp.route('/<hashid:corpus_id>/is_public/disable', methods=['POST'])
 | 
					@bp.route('/<hashid:corpus_id>/is_public/disable', methods=['POST'])
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
 | 
					@owner_or_admin_required()
 | 
				
			||||||
def disable_corpus_is_public(corpus_id):
 | 
					def disable_corpus_is_public(corpus_id):
 | 
				
			||||||
    corpus = Corpus.query.get_or_404(corpus_id)
 | 
					    corpus = Corpus.query.get_or_404(corpus_id)
 | 
				
			||||||
    if not (corpus.user == current_user or current_user.is_administrator()):
 | 
					 | 
				
			||||||
        abort(403)
 | 
					 | 
				
			||||||
    corpus.is_public = False
 | 
					    corpus.is_public = False
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
    return '', 204
 | 
					    return '', 204
 | 
				
			||||||
@@ -107,6 +111,7 @@ def current_user_unfollow_corpus(corpus_id):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@bp.route('/<hashid:corpus_id>/followers/<hashid:follower_id>/role', methods=['POST'])
 | 
					@bp.route('/<hashid:corpus_id>/followers/<hashid:follower_id>/role', methods=['POST'])
 | 
				
			||||||
 | 
					@corpus_follower_permission_required(['REMOVE_FOLLOWER', 'UPDATE_FOLLOWER'])
 | 
				
			||||||
def add_permission(corpus_id, follower_id):
 | 
					def add_permission(corpus_id, follower_id):
 | 
				
			||||||
    corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=follower_id).first_or_404()
 | 
					    corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=follower_id).first_or_404()
 | 
				
			||||||
    if not (corpus_follower_association.corpus.user == current_user or current_user.is_administrator()):
 | 
					    if not (corpus_follower_association.corpus.user == current_user or current_user.is_administrator()):
 | 
				
			||||||
@@ -188,6 +193,7 @@ def corpus(corpus_id):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@bp.route('/<hashid:corpus_id>/generate-corpus-share-link', methods=['GET', 'POST'])
 | 
					@bp.route('/<hashid:corpus_id>/generate-corpus-share-link', methods=['GET', 'POST'])
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
 | 
					@corpus_follower_permission_required('GENERATE_SHARE_LINK')
 | 
				
			||||||
def generate_corpus_share_link(corpus_id):
 | 
					def generate_corpus_share_link(corpus_id):
 | 
				
			||||||
    data = request.get_json('data')
 | 
					    data = request.get_json('data')
 | 
				
			||||||
    role = data['role']
 | 
					    role = data['role']
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,11 +3,17 @@
 | 
				
			|||||||
    <div class="user-view" style="padding-top: 8px;">
 | 
					    <div class="user-view" style="padding-top: 8px;">
 | 
				
			||||||
      <div class="background primary-color"></div>
 | 
					      <div class="background primary-color"></div>
 | 
				
			||||||
      <div class="row">
 | 
					      <div class="row">
 | 
				
			||||||
        <div class="col s2">
 | 
					        <div class="col s4">
 | 
				
			||||||
          <a href="{{ url_for('users.user', user_id=current_user.id) }}">
 | 
					            <a href="{{ url_for('users.user', user_id=current_user.id) }}">
 | 
				
			||||||
          <i class="material-icons" style="color:white; font-size:3em; margin-top: 25px; margin-left:-15px;">account_circle</i></div>
 | 
					            {% if current_user.avatar %}
 | 
				
			||||||
          </a>
 | 
					            <img src="{{ url_for('users.profile_avatar', user_id=current_user.id) }}" alt="user-image" class="circle responsive-img"  style="height:80%; margin-top: 20px; margin-left:-15px;">
 | 
				
			||||||
        <div class="col s10">
 | 
					            {% else %}
 | 
				
			||||||
 | 
					            <img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img" style="height:80%; margin-top: 20px; margin-left:-15px;">
 | 
				
			||||||
 | 
					            {% endif %}
 | 
				
			||||||
 | 
					            {# <i class="material-icons" style="color:white; font-size:3em; margin-top: 25px; margin-left:-15px;">account_circle</i></div> #}
 | 
				
			||||||
 | 
					            </a>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col s8">
 | 
				
			||||||
          <span class="white-text name">{{ current_user.username }}</span>
 | 
					          <span class="white-text name">{{ current_user.username }}</span>
 | 
				
			||||||
          <span class="white-text email">{{ current_user.email }}</span>
 | 
					          <span class="white-text email">{{ current_user.email }}</span>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -20,7 +26,6 @@
 | 
				
			|||||||
  <li><a href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a></li>
 | 
					  <li><a href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a></li>
 | 
				
			||||||
  <li><a href="{{ url_for('main.dashboard', _anchor='corpora') }}" style="padding-left: 47px;"><i class="nopaque-icons">I</i>My Corpora</a></li>
 | 
					  <li><a href="{{ url_for('main.dashboard', _anchor='corpora') }}" style="padding-left: 47px;"><i class="nopaque-icons">I</i>My Corpora</a></li>
 | 
				
			||||||
  <li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a></li>
 | 
					  <li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a></li>
 | 
				
			||||||
  <li><a href="{{ url_for('main.dashboard', _anchor='social') }}" style="padding-left: 47px;"><i class="material-icons">groups</i>Social</a></li>
 | 
					 | 
				
			||||||
  <li><a href="{{ url_for('contributions.contributions') }}"><i class="material-icons">new_label</i>Contribute</a></li>
 | 
					  <li><a href="{{ url_for('contributions.contributions') }}"><i class="material-icons">new_label</i>Contribute</a></li>
 | 
				
			||||||
  <li><div class="divider"></div></li>
 | 
					  <li><div class="divider"></div></li>
 | 
				
			||||||
  <li><a class="subheader">Processes & Services</a></li>
 | 
					  <li><a class="subheader">Processes & Services</a></li>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user