Project

General

Profile

Download (4.99 KB) Statistics
| Branch: | Tag: | Revision:

organization_api / ckanext / ozwillo_organization_api / plugin.py @ 606ae999

1 5c8cfd17 Serghei MIHAI
from hashlib import sha1
2
import hmac
3 74d08116 Serghei MIHAI
import requests
4
import logging
5 5c8cfd17 Serghei MIHAI
6
import ckan.plugins as plugins
7 cb821f25 Serghei MIHAI
import ckan.plugins.toolkit as toolkit
8
9 5c8cfd17 Serghei MIHAI
import ckan.logic as logic
10
11
from pylons import config
12
from ckan.common import request, _
13
from ckan.logic.action.create import _group_or_org_create as group_or_org_create
14 74d08116 Serghei MIHAI
from ckan.logic.action.create import user_create
15 7d5492a9 Serghei MIHAI
from ckan.logic.action.delete import _group_or_org_purge
16 5c8cfd17 Serghei MIHAI
17 cb821f25 Serghei MIHAI
plugin_config_prefix = 'ckanext.ozwillo_organization_api.'
18
19 74d08116 Serghei MIHAI
log = logging.getLogger(__name__)
20
21 5c8cfd17 Serghei MIHAI
def valid_signature_required(func):
22 cb821f25 Serghei MIHAI
23 5c8cfd17 Serghei MIHAI
    signature_header_name = config.get(plugin_config_prefix + 'signature_header_name',
24
                                       'X-Hub-Signature')
25 458a2c0b Serghei MIHAI
    instantiated_secret = config.get(plugin_config_prefix + 'instantiation_secret',
26 5c8cfd17 Serghei MIHAI
                                     'secret')
27
28
    def wrapper(context, data):
29
        if signature_header_name in request.headers:
30
            if request.headers[signature_header_name].startswith('sha1='):
31 cb821f25 Serghei MIHAI
                algo, received_hmac = request.headers[signature_header_name].rsplit('=')
32 74d08116 Serghei MIHAI
                computed_hmac = hmac.new(instantiated_secret, request.body, sha1).hexdigest()
33 cb821f25 Serghei MIHAI
                # the received hmac is uppercase according to
34
                # http://doc.ozwillo.com/#ref-3-2-1
35
                if received_hmac != computed_hmac.upper():
36 5c8cfd17 Serghei MIHAI
                    raise logic.NotAuthorized(_('Invalid HMAC'))
37
            else:
38
                raise logic.ValidationError(_('Invalid HMAC algo'))
39
        else:
40
            raise logic.NotAuthorized(_("No HMAC in the header"))
41
        return func(context, data)
42
    return wrapper
43
44
@valid_signature_required
45
def create_organization(context, data_dict):
46 74d08116 Serghei MIHAI
    context['ignore_auth'] = True
47
    model = context['model']
48 cb821f25 Serghei MIHAI
49
    destruction_secret = config.get(plugin_config_prefix + 'destruction_secret',
50
                                       'changeme')
51
52
    client_id = data_dict.pop('client_id')
53
    client_secret = data_dict.pop('client_secret')
54
    instance_id = data_dict.pop('instance_id')
55
56
    # re-mapping received dict
57
    registration_uri = data_dict.pop('instance_registration_uri')
58
    organization = data_dict['organization']
59 74d08116 Serghei MIHAI
    user = data_dict['user']
60 cb821f25 Serghei MIHAI
    org_dict = {
61
        'type': 'organization',
62 74d08116 Serghei MIHAI
        'name': organization['name'].lower(),
63 0225110e Serghei MIHAI
        'id': instance_id,
64 74d08116 Serghei MIHAI
        'title': organization['name'],
65 cb821f25 Serghei MIHAI
        'description': organization['type'],
66 74d08116 Serghei MIHAI
        'user': user['name']
67
    }
68
69
    user_dict = {
70
        'name': user['name'],
71
        'email': user['email_address'],
72
        'password': user['id']
73 cb821f25 Serghei MIHAI
    }
74 74d08116 Serghei MIHAI
    user_obj = model.User.get(user_dict['name'])
75
    if not user_obj:
76
        user_create(context, user_dict)
77
78
    context['user'] = user_dict['name']
79
80 cb821f25 Serghei MIHAI
    try:
81
        delete_uri = toolkit.url_for(controller='api', action='action',
82
                                     logic_function="delete-organization",
83
                                     ver=context['api_version'],
84
                                     qualified=True)
85 74d08116 Serghei MIHAI
        organization_uri = toolkit.url_for(host=request.host,
86
                                           controller='organization',
87
                                           action='read',
88
                                           id=org_dict['name'],
89
                                           qualified=True)
90
91 cb821f25 Serghei MIHAI
92
        group_or_org_create(context, org_dict, is_org=True)
93
94 74d08116 Serghei MIHAI
        # setting organization as active explicitely
95
        group = model.Group.get(org_dict['name'])
96
        group.state = 'active'
97
        group.save()
98
99 cb821f25 Serghei MIHAI
        # notify about organization creation
100
        services = {'services': [{
101
            'local_id': 'organization',
102
            'name': 'Organization ' + org_dict['name'] + ' on CKAN',
103 74d08116 Serghei MIHAI
            'service_uri': organization_uri,
104 cb821f25 Serghei MIHAI
            'visible': True}],
105
            'instance_id': instance_id,
106
            'destruction_uri': delete_uri,
107
            'destruction_secret': destruction_secret,
108
            'needed_scopes': [{
109
                'scope_id': 'profile',
110
                'motivation': 'Used to link user to the organization'
111
            }]
112
        }
113 606ae999 Serghei MIHAI
        headers = {'Content-type': 'application/json',
114
                   'Accept': 'application/json'}
115 cb821f25 Serghei MIHAI
        requests.post(registration_uri,
116
                      data = services,
117 606ae999 Serghei MIHAI
                      auth=(client_id, client_secret),
118
                      headers=headers
119 cb821f25 Serghei MIHAI
                  )
120 74d08116 Serghei MIHAI
    except Exception, e:
121
        log.debug('Exception "%s" occured while creating organization' % e)
122 458a2c0b Serghei MIHAI
        requests.delete(registration_uri)
123 cb821f25 Serghei MIHAI
124 5c8cfd17 Serghei MIHAI
125
@valid_signature_required
126
def delete_organization(context, data_dict):
127 7d5492a9 Serghei MIHAI
    data_dict['id'] = data_dict.pop('instance_id')
128
    context['ignore_auth'] = True
129
    _group_or_org_purge(context, data_dict, is_org=True)
130 5c8cfd17 Serghei MIHAI
131
132
class OzwilloOrganizationApiPlugin(plugins.SingletonPlugin):
133
    """
134
    API for OASIS to create and delete an organization
135
    """
136
    plugins.implements(plugins.IActions)
137
138
    def get_actions(self):
139
        return {
140 f81cd06f Serghei MIHAI
            'create-ozwillo-organization': create_organization,
141
            'delete-ozwillo-organization': delete_organization
142 5c8cfd17 Serghei MIHAI
        }