Projet

Général

Profil

Télécharger (3,85 ko) Statistiques
| Branche: | Tag: | Révision:

organization_api / ckanext / ozwillo_organization_api / plugin.py @ 458a2c0b

1 5c8cfd17 Serghei MIHAI
from hashlib import sha1
2
import hmac
3
4
import ckan.plugins as plugins
5 cb821f25 Serghei MIHAI
import ckan.plugins.toolkit as toolkit
6
7 5c8cfd17 Serghei MIHAI
import ckan.logic as logic
8
9
from pylons import config
10
from ckan.common import request, _
11
from ckan.logic.action.create import _group_or_org_create as group_or_org_create
12 7d5492a9 Serghei MIHAI
from ckan.logic.action.delete import _group_or_org_purge
13 5c8cfd17 Serghei MIHAI
14 cb821f25 Serghei MIHAI
plugin_config_prefix = 'ckanext.ozwillo_organization_api.'
15
16 5c8cfd17 Serghei MIHAI
def valid_signature_required(func):
17 cb821f25 Serghei MIHAI
18 5c8cfd17 Serghei MIHAI
    signature_header_name = config.get(plugin_config_prefix + 'signature_header_name',
19
                                       'X-Hub-Signature')
20 458a2c0b Serghei MIHAI
    instantiated_secret = config.get(plugin_config_prefix + 'instantiation_secret',
21 5c8cfd17 Serghei MIHAI
                                     'secret')
22
23
    def wrapper(context, data):
24
        if signature_header_name in request.headers:
25
            if request.headers[signature_header_name].startswith('sha1='):
26 cb821f25 Serghei MIHAI
                algo, received_hmac = request.headers[signature_header_name].rsplit('=')
27
                computed_hmac = hmac.new(instantiated_secret, str(data), sha1).hexdigest()
28
                # the received hmac is uppercase according to
29
                # http://doc.ozwillo.com/#ref-3-2-1
30
                if received_hmac != computed_hmac.upper():
31 5c8cfd17 Serghei MIHAI
                    raise logic.NotAuthorized(_('Invalid HMAC'))
32
            else:
33
                raise logic.ValidationError(_('Invalid HMAC algo'))
34
        else:
35
            raise logic.NotAuthorized(_("No HMAC in the header"))
36
        return func(context, data)
37
    return wrapper
38
39
@valid_signature_required
40
def create_organization(context, data_dict):
41 cb821f25 Serghei MIHAI
42
    destruction_secret = config.get(plugin_config_prefix + 'destruction_secret',
43
                                       'changeme')
44
45
    client_id = data_dict.pop('client_id')
46
    client_secret = data_dict.pop('client_secret')
47
    instance_id = data_dict.pop('instance_id')
48
49
    # re-mapping received dict
50
    registration_uri = data_dict.pop('instance_registration_uri')
51
    organization = data_dict['organization']
52
    org_dict = {
53
        'type': 'organization',
54
        'name': organization['organization_name'].lower(),
55 0225110e Serghei MIHAI
        'id': instance_id,
56 cb821f25 Serghei MIHAI
        'title': organization['organization_name'],
57
        'description': organization['type'],
58
    }
59
    try:
60
        delete_uri = toolkit.url_for(controller='api', action='action',
61
                                     logic_function="delete-organization",
62
                                     ver=context['api_version'],
63
                                     qualified=True)
64
65
        group_or_org_create(context, org_dict, is_org=True)
66
67
        # notify about organization creation
68
        services = {'services': [{
69
            'local_id': 'organization',
70
            'name': 'Organization ' + org_dict['name'] + ' on CKAN',
71
            'service_uri': '/organization/' + org_dict['name'],
72
            'visible': True}],
73
            'instance_id': instance_id,
74
            'destruction_uri': delete_uri,
75
            'destruction_secret': destruction_secret,
76
            'needed_scopes': [{
77
                'scope_id': 'profile',
78
                'motivation': 'Used to link user to the organization'
79
            }]
80
        }
81
        requests.post(registration_uri,
82
                      data = services,
83
                      auth=(client_id, client_secret)
84
                  )
85
    except:
86 458a2c0b Serghei MIHAI
        requests.delete(registration_uri)
87 cb821f25 Serghei MIHAI
88 5c8cfd17 Serghei MIHAI
89
@valid_signature_required
90
def delete_organization(context, data_dict):
91 7d5492a9 Serghei MIHAI
    data_dict['id'] = data_dict.pop('instance_id')
92
    context['ignore_auth'] = True
93
    _group_or_org_purge(context, data_dict, is_org=True)
94 5c8cfd17 Serghei MIHAI
95
96
class OzwilloOrganizationApiPlugin(plugins.SingletonPlugin):
97
    """
98
    API for OASIS to create and delete an organization
99
    """
100
    plugins.implements(plugins.IActions)
101
102
    def get_actions(self):
103
        return {
104 f81cd06f Serghei MIHAI
            'create-ozwillo-organization': create_organization,
105
            'delete-ozwillo-organization': delete_organization
106 5c8cfd17 Serghei MIHAI
        }