Fix #549 - Deauthorize OAuth applications
authorJessica Tallon <jessica@megworld.co.uk>
Wed, 1 Oct 2014 18:45:53 +0000 (19:45 +0100)
committerJessica Tallon <jessica@megworld.co.uk>
Wed, 1 Oct 2014 18:45:53 +0000 (19:45 +0100)
mediagoblin/db/models.py
mediagoblin/edit/routing.py
mediagoblin/edit/views.py
mediagoblin/static/css/base.css
mediagoblin/static/images/small-gavroche.png [new file with mode: 0644]
mediagoblin/static/images/small-gavroche.xcf [new file with mode: 0644]
mediagoblin/templates/mediagoblin/edit/deauthorize_applications.html [new file with mode: 0644]
mediagoblin/templates/mediagoblin/edit/edit_account.html

index 5a07effe3cc67be6902dd41150ceee5488123163..1b700dce370a4580d5d9bc1c1166474d144bfc2a 100644 (file)
@@ -217,6 +217,8 @@ class RequestToken(Base):
     created = Column(DateTime, nullable=False, default=datetime.datetime.now)
     updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
 
+    get_client = relationship(Client)
+
 class AccessToken(Base):
     """
         Model for representing the access tokens
@@ -230,6 +232,8 @@ class AccessToken(Base):
     created = Column(DateTime, nullable=False, default=datetime.datetime.now)
     updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
 
+    get_requesttoken = relationship(RequestToken)
+
 
 class NonceTimestamp(Base):
     """
index a2d03d2683b1dd76519a1aa053c174517140106c..b349975d397eabd8bc7e21b04e82cda0adcd6af8 100644 (file)
@@ -28,3 +28,5 @@ add_route('mediagoblin.edit.verify_email', '/edit/verify_email/',
     'mediagoblin.edit.views:verify_email')
 add_route('mediagoblin.edit.email', '/edit/email/',
     'mediagoblin.edit.views:change_email')
+add_route('mediagoblin.edit.deauthorize_applications', '/edit/deauthorize/',
+    'mediagoblin.edit.views:deauthorize_applications')
index 7359f520c4109332a0f4c6774da5332a7d998a60..2ccf11aebcb8c1cbc7a125b9821c99d48df1da82 100644 (file)
@@ -47,7 +47,7 @@ from mediagoblin.tools.text import (
     convert_to_tag_list_of_dicts, media_tags_as_string)
 from mediagoblin.tools.url import slugify
 from mediagoblin.db.util import check_media_slug_used, check_collection_slug_used
-from mediagoblin.db.models import User
+from mediagoblin.db.models import User, Client, AccessToken
 
 import mimetypes
 
@@ -258,6 +258,34 @@ def edit_account(request):
         {'user': user,
          'form': form})
 
+@require_active_login
+def deauthorize_applications(request):
+    """ Deauthroize OAuth applications """
+    if request.method == 'POST' and "application" in request.form:
+        token = request.form["application"]
+        access_token = AccessToken.query.filter_by(token=token).first()
+        if access_token is None:
+            messages.add_message(
+                request,
+                messages.ERROR,
+                _("Unknown application, not able to deauthorize")
+            )
+        else:
+            access_token.delete()
+            messages.add_message(
+                request,
+                messages.SUCCESS,
+                _("Application has been deauthorized")
+            )
+
+    access_tokens = AccessToken.query.filter_by(user=request.user.id)
+    applications = [(a.get_requesttoken, a) for a in access_tokens]
+
+    return render_to_response(
+        request,
+        'mediagoblin/edit/deauthorize_applications.html',
+        {'applications': applications}
+    )
 
 @require_active_login
 def delete_account(request):
