3
3
Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
4
"""
5
5
import os
6
- import shutil
7
6
7
+ from com .bea .common .security .utils .encoders import BASE64Encoder
8
+ from com .bea .common .security .xacml import DocumentParseException
9
+ from com .bea .common .security .xacml import URISyntaxException
10
+ from com .bea .security .providers .xacml .entitlement import EntitlementConverter
11
+ from com .bea .security .xacml .cache .resource import ResourcePolicyIdUtil
8
12
from java .io import File
9
13
from java .lang import String
10
14
11
15
from wlsdeploy .aliases .model_constants import POLICY
12
16
from wlsdeploy .aliases .model_constants import RESOURCE_ID
17
+ from wlsdeploy .aliases .model_constants import WLS_POLICIES
13
18
from wlsdeploy .exception import exception_helper
14
- import wlsdeploy .util .unicode_helper as str_helper
15
-
16
- import com .bea .common .security .utils .encoders .BASE64Encoder as BASE64Encoder
17
- import com .bea .common .security .xacml .DocumentParseException as DocumentParseException
18
- import com .bea .common .security .xacml .URISyntaxException as URISyntaxException
19
- import com .bea .security .providers .xacml .entitlement .EntitlementConverter as EntitlementConverter
20
- import com .bea .security .xacml .cache .resource .ResourcePolicyIdUtil as ResourcePolicyIdUtil
19
+ from wlsdeploy .tool .util import ldif_entry
20
+ from wlsdeploy .tool .util .ldif_entry import LDIFEntry
21
+ from wlsdeploy .util import dictionary_utils
22
+ from wlsdeploy .util import unicode_helper as str_helper
21
23
22
24
_DOMAIN_SECURITY_SUBDIR = 'security'
23
25
_WLS_XACML_AUTHORIZER_LDIFT_FILENAME = 'XACMLAuthorizerInit.ldift'
24
26
_WL_HOME_AUTHORIZER_LDIFT_FILE = os .path .join ('server' , 'lib' , _WLS_XACML_AUTHORIZER_LDIFT_FILENAME )
25
- _WLS_POLICY_DN_TEMPLATE = 'dn: cn=%s+xacmlVersion=1.0,ou=Policies,ou=XACMLAuthorization,ou=@realm@,dc=@domain@\n '
27
+ _WLS_POLICY_DN_TEMPLATE = 'dn: cn=%s+xacmlVersion=1.0,ou=Policies,ou=XACMLAuthorization,ou=@realm@,dc=@domain@'
28
+
26
29
27
30
class WebLogicPoliciesHelper (object ):
28
31
"""
@@ -50,7 +53,6 @@ def __init__(self, model_context, logger, exception_type):
50
53
self ._target_xacml_authorizer_ldift_dir = os .path .join (domain_home , _DOMAIN_SECURITY_SUBDIR )
51
54
self ._target_xacml_authorizer_ldift_file = \
52
55
os .path .join (self ._target_xacml_authorizer_ldift_dir , _WLS_XACML_AUTHORIZER_LDIFT_FILENAME )
53
- self ._target_xacml_authorizer_ldift_temp_file = '%s.new' % self ._target_xacml_authorizer_ldift_file
54
56
else :
55
57
ex = exception_helper .create_exception (exception_type , 'WLSDPLY-02001' )
56
58
self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
@@ -69,8 +71,7 @@ def update_xacml_authorizer(self, model_policies_dict):
69
71
return
70
72
71
73
self ._ensure_source_file_and_target_dir ()
72
- policy_entries_map = self ._create_xacml_authorizer_entries (model_policies_dict )
73
- self ._update_xacml_authorizer_ldift (policy_entries_map )
74
+ self ._update_xacml_authorizer_ldift (model_policies_dict )
74
75
self ._logger .exiting (class_name = self .__class_name , method_name = _method_name )
75
76
76
77
def _ensure_source_file_and_target_dir (self ):
@@ -90,94 +91,133 @@ def _ensure_source_file_and_target_dir(self):
90
91
self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
91
92
raise ex
92
93
93
- try :
94
- shutil .copyfile (self ._source_xacml_authorizer_ldift_file , self ._target_xacml_authorizer_ldift_temp_file )
95
- except IOError , ioe :
96
- error = exception_helper .convert_error_to_exception ()
97
- ex = exception_helper .create_exception (self ._exception_type , 'WLSDPLY-02003' ,
98
- self ._target_xacml_authorizer_ldift_dir , error .getLocalizedMssage (),
99
- error = error )
100
- self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
101
- raise ex
102
-
103
94
self ._logger .exiting (class_name = self .__class_name , method_name = _method_name )
104
95
105
- def _create_xacml_authorizer_entries (self , model_policies_map ):
106
- _method_name = '_create_xacml_authorizer_entries'
107
- self ._logger .entering (class_name = self .__class_name , method_name = _method_name )
108
-
109
- entries = dict ()
110
- if model_policies_map is not None :
111
- for model_policy_name , model_policy_dict in model_policies_map .iteritems ():
112
- model_policy_resource_id = model_policy_dict [RESOURCE_ID ]
113
- model_policy_policy = model_policy_dict [POLICY ]
114
- try :
115
- policy = self ._converter .convertResourceExpression (model_policy_resource_id , model_policy_policy )
116
- scope = self ._escaper .escapeString (String (model_policy_resource_id ))
117
- cn = self ._escaper .escapeString (policy .getId ().toString ())
118
- xacml = self ._b64encoder .encodeBuffer (String (policy .toString ()).getBytes ('UTF-8' ))
119
- entry = [
120
- _WLS_POLICY_DN_TEMPLATE % cn ,
121
- 'objectclass: top\n ' ,
122
- 'objectclass: xacmlEntry\n ' ,
123
- 'objectclass: xacmlAuthorizationPolicy\n ' ,
124
- 'objectclass: xacmlResourceScoping\n ' ,
125
- 'cn: %s\n ' % cn ,
126
- 'xacmlResourceScope: %s\n ' % scope ,
127
- 'xacmlVersion: 1.0\n ' ,
128
- 'xacmlStatus: 3\n ' ,
129
- 'xacmlDocument:: %s\n ' % xacml
130
- ]
131
- entries [model_policy_name ] = entry
132
- except DocumentParseException , dpe :
133
- ex = exception_helper .create_exception (self ._exception_type , 'WLSDPLY-02004' , model_policy_name ,
134
- RESOURCE_ID , model_policy_resource_id , POLICY ,
135
- model_policy_policy , dpe .getLocalizedMessage (), error = dpe )
136
- self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
137
- raise ex
138
- except URISyntaxException , use :
139
- ex = exception_helper .create_exception (self ._exception_type , 'WLSDPLY-02005' , model_policy_name ,
140
- RESOURCE_ID , model_policy_resource_id , POLICY ,
141
- model_policy_policy , use .getLocalizedMessage (), error = use )
142
- self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
143
- raise ex
144
-
145
- self ._logger .exiting (class_name = self .__class_name , method_name = _method_name )
146
- return entries
147
-
148
- def _update_xacml_authorizer_ldift (self , policy_entries_map ):
96
+ def _update_xacml_authorizer_ldift (self , model_policies_dict ):
149
97
_method_name = '_update_xacml_authorizer_ldift'
150
98
self ._logger .entering (class_name = self .__class_name , method_name = _method_name )
151
99
152
- self ._logger .finer ('WLSDPLY-02006' , self ._target_xacml_authorizer_ldift_temp_file ,
100
+ self ._logger .finer ('WLSDPLY-02006' , self ._target_xacml_authorizer_ldift_file ,
153
101
class_name = self .__class_name , method_name = _method_name )
154
- ldift_temp_file = None
102
+
103
+ target_ldift_file = None
155
104
try :
156
105
try :
157
- ldift_temp_file = open (self ._target_xacml_authorizer_ldift_temp_file , 'a' )
158
- for model_policy_name , ldift_lines in policy_entries_map .iteritems ():
159
- self ._logger .finer ('WLSDPLY-02007' , model_policy_name ,
160
- class_name = self .__class_name , method_name = _method_name )
161
- ldift_temp_file .write ('\n ' )
162
- ldift_temp_file .writelines (ldift_lines )
106
+ existing_policies = ldif_entry .read_entries (File (self ._source_xacml_authorizer_ldift_file ))
107
+
108
+ # build a map of resource IDs to existing policies
109
+ existing_policy_map = {}
110
+ for policy in existing_policies :
111
+ cn = policy .get_single_value ('cn' )
112
+ if cn :
113
+ policy_id = self ._escaper .unescapeString (cn )
114
+ resource_id = ResourcePolicyIdUtil .getResourceId (policy_id )
115
+ resource_key = _get_resource_key (resource_id )
116
+ existing_policy_map [resource_key ] = policy
117
+
118
+ # for each model policy, update an existing policy, or add a new one
119
+ new_policies = []
120
+ for model_policy_name , model_policy_dict in model_policies_dict .iteritems ():
121
+ model_resource_id = model_policy_dict [RESOURCE_ID ]
122
+ model_policy = model_policy_dict [POLICY ]
123
+ resource_key = _get_resource_key (model_resource_id )
124
+ existing_policy = dictionary_utils .get_element (existing_policy_map , resource_key ) # type: LDIFEntry
125
+ if existing_policy :
126
+ self ._update_policy_from_model (existing_policy , model_policy , model_policy_name )
127
+ else :
128
+ new_policy = self ._create_policy_from_model (model_resource_id , model_policy , model_policy_name )
129
+ new_policies .append (new_policy )
130
+
131
+ target_ldift_file = open (self ._target_xacml_authorizer_ldift_file , 'w' )
132
+ first = True
133
+ all_policies = existing_policies + new_policies
134
+ for policy in all_policies :
135
+ if not first :
136
+ target_ldift_file .write ('\n ' )
137
+ lines_text = '\n ' .join (policy .get_assignment_lines ()) + '\n '
138
+ target_ldift_file .writelines (lines_text )
139
+ first = False
140
+
163
141
except (ValueError ,IOError ,OSError ), error :
164
142
ex = exception_helper .create_exception (self ._exception_type , 'WLSDPLY-02008' ,
165
143
str_helper .to_string (error ), error = error )
166
144
self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
167
145
raise ex
168
146
finally :
169
- if ldift_temp_file is not None :
170
- ldift_temp_file .close ()
147
+ if target_ldift_file is not None :
148
+ target_ldift_file .close ()
149
+
150
+ self ._logger .exiting (class_name = self .__class_name , method_name = _method_name )
151
+
152
+ def _update_policy_from_model (self , policy_entry , model_policy , model_policy_name ):
153
+ _method_name = '_update_policy_from_model'
154
+
155
+ self ._logger .info ('WLSDPLY-02010' , model_policy_name , class_name = self .__class_name , method_name = _method_name )
156
+
157
+ self ._logger .notification ('WLSDPLY-02011' , WLS_POLICIES , model_policy_name ,
158
+ class_name = self .__class_name , method_name = _method_name )
159
+
160
+ scope = policy_entry .get_single_value ('xacmlResourceScope' )
161
+ resource_id = self ._escaper .unescapeString (scope )
162
+ policy = self ._convert_resource_expression (resource_id , model_policy , model_policy_name )
163
+ xacml = self ._b64encoder .encodeBuffer (String (policy .toString ()).getBytes ('UTF-8' ))
164
+
165
+ policy_entry .update_single_field ('xacmlDocument:' , xacml ) # double colon assignment
166
+
167
+ def _create_policy_from_model (self , model_resource_id , model_policy , model_policy_name ):
168
+ _method_name = '_create_policy_from_model'
169
+
170
+ self ._logger .info ('WLSDPLY-02007' , model_policy_name , class_name = self .__class_name , method_name = _method_name )
171
+
172
+ policy = self ._convert_resource_expression (model_resource_id , model_policy , model_policy_name )
173
+ scope = self ._escaper .escapeString (String (model_resource_id ))
174
+ cn = self ._escaper .escapeString (policy .getId ().toString ())
175
+ xacml = self ._b64encoder .encodeBuffer (String (policy .toString ()).getBytes ('UTF-8' ))
176
+
177
+ policy_entry = LDIFEntry ()
178
+ policy_entry .add_assignment_line (_WLS_POLICY_DN_TEMPLATE % cn )
179
+ policy_entry .add_assignment ('objectclass' , 'top' )
180
+ policy_entry .add_assignment ('objectclass' , 'xacmlEntry' )
181
+ policy_entry .add_assignment ('objectclass' , 'xacmlAuthorizationPolicy' )
182
+ policy_entry .add_assignment ('objectclass' , 'xacmlResourceScoping' )
183
+ policy_entry .add_assignment ('cn' , cn )
184
+ policy_entry .add_assignment ('xacmlResourceScope' , scope )
185
+ policy_entry .add_assignment ('xacmlVersion' , '1.0' )
186
+ policy_entry .add_assignment ('xacmlStatus' , 3 )
187
+ policy_entry .add_assignment ('xacmlDocument:' , xacml ) # double colon assignment
188
+ return policy_entry
189
+
190
+ def _convert_resource_expression (self , model_resource_id , model_policy , model_policy_name ):
191
+ _method_name = '_convert_resource_expression'
171
192
172
- # Rename the temp file
173
193
try :
174
- os .rename (self ._target_xacml_authorizer_ldift_temp_file , self ._target_xacml_authorizer_ldift_file )
175
- except OSError , ose :
176
- ex = exception_helper .create_exception (self ._exception_type , 'WLSDPLY-02009' ,
177
- self ._target_xacml_authorizer_ldift_temp_file ,
178
- self ._target_xacml_authorizer_ldift_file ,
179
- str_helper .to_string (ose ), error = ose )
194
+ return self ._converter .convertResourceExpression (model_resource_id , model_policy )
195
+
196
+ except DocumentParseException , dpe :
197
+ ex = exception_helper .create_exception (
198
+ self ._exception_type , 'WLSDPLY-02004' , model_policy_name , RESOURCE_ID ,
199
+ model_resource_id , POLICY , model_policy , dpe .getLocalizedMessage (), error = dpe )
200
+ self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
201
+ raise ex
202
+ except URISyntaxException , use :
203
+ ex = exception_helper .create_exception (
204
+ self ._exception_type , 'WLSDPLY-02005' , model_policy_name , RESOURCE_ID ,
205
+ model_resource_id , POLICY , model_policy , use .getLocalizedMessage (), error = use )
180
206
self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
181
207
raise ex
182
208
183
- self ._logger .exiting (class_name = self .__class_name , method_name = _method_name )
209
+
210
+ def _get_resource_key (resource_id ):
211
+ """
212
+ Create a key from the specified resource ID that can be used for comparison,
213
+ accounting for differences in spaces and ordering.
214
+ *** This key is for comparison and lookup only, don't use it as resource ID ***
215
+ :param resource_id: the resource ID for the key
216
+ :return: the resulting key
217
+ """
218
+ parts = resource_id .split (', ' ) # don't split path={weblogic,common,T3Services}
219
+ just_parts = []
220
+ for part in parts :
221
+ just_parts .append (part .strip ()) # clear any whitespace around the assignment
222
+ just_parts .sort () # put assignments in alpha order in the key only
223
+ return ', ' .join (just_parts )
0 commit comments