499c02ddfb9c66f20d47ca3068985f3e2d4dc722
[aaf/authz.git] / auth / auth-gui / src / main / java / org / onap / aaf / auth / gui / pages / PassChangeForm.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.auth.gui.pages;
23
24 import static org.onap.aaf.misc.xgen.html.HTMLGen.TABLE;
25
26 import java.io.IOException;
27 import java.net.ConnectException;
28 import java.util.GregorianCalendar;
29
30 import org.onap.aaf.auth.cmd.AAFcli;
31 import org.onap.aaf.auth.env.AuthzTrans;
32 import org.onap.aaf.auth.gui.AAF_GUI;
33 import org.onap.aaf.auth.gui.BreadCrumbs;
34 import org.onap.aaf.auth.gui.NamedCode;
35 import org.onap.aaf.auth.gui.Page;
36 import org.onap.aaf.auth.org.Organization;
37 import org.onap.aaf.auth.org.OrganizationException;
38 import org.onap.aaf.auth.org.OrganizationFactory;
39 import org.onap.aaf.auth.org.Organization.Identity;
40 import org.onap.aaf.cadi.CadiException;
41 import org.onap.aaf.cadi.LocatorException;
42 import org.onap.aaf.cadi.client.Future;
43 import org.onap.aaf.cadi.client.Rcli;
44 import org.onap.aaf.cadi.client.Retryable;
45 import org.onap.aaf.misc.env.APIException;
46 import org.onap.aaf.misc.env.Slot;
47 import org.onap.aaf.misc.xgen.Cache;
48 import org.onap.aaf.misc.xgen.DynamicCode;
49 import org.onap.aaf.misc.xgen.Mark;
50 import org.onap.aaf.misc.xgen.html.HTMLGen;
51
52 import aaf.v2_0.Users;
53
54 public class PassChangeForm extends Page {
55     // Package on purpose
56     static final String HREF = "/gui/passwd";
57     static final String NAME = "PassChange";
58     static final String fields[] = {"id","current","password","password2","startDate","ns"};
59     
60     public PassChangeForm(final AAF_GUI gui, final Page ... breadcrumbs) throws APIException, IOException {
61         super(gui.env,NAME,HREF, fields,
62             new BreadCrumbs(breadcrumbs),
63             new NamedCode(true,NAME) {    
64                 private final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
65                 @Override
66                 public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
67                     
68                     // p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
69                     hgen.incr(HTMLGen.H4,true,"style=margin: 0em 0em .4em 0em")
70                         .text("You are <i>adding</i> a New Password in the AAF System.")
71                         .end();
72
73                     Mark form = new Mark();
74                     hgen.incr(form,"form","method=post");
75                     
76                     Mark table = new Mark(TABLE);
77                     hgen.incr(table);
78
79                     cache.dynamic(hgen, new DynamicCode<HTMLGen, AAF_GUI, AuthzTrans>() {
80                         @Override
81                         public void code(final AAF_GUI gui, final AuthzTrans trans,    final Cache<HTMLGen> cache, final HTMLGen hgen)    throws APIException, IOException {
82                             String incomingID= trans.get(sID, "");
83                             boolean skipCurrent = false;
84                             if (incomingID.length()>0) {
85                                 try {
86                                     Organization org = OrganizationFactory.obtain(trans.env(), incomingID);
87                                     if (org==null) {
88                                         hgen.incr(HTMLGen.H4,"style=color:red;").text("Error: There is no supported company for ").text(incomingID).end();
89                                     } else {
90                                         Identity user = org.getIdentity(trans, incomingID);
91                                         if (user==null) {
92                                             int at = incomingID.indexOf('@');
93                                             hgen.incr(HTMLGen.H4,"style=color:red;").text("Error: You are not the sponsor of '").text(at<0?incomingID:incomingID.substring(0,at))
94                                                 .text("' defined at ").text(org.getName()).end();
95                                             incomingID = "";
96                                         } else {
97                                             // Owners/or the IDs themselves are allowed to reset password without previous one
98                                             skipCurrent=skipCurrent(trans, user);
99                                             
100                                             if (!skipCurrent) {
101                                                 final String id = incomingID;
102                                                 try {
103                                                     skipCurrent=gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
104                                                         @Override
105                                                         public Boolean code(Rcli<?> client)    throws CadiException, ConnectException, APIException {
106                                                             Future<Users> fc = client.read("/authn/creds/id/"+id,gui.getDF(Users.class));
107                                                             if (fc.get(AAFcli.timeout())) {
108                                                                 GregorianCalendar now = new GregorianCalendar();
109                                                                 for (aaf.v2_0.Users.User u : fc.value.getUser()) {
110                                                                     if (u.getType()<10 && u.getType()>=1 && u.getExpires().toGregorianCalendar().after(now)) {
111                                                                         return false; // an existing, non expired, password type exists
112                                                                     }
113                                                                 }
114                                                                 return true; // no existing, no expired password
115                                                             } else {
116                                                                 if (fc.code()==404) { // not found... 
117                                                                     return true;
118                                                                 } else {
119                                                                     trans.error().log(gui.aafCon.readableErrMsg(fc));
120                                                                 }
121                                                             }
122                                                             return false;
123                                                         }
124                                                     });
125                                                 } catch (LocatorException | CadiException e) {
126                                                     trans.error().log(e);
127                                                 }
128                                             }
129                                         }
130                                     }                                    
131                                 } catch (OrganizationException e) {
132                                     hgen.incr(HTMLGen.H4,"style=color:red;").text("Error: ")
133                                         .text(e.getMessage()).end();
134                                 }
135                             }
136                             
137                             hgen.input(fields[0],"ID*",true,"value="+incomingID,(incomingID.length()==0?"":"readonly"));
138                             if (!skipCurrent) {
139                                 hgen.input(fields[1],"Current Password*",true,"type=password");
140                             }
141                             if (skipCurrent) {
142                                 hgen.input(fields[1],"",false,"type=hidden", "value=").end();
143                             }
144
145                             hgen.input(fields[2],"New Password*",true, "type=password")
146                                 .input(fields[3], "Reenter New Password*",true, "type=password")
147             //                        .input(fields[3],"Start Date",false,"type=date", "value="+
148             //                                Chrono.dateOnlyFmt.format(new Date(System.currentTimeMillis()))
149             //                                )
150                                 .end(table);
151
152                         }
153
154                     });
155                     hgen.tagOnly("input", "type=submit", "value=Submit")
156                         .end(form)
157                         .br()
158                         .p("All AAF Passwords continue to be valid until their listed expiration dates.  ",
159                            "This allows you to migrate services to this new password until the old ones expire.").br().br()
160                         .p("Note: You must be an Admin of the Namespace where the MechID is defined.").br()
161                         ;
162                     
163                     Mark div = hgen.divID("passwordRules");
164                     cache.dynamic(hgen, new DynamicCode<HTMLGen, AAF_GUI, AuthzTrans>() {
165                         @Override
166                         public void code(final AAF_GUI gui, final AuthzTrans trans,    final Cache<HTMLGen> cache, final HTMLGen hgen)    throws APIException, IOException {
167                             try {
168                                 Organization org = OrganizationFactory.obtain(trans.env(),trans.getUserPrincipal().getName());
169                                 if (org!=null) {
170                                     hgen.incr(HTMLGen.H4).text("Password Rules for ").text(org.getName()).end()
171                                         .incr(HTMLGen.UL);
172                                     for (String line : org.getPasswordRules()) {
173                                         hgen.leaf(HTMLGen.LI).text(line).end();
174                                     }
175                                     hgen.end();
176                                 }
177                             } catch (OrganizationException e) {
178                                 hgen.p("No Password Rules can be found for company of ID ",trans.getUserPrincipal().getName()).br();
179                             }
180                         }
181                     });
182                     hgen.end(div);
183                 }
184             }
185         );
186     }
187
188     // Package on Purpose
189     static boolean skipCurrent(AuthzTrans trans, Identity user) throws OrganizationException {
190         if (user!=null) {
191             // Should this be an abstractable Policy?
192             String tuser = trans.user();
193             if (user.fullID().equals(trans.user())) {
194                 return true;
195             } else {
196                 Identity manager = user.responsibleTo();
197                 if (tuser.equals(user.fullID()) || manager.isFound()) {
198                     return true;
199                 }
200             }
201         }
202         return false;
203     }
204
205 }