changes to app_token
This commit is contained in:
parent
5bda9e8d83
commit
4498be544b
|
@ -35,6 +35,7 @@ class TOTPDeleteForm(FlaskForm):
|
||||||
|
|
||||||
class AppTokenForm(FlaskForm):
|
class AppTokenForm(FlaskForm):
|
||||||
name = StringField(gettext('name'), validators=[DataRequired(),Length(min=1, max=255) ])
|
name = StringField(gettext('name'), validators=[DataRequired(),Length(min=1, max=255) ])
|
||||||
|
scopes = StringField(gettext('scopes'), validators=[DataRequired(),Length(min=1, max=255) ])
|
||||||
submit = SubmitField(gettext('Activate'))
|
submit = SubmitField(gettext('Activate'))
|
||||||
|
|
||||||
class AppTokenDeleteForm(FlaskForm):
|
class AppTokenDeleteForm(FlaskForm):
|
||||||
|
|
|
@ -198,8 +198,12 @@ class User(BaseModel, ModelUpdatedMixin):
|
||||||
def change_password(self, password_new: str) -> None:
|
def change_password(self, password_new: str) -> None:
|
||||||
self.password_hashed = crypt.crypt(password_new)
|
self.password_hashed = crypt.crypt(password_new)
|
||||||
|
|
||||||
def get_tokens_by_service(self, service: Service) -> list['AppToken']:
|
def get_token_by_name(self, name: str) -> Optional['AppToken']:
|
||||||
return [ token for token in self.app_tokens if token.service_name == service.name ]
|
for token in self.app_tokens:
|
||||||
|
if token.name == name:
|
||||||
|
return token
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_token_by_scope(self, scope: str) -> Iterator['AppToken']:
|
def get_token_by_scope(self, scope: str) -> Iterator['AppToken']:
|
||||||
for token in self.app_tokens:
|
for token in self.app_tokens:
|
||||||
|
|
|
@ -4,47 +4,36 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
<div>
|
||||||
{% for service in services.values() if service.app_token %}
|
<table class="table">
|
||||||
<li class="nav-item">
|
<thead>
|
||||||
<a class="nav-link{{' active' if loop.first else ''}}" id="home-tab" data-toggle="tab" href="#{{ service.name }}" role="tab" aria-controls="home" aria-selected="true">{{ service.name }}</a>
|
<tr>
|
||||||
</li>
|
<th>name</th>
|
||||||
{% endfor %}
|
<th>scopes</th>
|
||||||
</ul>
|
<th>last used</th>
|
||||||
|
<th>created at<th>
|
||||||
<div class="tab-content" id="myTabContent">
|
<th> <th>
|
||||||
{% for service in services.values() if service.app_token %}
|
</tr>
|
||||||
|
</thead>
|
||||||
<div class="tab-pane fade{{ ' show active' if loop.first else '' }}" id="{{ service.name }}" role="tabpanel" aria-labelledby="{{ service.name }}-tab">
|
<tbody>
|
||||||
<table class="table">
|
{% for app_token in current_user.app_tokens %}
|
||||||
<thead>
|
<tr>
|
||||||
<tr>
|
<td>{{ app_token.name }}</td>
|
||||||
<th>name</th>
|
<td>{{ app_token.scopes }}</td>
|
||||||
<th>last used</th>
|
<td>{{ app_token.last_used }}</td>
|
||||||
<th>created at<th>
|
<td>{{ app_token.created_at }}</td>
|
||||||
<th> <th>
|
<td>
|
||||||
</tr>
|
{{ render_form(delete_form, action_url=url_for('frontend.app_token_delete', app_token_name=app_token.name)) }}
|
||||||
</thead>
|
{#
|
||||||
<tbody>
|
<a title="{{ gettext('Revoke')}}" href="{{ url_for('.app_token_revoce', id=app_token.id) }}" onclick="client_cert.revoke_certificate(this.href, '{{ cert.serial_number_hex }}'); return false;"><i class="fas fa-ban"></i></a>
|
||||||
{% for app_token in current_user.get_tokens_by_service(service) %}
|
#}
|
||||||
<tr>
|
</td>
|
||||||
<td>{{ app_token.name }}</td>
|
</tr>
|
||||||
<td>{{ app_token.last_used }}</td>
|
{% endfor %}
|
||||||
<td>{{ app_token.created_at }}</td>
|
|
||||||
<td>
|
|
||||||
{{ render_form(delete_form, action_url=url_for('frontend.app_token_delete', service_name=service.name,app_token_name=app_token.name)) }}
|
|
||||||
{#
|
|
||||||
<a title="{{ gettext('Revoke')}}" href="{{ url_for('.app_token_revoce', id=app_token.id) }}" onclick="client_cert.revoke_certificate(this.href, '{{ cert.serial_number_hex }}'); return false;"><i class="fas fa-ban"></i></a>
|
|
||||||
#}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
</table>
|
||||||
<a class="btn btn-primary" href="{{ url_for('frontend.app_token_new', service_name=service.name) }}">
|
<a class="btn btn-primary" href="{{ url_for('frontend.app_token_new') }}">
|
||||||
New Token
|
New Token
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends 'frontend/base.html.j2' %}
|
{% extends 'frontend/base.html.j2' %}
|
||||||
|
|
||||||
{% block title %}{{ gettext('new app token for {service_name}').format(service_name=service.name) }}{% endblock %}
|
{% block title %}{{ gettext('new app token') }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{% extends 'frontend/base.html.j2' %}
|
{% extends 'frontend/base.html.j2' %}
|
||||||
|
|
||||||
{% block title %}{{ gettext('new app token for {service_name}').format(service_name=service.name) }}{% endblock %}
|
{% block title %}{{ gettext('new app token') }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
Your new App Token for {{ service.name }}:
|
Your new App Token for scopes: {app_token.scopes}:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -58,36 +58,36 @@ def introspect() -> ResponseReturnValue:
|
||||||
return jsonify(token_info)
|
return jsonify(token_info)
|
||||||
|
|
||||||
|
|
||||||
@api_views.route('/login/<service_name>', methods=['POST'])
|
# @api_views.route('/login/<service_name>', methods=['POST'])
|
||||||
def email_login(service_name: str) -> ResponseReturnValue:
|
# def email_login(service_name: str) -> ResponseReturnValue:
|
||||||
if service_name not in lenticular_services:
|
# if service_name not in lenticular_services:
|
||||||
return '', 404
|
# return '', 404
|
||||||
service = lenticular_services[service_name]
|
# service = lenticular_services[service_name]
|
||||||
|
|
||||||
if not request.is_json:
|
# if not request.is_json:
|
||||||
return jsonify({}), 400
|
# return jsonify({}), 400
|
||||||
req_payload = request.get_json() # type: Any
|
# req_payload = request.get_json() # type: Any
|
||||||
|
|
||||||
if not isinstance(req_payload, dict):
|
# if not isinstance(req_payload, dict):
|
||||||
return 'bad request', 400
|
# return 'bad request', 400
|
||||||
|
|
||||||
password = req_payload["password"]
|
# password = req_payload["password"]
|
||||||
username = req_payload["username"]
|
# username = req_payload["username"]
|
||||||
|
|
||||||
if '@' in username:
|
# if '@' in username:
|
||||||
username = username.split('@')[0]
|
# username = username.split('@')[0]
|
||||||
|
|
||||||
user = User.query.filter_by(username=username.lower()).first() # type: Optional[User]
|
# user = User.query.filter_by(username=username.lower()).first() # type: Optional[User]
|
||||||
if user is None:
|
# if user is None:
|
||||||
logger.warning(f'login with invalid username')
|
# logger.warning(f'login with invalid username')
|
||||||
return jsonify({}), 403
|
# return jsonify({}), 403
|
||||||
|
|
||||||
for app_token in user.get_tokens_by_service(service):
|
# for app_token in user.get_token_by_name(service):
|
||||||
if secrets.compare_digest(password, app_token.token):
|
# if secrets.compare_digest(password, app_token.token):
|
||||||
app_token.last_used = datetime.now()
|
# app_token.last_used = datetime.now()
|
||||||
db.session.commit()
|
# db.session.commit()
|
||||||
return jsonify({'username': user.username}), 200
|
# return jsonify({'username': user.username}), 200
|
||||||
|
|
||||||
logger.warning(f'login with invalid password for {username}')
|
# logger.warning(f'login with invalid password for {username}')
|
||||||
return jsonify({}), 403
|
# return jsonify({}), 403
|
||||||
|
|
||||||
|
|
|
@ -153,17 +153,14 @@ def app_token() -> ResponseReturnValue:
|
||||||
delete_form=delete_form,
|
delete_form=delete_form,
|
||||||
services=lenticular_services)
|
services=lenticular_services)
|
||||||
|
|
||||||
@frontend_views.route('/app_token/<service_name>/new', methods=['GET','POST'])
|
@frontend_views.route('/app_token/new', methods=['GET','POST'])
|
||||||
def app_token_new(service_name: str) -> ResponseReturnValue:
|
def app_token_new() -> ResponseReturnValue:
|
||||||
if service_name not in lenticular_services:
|
|
||||||
return '', 404
|
|
||||||
service = lenticular_services[service_name]
|
|
||||||
form = AppTokenForm()
|
form = AppTokenForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
user_any = get_current_user() # type: Any
|
user_any = get_current_user() # type: Any
|
||||||
user = user_any # type: User
|
user = user_any # type: User
|
||||||
app_token = AppToken.new(user, service, "")
|
app_token = AppToken.new(user, name="",scopes="")
|
||||||
form.populate_obj(app_token)
|
form.populate_obj(app_token)
|
||||||
# check for duplicate names
|
# check for duplicate names
|
||||||
for user_app_token in user.app_tokens:
|
for user_app_token in user.app_tokens:
|
||||||
|
@ -171,23 +168,18 @@ def app_token_new(service_name: str) -> ResponseReturnValue:
|
||||||
return 'name already exist', 400
|
return 'name already exist', 400
|
||||||
user.app_tokens.append(app_token)
|
user.app_tokens.append(app_token)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return render_template('frontend/app_token_new_show.html.j2', service=service, app_token=app_token)
|
return render_template('frontend/app_token_new_show.html.j2', app_token=app_token)
|
||||||
|
|
||||||
|
|
||||||
return render_template('frontend/app_token_new.html.j2',
|
return render_template('frontend/app_token_new.html.j2',
|
||||||
form=form,
|
form=form)
|
||||||
service=service)
|
|
||||||
|
|
||||||
@frontend_views.route('/app_token/<service_name>/<app_token_name>', methods=["POST"])
|
@frontend_views.route('/app_token/<app_token_name>', methods=["POST"])
|
||||||
def app_token_delete(service_name: str, app_token_name: str) -> ResponseReturnValue:
|
def app_token_delete(app_token_name: str) -> ResponseReturnValue:
|
||||||
form = AppTokenDeleteForm()
|
form = AppTokenDeleteForm()
|
||||||
|
|
||||||
if service_name not in lenticular_services:
|
|
||||||
return '', 404
|
|
||||||
|
|
||||||
service = lenticular_services[service_name]
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
app_token = get_current_user().get_token(service, app_token_name)
|
app_token = get_current_user().get_token_by_name(app_token_name)
|
||||||
if app_token is None:
|
if app_token is None:
|
||||||
return 'not found', 404
|
return 'not found', 404
|
||||||
db.session.delete(app_token)
|
db.session.delete(app_token)
|
||||||
|
|
Loading…
Reference in a new issue