33Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
44"""
55import os
6- import shutil
76
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
812from java .io import File
913from java .lang import String
1014
1115from wlsdeploy .aliases .model_constants import POLICY
1216from wlsdeploy .aliases .model_constants import RESOURCE_ID
17+ from wlsdeploy .aliases .model_constants import WLS_POLICIES
1318from 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
2123
2224_DOMAIN_SECURITY_SUBDIR = 'security'
2325_WLS_XACML_AUTHORIZER_LDIFT_FILENAME = 'XACMLAuthorizerInit.ldift'
2426_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+
2629
2730class WebLogicPoliciesHelper (object ):
2831 """
@@ -50,7 +53,6 @@ def __init__(self, model_context, logger, exception_type):
5053 self ._target_xacml_authorizer_ldift_dir = os .path .join (domain_home , _DOMAIN_SECURITY_SUBDIR )
5154 self ._target_xacml_authorizer_ldift_file = \
5255 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
5456 else :
5557 ex = exception_helper .create_exception (exception_type , 'WLSDPLY-02001' )
5658 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):
6971 return
7072
7173 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 )
7475 self ._logger .exiting (class_name = self .__class_name , method_name = _method_name )
7576
7677 def _ensure_source_file_and_target_dir (self ):
@@ -90,94 +91,133 @@ def _ensure_source_file_and_target_dir(self):
9091 self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
9192 raise ex
9293
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-
10394 self ._logger .exiting (class_name = self .__class_name , method_name = _method_name )
10495
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 ):
14997 _method_name = '_update_xacml_authorizer_ldift'
15098 self ._logger .entering (class_name = self .__class_name , method_name = _method_name )
15199
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 ,
153101 class_name = self .__class_name , method_name = _method_name )
154- ldift_temp_file = None
102+
103+ target_ldift_file = None
155104 try :
156105 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+
163141 except (ValueError ,IOError ,OSError ), error :
164142 ex = exception_helper .create_exception (self ._exception_type , 'WLSDPLY-02008' ,
165143 str_helper .to_string (error ), error = error )
166144 self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
167145 raise ex
168146 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'
171192
172- # Rename the temp file
173193 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 )
180206 self ._logger .throwing (ex , class_name = self .__class_name , method_name = _method_name )
181207 raise ex
182208
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