index f9d90df1337cf53f6135458d4036771f3768a2e7..c7e1496f06694bff06ebb0a48985fec13cf49705 100644 (file)
@@ -965,3 +965,19 @@ table.metadata_editor tr td {
 table.metadata_editor tr td.form_field_input input {
     width:350px;
 }
+
+.application {
+  min-height: 30px;
+  margin-left: 70px;
+}
+
+.application-icon {
+  position: absolute;
+  left: 12px;
+  width: 50px;
+  height: 50px;
+}
+
+.application-button {
+  float: right;
+}
diff --git a/mediagoblin/static/images/small-gavroche.png b/mediagoblin/static/images/small-gavroche.png
new file mode 100644 (file)
index 0000000..13192d9
Binary files /dev/null and b/mediagoblin/static/images/small-gavroche.png differ
diff --git a/mediagoblin/static/images/small-gavroche.xcf b/mediagoblin/static/images/small-gavroche.xcf
new file mode 100644 (file)
index 0000000..0291d2e
Binary files /dev/null and b/mediagoblin/static/images/small-gavroche.xcf differ
diff --git a/mediagoblin/templates/mediagoblin/edit/deauthorize_applications.html b/mediagoblin/templates/mediagoblin/edit/deauthorize_applications.html
new file mode 100644 (file)
index 0000000..f3b83e4
--- /dev/null
@@ -0,0 +1,69 @@
+{#
+# GNU MediaGoblin -- federated, autonomous media hosting
+# Copyright (C) 2011, 2012 MediaGoblin contributors.  See AUTHORS.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#}
+{%- extends "mediagoblin/base.html" %}
+
+{% block title -%}
+  {% trans -%}
+    Deauthorize applications
+  {%- endtrans %} &mdash; {{ super() }}
+{%- endblock %}
+
+{% block mediagoblin_content %}
+  <h2>{% trans -%}Deauthorize Applications{%- endtrans %}</h2>
+  <p>{% trans -%}
+    These applications can access your GNU MediaGoblin account. Deauthorizing the
+    application will prevent the application from accessing your account.
+    {%- endtrans %}
+  </p>
+
+  <form method="POST" action="{{ request.urlgen('mediagoblin.edit.deauthorize_applications') }}">
+  {{ csrf_token }}
+  {% if not applications %}
+    <em>{% trans -%}There are no applications authorized.{%- endtrans %}</em>
+  {% endif %}
+  {% for application, access in applications %}
+    <div class="application">
+      <div class="application-button">
+        <button class="button_action" name="application" value="{{ access.token }}">Deauthorize</button>
+      </div>
+      {% if application.get_client.logo_url %}
+        <img class="application-icon" src="{{ application.get_client.logo_url }}">
+      {% else %}
+        <img class="application-icon" src="{{ request.staticdirect('/images/small-gavroche.png') }}">
+      {% endif %}
+      <div class="application-content">
+        <strong>{{ application.get_client.application_name }}</strong>
+        <p class="application-data">
+          <small>
+            {% trans -%}Type:{%- endtrans %}
+            &nbsp;
+            {{ application.get_client.application_type }}</small>
+          <br />
+          <small>
+            {% trans -%}Authorized:{%- endtrans %}
+            &nbsp;
+            {%- trans formatted_time=timesince(access.created) -%}
+              {{ formatted_time }} ago
+            {%- endtrans -%}
+          </small>
+        </p>
+      </div>
+    </div>
+  {% endfor %}
+  </form>
+{% endblock %}
\ No newline at end of file
index 574fe45997b99397fc8171c47c48c50740150e1c..14a66482bf75560409bdec6a23a5112f153fbc16 100644 (file)
     <a href="{{ request.urlgen('mediagoblin.edit.delete_account') }}">
       {%- trans %}Delete my account{% endtrans -%}
     </a>
-    &middot;
+    <br />
+    <a href="{{ request.urlgen('mediagoblin.edit.deauthorize_applications') }}">
+      {%- trans %}Deauthorize applications{% endtrans -%}
+    </a>
     {% template_hook("edit_link") %}
     <a href="{{ request.urlgen('mediagoblin.edit.email') }}">
       {% trans %}Email{% endtrans %}