Projet

Général

Profil

Télécharger (5,82 ko) Statistiques
| Branche: | Tag: | Révision:

organization_api / ckanext / ozwillo_organization_api / plugin.py @ a402d093

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