You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2014/06/04 22:52:03 UTC

[04/16] git commit: [#1687] ticket:574 Remove ApiToken & ApiTicket

[#1687] ticket:574 Remove ApiToken & ApiTicket


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/63652297
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/63652297
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/63652297

Branch: refs/heads/master
Commit: 6365229700600fc6e5720b4d90ab58bab39b2715
Parents: 65cc6e7
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri May 2 12:31:46 2014 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jun 3 15:27:21 2014 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py               | 18 ----
 Allura/allura/controllers/site_admin.py         | 49 ----------
 Allura/allura/model/__init__.py                 |  2 +-
 Allura/allura/model/auth.py                     | 99 --------------------
 .../templates/site_admin_api_tickets.html       | 66 -------------
 5 files changed, 1 insertion(+), 233 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/63652297/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index abe6454..85a6df1 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -19,7 +19,6 @@
 
 """REST Controller"""
 import logging
-from urllib import quote, unquote
 
 import oauth2 as oauth
 from webob import exc
@@ -50,23 +49,6 @@ class RestController(object):
         'Based on request.params or oauth, authenticate the request'
         if 'oauth_token' in request.params or 'access_token' in request.params:
             return self.oauth._authenticate()
-        elif 'api_key' in request.params:
-            api_key = request.params.get('api_key')
-            token = M.ApiTicket.get(api_key)
-            if not token:
-                token = M.ApiToken.get(api_key)
-            else:
-                log.info('Authenticating with API ticket')
-            # Sometimes a path might be only partially escaped like /FAQ-Development,%20Bug%20Reporting,
-            # I don't know why.
-            path = quote(unquote(request.path))
-            if path != request.path:
-                log.info('Canonicalized %s to %s', request.path, path)
-            if token is not None and token.authenticate_request(path, request.params):
-                return token
-            else:
-                log.info('API authentication failure')
-                raise exc.HTTPForbidden
         else:
             return None
 

http://git-wip-us.apache.org/repos/asf/allura/blob/63652297/Allura/allura/controllers/site_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/site_admin.py b/Allura/allura/controllers/site_admin.py
index 352d35f..3cf4973 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -21,8 +21,6 @@ from datetime import datetime, timedelta
 
 from tg import expose, validate, flash, config, redirect
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from ming.orm import session
-import pymongo
 import bson
 import tg
 from pylons import app_globals as g
@@ -77,7 +75,6 @@ class SiteAdminController(object):
         base_url = '/nf/admin/'
         links = [
             SitemapEntry('Home', base_url, ui_icon=g.icons['admin']),
-            SitemapEntry('API Tickets', base_url + 'api_tickets', ui_icon=g.icons['admin']),
             SitemapEntry('Add Subscribers', base_url + 'add_subscribers', ui_icon=g.icons['admin']),
             SitemapEntry('New Projects', base_url + 'new_projects', ui_icon=g.icons['admin']),
             SitemapEntry('Reclone Repo', base_url + 'reclone_repo', ui_icon=g.icons['admin']),
@@ -92,52 +89,6 @@ class SiteAdminController(object):
     def index(self):
         return {}
 
-    @expose('jinja:allura:templates/site_admin_api_tickets.html')
-    @without_trailing_slash
-    def api_tickets(self, **data):
-        import json
-        import dateutil.parser
-        if request.method == 'POST':
-            log.info('api_tickets: %s', data)
-            ok = True
-            for_user = M.User.by_username(data['for_user'])
-            if not for_user:
-                ok = False
-                flash('User not found')
-            caps = None
-            try:
-                caps = json.loads(data['caps'])
-            except ValueError:
-                ok = False
-                flash('JSON format error')
-            if type(caps) is not type({}):
-                ok = False
-                flash(
-                    'Capabilities must be a JSON dictionary, mapping capability name to optional discriminator(s) (or "")')
-            try:
-                expires = dateutil.parser.parse(data['expires'])
-            except ValueError:
-                ok = False
-                flash('Date format error')
-            if ok:
-                tok = None
-                try:
-                    tok = M.ApiTicket(user_id=for_user._id,
-                                      capabilities=caps, expires=expires)
-                    session(tok).flush()
-                    log.info('New token: %s', tok)
-                    flash('API Ticket created')
-                except:
-                    log.exception('Could not create API ticket:')
-                    flash('Error creating API ticket')
-        elif request.method == 'GET':
-            data = {'expires': datetime.utcnow() + timedelta(days=2)}
-
-        data['token_list'] = M.ApiTicket.query.find().sort(
-            'mod_date', pymongo.DESCENDING).all()
-        log.info(data['token_list'])
-        return data
-
     def subscribe_artifact(self, url, user):
         artifact_url = urlparse(url).path[1:-1].split("/")
         neighborhood = M.Neighborhood.query.find({

http://git-wip-us.apache.org/repos/asf/allura/blob/63652297/Allura/allura/model/__init__.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/__init__.py b/Allura/allura/model/__init__.py
index bc40872..a74bff6 100644
--- a/Allura/allura/model/__init__.py
+++ b/Allura/allura/model/__init__.py
@@ -25,7 +25,7 @@ from .index import ArtifactReference, Shortlink
 from .artifact import Artifact, MovedArtifact, Message, VersionedArtifact, Snapshot, Feed, AwardFile, Award, AwardGrant, VotableArtifact
 from .discuss import Discussion, Thread, PostHistory, Post, DiscussionAttachment
 from .attachments import BaseAttachment
-from .auth import AuthGlobals, User, ProjectRole, EmailAddress, ApiToken, ApiTicket, OldProjectRole
+from .auth import AuthGlobals, User, ProjectRole, EmailAddress, OldProjectRole
 from .auth import AuditLog, audit_log, AlluraUserProperty
 from .filesystem import File
 from .notification import Notification, Mailbox

http://git-wip-us.apache.org/repos/asf/allura/blob/63652297/Allura/allura/model/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index 7d56e8c..6a9d279 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -25,7 +25,6 @@ import hashlib
 from urlparse import urlparse
 from email import header
 from hashlib import sha256
-import uuid
 from pytz import timezone
 from datetime import timedelta, datetime, time
 
@@ -110,104 +109,6 @@ class AlluraUserProperty(ForeignIdProperty):
         super(AlluraUserProperty, self).__init__('User', allow_none=True, **kwargs)
 
 
-class ApiAuthMixIn(object):
-
-    def authenticate_request(self, path, params):
-        try:
-            # Validate timestamp
-            timestamp = iso8601.parse_date(params['api_timestamp'])
-            timestamp_utc = timestamp.replace(
-                tzinfo=None) - timestamp.utcoffset()
-            if abs(datetime.utcnow() - timestamp_utc) > timedelta(minutes=10):
-                return False
-            # Validate signature
-            api_signature = params['api_signature']
-            params = sorted((k, v)
-                            for k, v in params.iteritems() if k != 'api_signature')
-            string_to_sign = path + '?' + urlencode(params)
-            digest = hmac.new(self.secret_key, string_to_sign, hashlib.sha256)
-            return digest.hexdigest() == api_signature
-        except KeyError:
-            return False
-
-    def sign_request(self, path, params):
-        if hasattr(params, 'items'):
-            params = params.items()
-        has_api_key = has_api_timestamp = has_api_signature = False
-        for k, v in params:
-            if k == 'api_key':
-                has_api_key = True
-            if k == 'api_timestamp':
-                has_api_timestamp = True
-            if k == 'api_signature':
-                has_api_signature = True
-        if not has_api_key:
-            params.append(('api_key', self.api_key))
-        if not has_api_timestamp:
-            params.append(('api_timestamp', datetime.utcnow().isoformat()))
-        if not has_api_signature:
-            string_to_sign = urllib.quote(path) + \
-                '?' + urlencode(sorted(params))
-            digest = hmac.new(self.secret_key, string_to_sign, hashlib.sha256)
-            params.append(('api_signature', digest.hexdigest()))
-        return params
-
-    def get_capability(self, key):
-        return None
-
-
-class ApiToken(MappedClass, ApiAuthMixIn):
-
-    class __mongometa__:
-        name = 'api_token'
-        session = main_orm_session
-        unique_indexes = ['user_id']
-
-    _id = FieldProperty(S.ObjectId)
-    user_id = AlluraUserProperty()
-    api_key = FieldProperty(str, if_missing=lambda: str(uuid.uuid4()))
-    secret_key = FieldProperty(str, if_missing=h.cryptographic_nonce)
-
-    user = RelationProperty('User')
-
-    @classmethod
-    def get(cls, api_key):
-        return cls.query.get(api_key=api_key)
-
-
-class ApiTicket(MappedClass, ApiAuthMixIn):
-
-    class __mongometa__:
-        name = 'api_ticket'
-        session = main_orm_session
-    PREFIX = 'tck'
-
-    _id = FieldProperty(S.ObjectId)
-    user_id = AlluraUserProperty()
-    api_key = FieldProperty(
-        str, if_missing=lambda: ApiTicket.PREFIX + h.nonce(20))
-    secret_key = FieldProperty(str, if_missing=h.cryptographic_nonce)
-    expires = FieldProperty(datetime, if_missing=None)
-    capabilities = FieldProperty({str: None})
-    mod_date = FieldProperty(datetime, if_missing=datetime.utcnow)
-
-    user = RelationProperty('User')
-
-    @classmethod
-    def get(cls, api_ticket):
-        if not api_ticket.startswith(cls.PREFIX):
-            return None
-        return cls.query.get(api_key=api_ticket)
-
-    def authenticate_request(self, path, params):
-        if self.expires and datetime.utcnow() > self.expires:
-            return False
-        return ApiAuthMixIn.authenticate_request(self, path, params)
-
-    def get_capability(self, key):
-        return self.capabilities.get(key)
-
-
 class EmailAddress(MappedClass):
     re_format = re.compile('^.* <(.*)>$')
 

http://git-wip-us.apache.org/repos/asf/allura/blob/63652297/Allura/allura/templates/site_admin_api_tickets.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/site_admin_api_tickets.html b/Allura/allura/templates/site_admin_api_tickets.html
deleted file mode 100644
index 0dba2ea..0000000
--- a/Allura/allura/templates/site_admin_api_tickets.html
+++ /dev/null
@@ -1,66 +0,0 @@
-{#-
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
--#}
-{% set page="api_tickets" %}
-{% extends 'allura:templates/site_admin.html' %}
-
-{% block content %}
-<h1>Special API Tickets</h1>
-<p>API Tickets give access to special APIs which should be used under supervision.
-</p>
-
-<form name="ticket_form" method="POST">
-<table>
-<tr>
-<td>Username:</td> <td><input name="for_user" type="text" value="{{for_user}}"></td>
-</tr>
-<tr>
-<td>Capabilities (JSON):</td> <td><input name="caps" type="text" value="{{caps}}"></td>
-</tr>
-<tr>
-<td>Expiration date:</td> <td><input name="expires" type="text" value="{{expires}}"></td>
-</tr>
-<tr>
-<td><input type="submit" value="Save"><td>
-</tr>
-</table>
-{{lib.csrf_token()}}
-</form>
-
-<table>
-<tr>
-<th>Username</th>
-<th>Expiration Date</th>
-<th>Capabilities</th>
-</tr>
-{% for token in token_list %}
-<tr>
-<td>{{token.user.username}}</td>
-<td>{{token.expires}}</td>
-<td>{{h.json.dumps(token.capabilities)}}</td>
-<td></td>
-</tr>
-<tr>
-<td colspan="3">
-&nbsp;&nbsp;&nbsp;API Ticket: {{token.api_key}}<br/>
-&nbsp;&nbsp;&nbsp;Secret Key: {{token.secret_key}}</td>
-</tr>
-{% endfor %}
-</table>
-
-{% endblock %}