DBA Data[Home] [Help]

PACKAGE BODY: APPS.UMX_PASSWORD_PVT

Source


1 PACKAGE BODY UMX_PASSWORD_PVT AS
2   /* $Header: UMXVUPWB.pls 120.5 2006/07/20 23:56:53 kching noship $ */
3 
4   g_itemtype wf_item_types.name%type := 'UMXUPWD';
5   -- Private function to get the email address of the active user from
6   -- 1) WF local roles
7   -- 2) FND User
8   -- 3) The first TCA party
9   procedure get_email_address (p_user_name               in fnd_user.user_name%type,
10                                x_role_name               out nocopy varchar2,
11                                x_email_address           out nocopy varchar2,
12                                x_notification_preference out nocopy varchar2,
13                                x_message_name            out nocopy varchar2,
14                                x_message_data            out nocopy varchar2) is
15 
16     -- TCA Party declares email address as varchar2 2000, largest amount the
17     -- three schema.
18     l_role_display_name        wf_local_roles.display_name%type;
19     l_language                 wf_local_roles.language%type;
20     l_territory                wf_local_roles.territory%type;
21 
22     cursor get_fnd_email (p_user_name in fnd_user.user_name%type) is
23       SELECT email_address
24       FROM fnd_user
25       WHERE user_name = p_user_name
26       AND start_date <= sysdate
27       AND nvl(end_date, sysdate + 1) > sysdate;
28 
29     cursor get_tca_email (p_user_name in fnd_user.user_name%type) is
30       SELECT hzp.email_address
31       FROM hz_parties hzp, fnd_user fu
32       WHERE hzp.party_id = fu.person_party_id
33       AND fu.user_name = p_user_name;
34 
35   begin
36 
37     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
38       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
39                       'fnd.plsql.UMXVUPWB.get_email_address.begin',
40                       'p_user_name: ' || p_user_name);
41     end if;
42 
43     -- First get the email from wf directory
44     WF_DIRECTORY.GetRoleInfo (p_user_name, l_role_display_name, x_email_address,
45                               x_notification_preference, l_language, l_territory);
46 
47     if x_email_address is not null then
48       x_role_name := p_user_name;
49     else
50       -- Try to get the email from fnd_user
51       open get_fnd_email (p_user_name);
52       fetch get_fnd_email into x_email_address;
53       if (get_fnd_email%NOTFOUND) then
54         x_message_name := 'UMX_FORGOT_PWD_INVALID_ACCT';
55         fnd_message.set_name('FND', x_message_name);
56         x_message_data := fnd_message.get;
57       else
58         if x_email_address is null then
59           -- if email is still null then get it from tca
60           -- check if there is a valid party email
61           for party in get_tca_email (p_user_name) loop
62             x_email_address := party.email_address;
63             exit when x_email_address is not null;
64           end loop;
65         end if;
66       end if;
67       close get_fnd_email;
68     end if;
69 
70     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
71       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
72                       'fnd.plsql.UMXVUPWB.get_email_address.end',
73                       'x_role_name: ' || x_role_name ||
74                       ' | x_email_address: ' || x_email_address ||
75                       ' | x_message_name: ' || x_message_name ||
76                       ' | x_message_data: ' || x_message_data);
77     end if;
78 
79   end get_email_address;
80 
81   function get_username_from_userid (p_user_id  in fnd_user.user_id%type) return fnd_user.user_name%type is
82 
83     cursor get_username_from_userid is
84       select user_name
85       from   fnd_user
86       where  user_id = p_user_id;
87 
88     l_user_name fnd_user.user_name%type;
89 
90   begin
91 
92     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
93       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
94                       'fnd.plsql.UMXVUPWB.get_username_from_userid.begin',
95                       'p_user_id: ' || p_user_id);
96     end if;
97 
98     open get_username_from_userid;
99     fetch get_username_from_userid into l_user_name;
100     if (get_username_from_userid%notfound) then
101       close get_username_from_userid;
102       if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_EXCEPTION) then
103         FND_LOG.STRING (FND_LOG.LEVEL_EXCEPTION,
104                         'fnd.plsql.UMXVUPWB.ForgotPwd',
105                         'Username cannot be found with userid (' || p_user_id || ')');
106       end if;
107       fnd_message.set_name ('FND', 'UMX_COMMON_UNEXPECTED_ERR_MSG');
108       raise_application_error ('-20000', fnd_message.get);
109     end if;
110     close get_username_from_userid;
111 
112     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
113       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
114                       'fnd.plsql.UMXVUPWB.get_username_from_userid.end',
115                       'l_user_name: ' || l_user_name);
116     end if;
117 
118     return l_user_name;
119 
120   end;
121 
122   -- Procedure  : validate_password
123   -- Type       : Private
124   -- Pre_reqs   :
125   -- Description: This API will validate the user's password.
126   -- Parameters
127   -- input parameters :
128   --    p_username - username of the password's owner
129   --    p_password - password to validate
130   -- output parameters:
131   --    x_return_status - Returns FND_API.G_RET_STS_SUCCESS if success
132   --                    - Returns FND_API.G_RET_STS_ERROR if failed
133   --    x_message_data  - Reason why it is failed.
134   -- Errors      :
135   -- Other Comments :
136   Procedure validate_password (p_username      in fnd_user.user_name%type,
137                                p_password      in varchar2,
138                                x_return_status out NOCOPY varchar2,
139                                x_message_data  out NOCOPY varchar2) is
140 
141   BEGIN
142 
143     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
144       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
145                       'fnd.plsql.UMXVUPWB.validate_password.begin',
146                       'p_username: ' || p_username ||
147                       ' | p_password: ' || p_password);
148     end if;
149 
150     -- Get username from user id if username is null
151     if (fnd_web_sec.validate_password (p_username, p_password) = 'N') then
152       x_return_status := FND_API.G_RET_STS_ERROR;
153       x_message_data := fnd_message.get ();
154     else
155       x_return_status := FND_API.G_RET_STS_SUCCESS;
156     end if;
157 
158     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
159       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
160                       'fnd.plsql.UMXVUPWB.validate_password.end',
161                       'x_return_status: ' || x_return_status ||
162                       ' | x_message_data: ' || x_message_data);
163     end if;
164 
165   END;
166 
167   /**
168    * Function    :  generate_password
169    * Type        :  Private
170    * Pre_reqs    :
171    * Description : Creates a password. The length of the password is obtained
172    *               from the profile SIGNON_PASSWORD_LENGTH.
173    * Parameters
174    * input parameters : None
175    * output parameters
176    * @return   returns a String that can be used as the password
177    * Errors      :
178    * Other Comments :
179    */
180 
181   function generate_password return varchar2 is
182 
183     l_password_len int := 6;
184     x_password     varchar2(40);
185     ascii_offset   int := 65;
186 
187   begin
188 
189     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
190       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
191                       'fnd.plsql.UMXVUPWB.generate_password.begin', '');
192     end if;
193 
194     -- initialize the random number generator
195     --dbms_random.initialize(dbms_utility.get_time);
196 
197     -- using the profile, determine the length of the random number
198     l_password_len := greatest(nvl(fnd_profile.value('SIGNON_PASSWORD_LENGTH'), l_password_len), l_password_len);
199 
200     -- generate a random number to determine where to use an alphabet or a
201     -- numeric character for a given position in the password
202 
203     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
204       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
205                       'fnd.plsql.UMXVUPWB.generate_password',
206                       'l_password_len: ' || l_password_len);
207     end if;
208 
209     for j in 1..l_password_len loop
210       if (mod(abs(dbms_random.random),2) = 1) then
211         -- generate number
212         x_password := x_password || mod(abs(FND_CRYPTO.SmallRandomNumber),10);
213       else
214         -- generate character
215         x_password := x_password || fnd_global.local_chr(mod(abs(FND_CRYPTO.SmallRandomNumber),26)
216             + ascii_offset);
217       end if;
218     end loop;
219 
220     -- terminate the random number generator
221     --dbms_random.terminate;
222 
223     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
224       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
225                       'fnd.plsql.UMXVUPWB.generate_password.end',
226                       'x_password: ' || x_password);
227     end if;
228 
229     return x_password;
230 
231   end generate_password;
232 
233   Procedure SetPassword (p_username in fnd_user.user_name%type,
234                          x_password in out NOCOPY varchar2) is
235 
236     l_result varchar2(10);
237     v_counter BINARY_INTEGER := 1;
238 
239   begin
240 
241     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
242       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
243                       'fnd.plsql.UMXVUPWB.SetPassword.begin',
244                       'p_username: ' || p_username ||
245                       ' | x_password: ' || x_password);
246     end if;
247 
248     if (x_password is null) then
249       x_password := generate_password;
250 
251       -- code for validating the generated username
252 
253       -- loop till password clears the validations
254       l_result := FND_WEB_SEC.validate_password (p_username, x_password);
255       WHILE ((l_result <> 'Y') AND (v_counter <= 100)) LOOP
256         v_counter := v_counter + 1;
257         x_password := generate_password;
258         l_result := FND_WEB_SEC.validate_password (p_username, x_password);
259       END LOOP;
260 
261       IF (( v_counter > 100 ) and ( l_result <> 'Y' )) THEN
262         -- Throw exception as even though generated password 100 times, but
263         -- cannot pass validation criteria
264         if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_EXCEPTION) then
265           FND_LOG.STRING (FND_LOG.LEVEL_EXCEPTION,
266                           'fnd.plsql.UMXVUPWB.ForgotPwd',
267                           'Could not generated password automatically which satisfies validation requirements.');
268         end if;
269         fnd_message.set_name ('FND', 'UMX_COMMON_UNEXPECTED_ERR_MSG');
270         raise_application_error ('-20000', fnd_message.get);
271       END IF;
272 
273       -- end of code for validating username
274 
275     end if;
276 
277     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
278       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
279                       'fnd.plsql.UMXVUPWB.SetPassword.end',
280                       'x_password: ' || x_password);
281     end if;
282 
283   end;
284 
285   Procedure SetPassword_WF(itemtype  in varchar2,
286                            itemkey   in varchar2,
287                            actid     in number,
288                            funcmode  in varchar2,
289                            resultout in out NOCOPY varchar2) is
290 
291     l_password varchar2(40);
292     l_user_name fnd_user.user_name%type;
293 
294   begin
295     if (funcmode = 'RUN') then
296       -- Check if the password is already set.
297       l_password := WF_ENGINE.GetActivityAttrText (
298           itemtype => itemtype,
299           itemkey  => itemkey,
300           actid    => actid,
301           aname    => 'PASSWORD');
302 
303       if (l_password is null) then
304         -- code for validating the generated username
305         -- get the username
306         l_user_name := WF_ENGINE.GetActivityAttrText(
307             itemtype => itemtype,
308             itemkey  => itemkey,
309             actid    => actid,
310             aname    => 'USER_NAME');
311 
312         SetPassword (p_username => l_user_name,
313                      x_password  => l_password);
314 
315         wf_engine.SetItemAttrText (itemtype => itemtype,
316                                    itemkey  => itemkey,
317                                    aname    => 'PASSWORD',
318                                    avalue   => l_password);
319 
320       end if;
321     end if;
322 
323     resultout := WF_ENGINE.eng_completed || ':' || WF_ENGINE.eng_null;
324 
325   exception
326     when others then
327       Wf_Core.Context('UMX_PASSWORD_PVT', 'SetPassword_WF', itemtype, itemkey, actid);
328       raise;
329   end;
330 
331   -------------------------------------------------------------------
332   -- Name:        UpdatePassword_WF
333   -- Description: Calls FND_USER_PKG.UpdateUserParty
334   -------------------------------------------------------------------
335   Procedure UpdatePassword_WF(itemtype  in varchar2,
336                               itemkey   in varchar2,
337                               actid     in number,
338                               funcmode  in varchar2,
339                               resultout in out NOCOPY varchar2) is
340 
341   begin
342 
343     if (funcmode = 'RUN') then
344 
345       FND_USER_PKG.UpdateUserParty (
346           x_user_name                  =>
347               WF_ENGINE.GetActivityAttrText(itemtype, itemkey, actid,
348                                             'USER_NAME', TRUE),
349           x_owner                      => null,
350           x_unencrypted_password       =>
351               WF_ENGINE.GetActivityAttrText(itemtype, itemkey, actid,
352                                             'PASSWORD', TRUE),
353           x_password_date              => fnd_user_pkg.null_date);
354 
355     end if;
356 
357     resultout := WF_ENGINE.eng_completed || ':' || WF_ENGINE.eng_null;
358 
359   exception
360     when others then
361       Wf_Core.Context('UMX_PASSWORD_PVT', 'UpdatePassword_WF', itemtype, itemkey,
362                       actid);
363       raise;
364   end;
365 
366 
367 
368 /* this method returns a formatted name to be used for display name*/
369 function getDisplayName(username in varchar2) return varchar2 is
370   cursor C_party_id is
371    SELECT person_party_id
372    FROM fnd_user
373    where user_name = username;
374 
375   x_return_status		varchar2(40);
376   x_msg_count			NUMBER;
377   x_msg_data			VARCHAR2(4000);
378   x_formatted_name		VARCHAR2(4000);
379   x_formatted_lines_cnt		NUMBER;
380   x_formatted_name_tbl		hz_format_pub.string_tbl_type;
381   l_party_id number;
382 begin
383   for i in C_party_id loop
384     l_party_id := i.person_party_id;
385   end loop;
386 
387   if l_party_id is null then
388     return username;
389   else
390    Hz_format_pub.format_name (
391   p_party_id	=> l_party_id,
392   x_return_status	=>  x_return_status,
393   x_msg_count	=> x_msg_count,
394   x_msg_data	=> x_msg_data,
395   x_formatted_name => x_formatted_name,
396   x_formatted_lines_cnt	=> x_formatted_lines_cnt,
397   x_formatted_name_tbl	=> x_formatted_name_tbl	);
398 
399       return x_formatted_name;
400   end if;
401 end getDisplayName;
402   -------------------------------------------------------------------
403   -- Name:        CreateRole
404   -- Description: Creates an adhoc role with notification preference always set
405   --              to 'MAIL'. This would ensure that the user would get an email
406   --              for all password related notifications. The name of the role
407   --              is set to FND-username
408   -------------------------------------------------------------------
409   Procedure CreateRole(itemtype  in varchar2,
410                        itemkey   in varchar2,
411                        actid     in number,
412                        funcmode  in varchar2,
413                        resultout in out NOCOPY varchar2) is
414 
415     l_role_name                wf_local_roles.name%type;
416     l_notification_preference  wf_local_roles.notification_preference%type;
417     l_username  fnd_user.user_name%type;
418     l_display_name varchar2(4000);
419   begin
420 
421     if (funcmode = 'RUN') then
422 
423       l_role_name := WF_ENGINE.GetItemAttrText(itemtype, itemkey, 'X_USER_ROLE');
424       l_notification_preference := WF_ENGINE.GetItemAttrText (itemtype, itemkey, 'NOTIFICATION_PREFERENCE');
425 
426       if (l_role_name is NULL) or (l_notification_preference not like 'MAIL%') then
427         -- No role with the user_name, create an ad hoc role.
428         l_username := upper(WF_ENGINE.GetItemAttrText(itemtype, itemkey, 'USER_NAME'));
429         l_role_name := 'FNDPWD_' || itemkey || '_' || l_username;
430         l_display_name := getDisplayName(l_username);
431         WF_DIRECTORY.CreateAdHocRole (
432             role_name         => l_role_name,
433             role_display_name => l_display_name,
434             email_address     => WF_ENGINE.GetItemAttrText(itemtype, itemkey, 'EMAIL_ADDRESS'));
435         wf_engine.SetItemAttrText (itemtype => itemtype,
436                                    itemkey  => itemkey,
437                                    aname    => 'X_USER_ROLE',
438                                    avalue   => l_role_name);
439       end if;
440     end if;
441     resultout := WF_ENGINE.eng_completed || ':' || WF_ENGINE.eng_null;
442 
443   exception
444     when others then
445       Wf_Core.Context('UMX_PASSWORD_PVT', 'CreateRole', itemtype, itemkey,
446                       actid);
447       raise;
448   end CreateRole;
449 
450   -- Private Method to start Workflow
451   procedure start_workflow (p_user_name               in varchar2,
452                             p_password                in varchar2,
453                             p_email_address           in varchar2,
454                             p_role_name               in varchar2,
455                             p_notification_preference in varchar2,
456                             p_user_appr_msg_name      in varchar2,
457                             p_pwd_reset_msg_name      in varchar2,
458                             p_check_identity          in varchar2,
459                             x_itemkey                 out nocopy varchar2) is
460   begin
461 
462     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
463       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
464                       'fnd.plsql.UMXVUPWB.start_workflow.begin',
465                       'p_user_name: ' || p_user_name ||
466                       ' | p_email_address: ' || p_email_address ||
467                       ' | p_role_name: ' || p_role_name ||
468                       ' | p_user_appr_msg_name: ' || p_user_appr_msg_name ||
469                       ' | p_pwd_reset_msg_name: ' || p_pwd_reset_msg_name ||
470                       ' | p_check_identity: ' || p_check_identity);
471     end if;
472 
473     select to_char (UMX_PASSWORD_WF_S.Nextval) into x_itemkey from dual;
474 
475     -- start the workflow that will send the notification and reset
476     -- the password
477 
478     wf_engine.CreateProcess(itemtype => g_itemtype,
479                             itemkey  => x_itemkey,
480                             process  => 'RESETPASSWD');
481 
482     wf_engine.SetItemAttrText(itemtype => g_itemtype,
483                               itemkey  => x_itemkey,
484                               aname    => 'USER_NAME',
485                               avalue   => p_user_name);
486 
487     wf_engine.SetItemAttrText(itemtype => g_itemtype,
488                               itemkey  => x_itemkey,
489                               aname    => 'PASSWORD',
490                               avalue   => p_password);
491 
492     if p_email_address is not null then
493       wf_engine.SetItemAttrText (itemtype => g_itemtype,
494                                  itemkey  => x_itemkey,
495                                  aname    => 'EMAIL_ADDRESS',
496                                  avalue   => p_email_address);
497     end if;
498 
499     if p_role_name is not null then
500       wf_engine.SetItemAttrText (itemtype => g_itemtype,
501                                  itemkey  => x_itemkey,
502                                  aname    => 'X_USER_ROLE',
503                                  avalue   => p_role_name);
504     end if;
505 
506     if p_notification_preference is not null then
507       wf_engine.SetItemAttrText (itemtype => g_itemtype,
508                                  itemkey  => x_itemkey,
509                                  aname    => 'NOTIFICATION_PREFERENCE',
510                                  avalue   => p_notification_preference);
511     end if;
512 
513     if p_user_appr_msg_name is not null then
514       wf_engine.SetItemAttrText(itemtype => g_itemtype,
515                                 itemkey  => x_itemkey,
516                                 aname    => 'APPR_MESSAGE',
517                                 avalue   => p_user_appr_msg_name);
518     end if;
519 
520     if p_pwd_reset_msg_name is not null then
521       wf_engine.SetItemAttrText(itemtype => g_itemtype,
522                                 itemkey  => x_itemkey,
523                                 aname    => 'CONFIRM_MSG',
524                                 avalue   => p_pwd_reset_msg_name);
525     end if;
526 
527     -- Only update if the Notify User Flag is 'Y' or 'N'
528     if  (p_check_identity = 'Y') or (p_check_identity = 'N') then
529       wf_engine.SetItemAttrText (itemtype => g_itemtype,
530                                  itemkey  => x_itemkey,
531                                  aname    => 'L_CHECK_IDENTITY_FLAG',
532                                  avalue   => p_check_identity);
533     end if;
534 
535     wf_engine.StartProcess(itemtype => g_itemtype,
536                            itemkey  => x_itemkey);
537 
538     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
539       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
540                       'fnd.plsql.UMXVUPWB.start_workflow.end',
541                       'x_itemkey: ' || x_itemkey);
542     end if;
543   end start_workflow;
544 
545   -- Private Method
546   procedure ResetPwdPvt (p_username              in fnd_user.user_name%type,
547                          p_password              in varchar2 default null,
548                          p_user_appr_msg_name    in varchar2 default null,
549                          p_pwd_reset_msg_name    in varchar2 default null,
550                          p_check_identity        in varchar2 default 'Y',
551                          p_report_no_email_error in varchar2 default 'N',
552                          x_return_status         out NOCOPY varchar2,
553                          x_message_name          out NOCOPY varchar2,
554                          x_message_data          out NOCOPY varchar2) is
555 
556     l_user_name                fnd_user.user_name%type := upper(p_username);
557     l_email_address            varchar2(2000);
558     l_role_name                wf_local_roles.name%type;
559     l_password                 varchar2(40);
560     l_notification_preference  wf_local_roles.notification_preference%type;
561     l_result                   wf_item_activity_statuses.activity_result_code%type;
562     l_status                   wf_item_activity_statuses.activity_status%type;
563     l_itemkey                  wf_items.item_key%type;
564     l_pwdChangeable            boolean := null;
565     l_nonExistentUser          boolean := false;
566 
567   begin
568 
569     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
570       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
571                       'fnd.plsql.UMXVUPWB.ResetPwdPvt.begin',
572                       'p_username: ' || p_username ||
573                       ' | p_password: ' || p_password ||
574                       ' | p_user_appr_msg_name: ' || p_user_appr_msg_name ||
575                       ' | p_pwd_reset_msg_name: ' || p_pwd_reset_msg_name ||
576                       ' | p_check_identity: ' || p_check_identity);
577     end if;
578 
579     -- initialize the return status
580     x_return_status := FND_API.G_RET_STS_ERROR;
581 
582     -- validate required fields
583     -- validate user name
584     if l_user_name is NULL then
585       x_message_name := 'UMX_FORGOT_PWD_NULL_USER';
586       fnd_message.set_name('FND', x_message_name);
587       x_message_data := fnd_message.get;
588     else
589       if FND_SSO_Manager.isPasswordChangeable (l_user_name) THEN
590         get_email_address (l_user_name, l_role_name, l_email_address,
591                            l_notification_preference, x_message_name,
592                            x_message_data);
593         if (x_message_name is null) then
594           if (l_email_address is not null) then
595             -- Start Workflow to reset user's password.
596             start_workflow (l_user_name, p_password, l_email_address, l_role_name,
597                             l_notification_preference, p_user_appr_msg_name,
598                             p_pwd_reset_msg_name, p_check_identity, l_itemkey);
599             -- Check if the workflow is in error status
600             wf_engine.itemstatus (g_itemtype, l_itemkey, l_status, l_result);
601             if (l_status = 'ERROR') then
602               -- Error status
603               x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
604               x_message_name := 'UMX_FORGOT_PWD_UNEXP_ERR_MSG';
605             else
606               -- Not error, return notified message.
607               x_return_status := FND_API.G_RET_STS_SUCCESS;
608               x_message_name  := 'UMX_FORGOT_PWD_NOTIFY';
609             end if;
610             fnd_message.set_name('FND', x_message_name);
611             x_message_data := fnd_message.get;
612           else -- email address is null
613             if (p_report_no_email_error = 'Y') then
614               -- At the moment, only forgot password will require to raise
615               -- error message if email address is missing.
616               x_message_name := 'UMX_FORGOT_PWD_NULL_EMAIL';
617               fnd_message.set_name ('FND', x_message_name);
618               x_message_data := fnd_message.get;
619             else
620               -- Reset the password without starting a workflow
621               l_password := p_password;
622               SetPassword (p_username  => l_user_name,
623                            x_password  => l_password);
624               FND_USER_PKG.UpdateUserParty (
625                   x_user_name            => l_user_name,
626                   x_owner                => null,
627                   x_unencrypted_password => l_password,
628                   x_password_date        => fnd_user_pkg.null_date);
629               x_return_status := FND_API.G_RET_STS_SUCCESS;
630             end if;
631           end if;
632         end if;
633       else -- cannot change password for this user
634 
635         /*
636         -- Second phase will allow re-direct to different site to change password
637         -- else if l_auth_mode = 'EXTERNAL'
638         -- then
639         -- get the value of the profile option FND_PASSWORD_EXTERNAL_SITE
640         -- create the link woth this url (redirection to the whatever the
641         -- profile options says. If null give them the standard error message below
642         -- owa_util.redirect_url(l_external_password_site);th_mode = 'EXTERNAL' then
643         */
644 
645         x_message_name := 'UMX_FORGOT_PWD_EXTERNAL';
646         fnd_message.set_name('FND', x_message_name);
647         x_message_data := fnd_message.get;
648 
649       end if;
650     end if;
651 
652     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
653       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
654                       'fnd.plsql.UMXVUPWB.ResetPwdPvt.end',
655                       'x_return_status: ' || x_return_status ||
656                       ' | x_message_name: ' || x_message_name ||
657                       ' | x_message_data: ' || x_message_data);
658     end if;
659   EXCEPTION
660       when FND_SSO_MANAGER.userNotFound then
661         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
662         --x_message_name := 'UMX_FORGOT_PWD_UNEXP_ERR_MSG';
663         x_message_name := 'UMX_FORGOT_PWD_INVALID_ACCT';
664         fnd_message.set_name('FND', x_message_name);
665         x_message_data := fnd_message.get;
666 
667   END ResetPwdPvt;
668 
669 
670   procedure ResetPwd (p_username           in fnd_user.user_name%type,
671                       p_password           in varchar2 default null,
672                       p_user_appr_msg_name in varchar2 default null,
673                       p_pwd_reset_msg_name in varchar2 default null,
674                       p_check_identity     in varchar2 default 'Y',
675                       x_return_status      out NOCOPY varchar2,
676                       x_message_data       out NOCOPY varchar2) is
677 
678   x_message_name varchar2(80);
679 
680   begin
681 
682     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
683       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
684                       'fnd.plsql.UMXVUPWB.ResetPwd.begin',
685                       'p_username: ' || p_username ||
686                       ' | p_password: ' || p_password ||
687                       ' | p_user_appr_msg_name: ' || p_user_appr_msg_name ||
688                       ' | p_pwd_reset_msg_name: ' || p_pwd_reset_msg_name ||
689                       ' | p_check_identity: ' || p_check_identity);
690     end if;
691 
692     ResetPwdPvt (p_username             => p_username,
693                  p_password             => p_password,
694                  p_user_appr_msg_name   => p_user_appr_msg_name,
695                  p_pwd_reset_msg_name   => p_pwd_reset_msg_name,
696                  p_check_identity       => p_check_identity,
697                  x_return_status        => x_return_status,
698                  x_message_name         => x_message_name,
699                  x_message_data         => x_message_data);
700 
701     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
702       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
703                       'fnd.plsql.UMXVUPWB.ResetPwd.end',
704                       'x_return_status: ' || x_return_status ||
705                       ' | x_message_data: ' || x_message_data);
706     end if;
707 
708   end ResetPwd;
709 
710   procedure ForgotPwd(p_username           in fnd_user.user_name%type,
711                       p_user_appr_msg_name in varchar2 default null,
712                       p_pwd_reset_msg_name in varchar2 default null,
713                       p_check_identity     in varchar2 default 'Y',
714                       x_return_status      out NOCOPY varchar2,
715                       x_message_name       out NOCOPY varchar2,
716                       x_message_data       out NOCOPY varchar2) is
717   begin
718 
719     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
720       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
721                       'fnd.plsql.UMXVUPWB.ForgotPwd.begin',
722                       'p_username: ' || p_username ||
723                       ' | p_user_appr_msg_name: ' || p_user_appr_msg_name ||
724                       ' | p_pwd_reset_msg_name: ' || p_pwd_reset_msg_name ||
725                       ' | p_check_identity: ' || p_check_identity);
726     end if;
727 
728     ResetPwdPvt (p_username              => p_username,
729                  p_user_appr_msg_name    => p_user_appr_msg_name,
730                  p_pwd_reset_msg_name    => p_pwd_reset_msg_name,
731                  p_check_identity        => p_check_identity,
732                  p_report_no_email_error => 'Y',
733                  x_return_status         => x_return_status,
734                  x_message_name          => x_message_name,
735                  x_message_data          => x_message_data);
736 
737     if (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_PROCEDURE) then
738       FND_LOG.STRING (FND_LOG.LEVEL_PROCEDURE,
739                       'fnd.plsql.UMXVUPWB.ForgotPwd.end',
740                       'x_return_status: ' || x_return_status ||
741                       ' | x_message_name: ' || x_message_name ||
742                       ' | x_message_data: ' || x_message_data);
743     end if;
744 
745   end ForgotPwd;
746 
747   -------------------------------------------------------------------
748   -- Name:        clean_up_ad_hoc_role
749   -- Description: This API set the status to inactive and expiration
750   --              date to sysdate of the ad hoc role created by the password
751   --              workflow.
752   -------------------------------------------------------------------
753   Procedure clean_up_ad_hoc_role (itemtype  in varchar2,
754                                   itemkey   in varchar2,
755                                   actid     in number,
756                                   funcmode  in varchar2,
757                                   resultout in out NOCOPY varchar2) is
758 
759     l_role_name                wf_local_roles.name%type;
760 
761   begin
762 
763     if (funcmode = 'RUN') then
764       l_role_name := WF_ENGINE.GetItemAttrText (itemtype, itemkey, 'X_USER_ROLE');
765 
766       -- First check Ad Hoc Role is being used.
767       if (l_role_name = 'FNDPWD_' || itemkey || '_' || upper(WF_ENGINE.GetItemAttrText(itemtype, itemkey, 'USER_NAME'))) then
768 
769         -- Make Ad Hoc Role to expire.
770         -- The expiration_date is set to +30 based on the recommandation from WF.
771         wf_directory.SetAdHocRoleExpiration (role_name       => l_role_name,
772                                              expiration_date => sysdate + 30);
773 
774         -- Set Ad Hoc Role to inactive
775         wf_directory.SetAdHocRoleStatus (role_name => l_role_name,
776                                          status    => 'INACTIVE');
777       end if;
778     end if;
779 
780     resultout := WF_ENGINE.eng_completed || ':' || WF_ENGINE.eng_null;
781 
782   exception
783     when others then
784       Wf_Core.Context('UMX_PASSWORD_PVT', 'clean_up_ad_hoc_role', itemtype, itemkey,
785                       actid);
786       raise;
787   end;
788 
789 END UMX_PASSWORD_PVT;