Project

General

Profile

0003-wf-roles-handle-case-when-user-attributes-are-manage.patch

Benjamin Dauvergne, 04 January 2016 04:55 PM

Download (4.68 KB)

View differences:

Subject: [PATCH 3/3] wf/roles: handle case when user attributes are managed by
 the idp (#9210)

If the user's attributes are managed by an idp, we add/remove roles by calling
the idp role management web-services. It only works with authentic2.
 wcs/wf/roles.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)
wcs/wf/roles.py
14 14
# You should have received a copy of the GNU General Public License
15 15
# along with this program; if not, see <http://www.gnu.org/licenses/>.
16 16

  
17
from quixote import get_request, get_publisher
17
import urlparse
18
import urllib
19

  
20
from quixote import get_request, get_publisher, get_response
18 21
from qommon.form import *
19 22
from wcs.workflows import WorkflowStatusItem, register_item_class
20
from wcs.roles import get_user_roles
23
from wcs.roles import get_user_roles, Role
24
from qommon.ident.idp import is_idp_managing_user_attributes
25
from qommon.misc import http_post_request, http_delete_request
26
from qommon.publisher import get_cfg, get_logger
27
from wcs.api import sign_url
28

  
29

  
30
def get_secret(url):
31
    domain = urlparse.urlparse(url).netloc.split(':')[0]
32
    secret = get_publisher().get_site_option(domain, 'api-secrets')
33
    return secret
34

  
35

  
36
def roles_ws_url(role_uuid, user_uuid):
37
    idps = get_cfg('idp', {})
38
    entity_id = idps.values()[0]['metadata_url']
39
    base_url = entity_id.split('idp/saml2/metadata')[0]
40
    url = urlparse.urljoin(base_url, '/api/roles/%s/members/%s/' % (urllib.quote(role_uuid),
41
                                                                     urllib.quote(user_uuid)))
42
    secret = get_secret(url)
43
    orig = get_request().get_server().split(':')[0]
44
    url += '?orig=%s' % orig
45
    return sign_url(url, secret)
46

  
21 47

  
22 48
class AddRoleWorkflowStatusItem(WorkflowStatusItem):
23 49
    description = N_('Add Role to User')
......
50 76
            # we can't work on anonymous or user_hash'ed forms
51 77
            return
52 78
        user = get_publisher().user_class.get(formdata.user_id)
79
        self.perform_local(user, formdata)
80
        if user.name_identifiers and is_idp_managing_user_attributes():
81
            self.perform_idp(user, formdata)
82

  
83
    def perform_local(self, user, formdata):
53 84
        if not user.roles:
54 85
            user.roles = []
55 86
        if not self.role_id in user.roles:
......
60 91
            # changes.
61 92
            get_request().user = user
62 93

  
94
    def perform_idp(self, user, formdata):
95
        role = Role.get(self.role_id)
96
        role_uuid = role.slug
97
        user_uuid = user.name_identifiers[0]
98
        url = roles_ws_url(role_uuid, user_uuid)
99
        def after_job(job):
100
            response, status, data, auth_header = http_post_request(url)
101
            if status != 201:
102
                get_logger().error('failed to add role %r to user %r',
103
                                   role, user)
104
        get_response().add_after_job(
105
            str(N_('Adding role')),
106
            after_job)
107

  
108

  
63 109
register_item_class(AddRoleWorkflowStatusItem)
64 110

  
65 111

  
......
86 132
            # we can't work on anonymous or user_hash'ed forms
87 133
            return
88 134
        user = get_publisher().user_class.get(formdata.user_id)
135
        self.perform_local(user, formdata)
136
        if user.name_identifiers and is_idp_managing_user_attributes():
137
            self.perform_idp(user, formdata)
138

  
139
    def perform_local(self, user, formdata):
89 140
        if user.roles and self.role_id in user.roles:
90 141
            user.roles.remove(self.role_id)
91 142
            user.store()
......
94 145
                # with the changes.
95 146
                get_request().user = user
96 147

  
148
    def perform_idp(self, user, formdata):
149
        role = Role.get(self.role_id)
150
        role_uuid = role.slug
151
        user_uuid = user.name_identifiers[0]
152
        url = roles_ws_url(role_uuid, user_uuid)
153
        def after_job(job):
154
            response, status, data, auth_header = http_delete_request(url)
155
            if status != 200:
156
                get_logger().error('failed to remove role %r from user %r',
157
                                   role, user)
158
        get_response().add_after_job(
159
            str(N_('Removing role')),
160
            after_job)
161

  
97 162
register_item_class(RemoveRoleWorkflowStatusItem)
98
-