Project

General

Profile

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

Benjamin Dauvergne, 27 December 2015 12:19 PM

Download (4.35 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 | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)
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
import urlparse
18
import urllib
19

  
17 20
from quixote import get_request, get_publisher
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_manage_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
        if user.name_identifiers and is_idp_manage_user_attributes():
80
            self.perform_idp(user, formdata)
81
        else:
82
            self.perform_local(user, formdata)
83

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

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

  
105

  
63 106
register_item_class(AddRoleWorkflowStatusItem)
64 107

  
65 108

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

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

  
146
    def perform_idp(self, user, formdata):
147
        role = Role.get(self.role_id)
148
        role_uuid = role.slug
149
        user_uuid = user.name_identifiers[0]
150
        response, status, data, auth_header = http_delete_request(
151
            roles_ws_url(role_uuid, user_uuid))
152
        if status != 200:
153
            get_logger().error('failed to remove role %r from user %r',
154
                               role, user)
155

  
97 156
register_item_class(RemoveRoleWorkflowStatusItem)
98
-