AT&T 2.0.19 Code drop, stage 3
[aaf/authz.git] / auth / auth-service / src / main / java / org / onap / aaf / auth / service / api / API_Creds.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.service.api;
23
24 import static org.onap.aaf.auth.rserv.HttpMethods.DELETE;
25 import static org.onap.aaf.auth.rserv.HttpMethods.GET;
26 import static org.onap.aaf.auth.rserv.HttpMethods.POST;
27 import static org.onap.aaf.auth.rserv.HttpMethods.PUT;
28
29 import java.security.Principal;
30 import java.util.Date;
31
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpServletResponse;
34
35 import org.eclipse.jetty.http.HttpStatus;
36 import org.onap.aaf.auth.direct.DirectAAFUserPass;
37 import org.onap.aaf.auth.env.AuthzTrans;
38 import org.onap.aaf.auth.layer.Result;
39 import org.onap.aaf.auth.rserv.HttpMethods;
40 import org.onap.aaf.auth.service.AAF_Service;
41 import org.onap.aaf.auth.service.Code;
42 import org.onap.aaf.auth.service.facade.AuthzFacade;
43 import org.onap.aaf.auth.service.mapper.Mapper.API;
44 import org.onap.aaf.cadi.CredVal;
45 import org.onap.aaf.cadi.Symm;
46 import org.onap.aaf.cadi.principal.BasicPrincipal;
47 import org.onap.aaf.cadi.principal.X509Principal;
48 import org.onap.aaf.misc.env.Env;
49 import org.onap.aaf.misc.env.TimeTaken;
50
51 /**
52  * Initialize All Dispatches related to Credentials (AUTHN)
53  * @author Jonathan
54  *
55  */
56 public class API_Creds {
57         // Hide Public Interface
58         private API_Creds() {}
59         // needed to validate Creds even when already Authenticated x509
60         /**
61          * TIME SENSITIVE APIs
62          * 
63          * These will be first in the list
64          * 
65          * @param env
66          * @param authzAPI
67          * @param facade
68          * @param directAAFUserPass 
69          * @throws Exception
70          */
71         public static void timeSensitiveInit(Env env, AAF_Service authzAPI, AuthzFacade facade, final DirectAAFUserPass directAAFUserPass) throws Exception {
72                 /**
73                  * Basic Auth, quick Validation
74                  * 
75                  * Responds OK or NotAuthorized
76                  */
77                 authzAPI.route(env, HttpMethods.GET, "/authn/basicAuth", new Code(facade,"Is given BasicAuth valid?",true) {
78                         @Override
79                         public void handle(
80                                         AuthzTrans trans, 
81                                         HttpServletRequest req,
82                                         HttpServletResponse resp) throws Exception {
83
84                                 Principal p = trans.getUserPrincipal();
85                                 if (p instanceof BasicPrincipal) {
86                                         // the idea is that if call is made with this credential, and it's a BasicPrincipal, it's ok
87                                         // otherwise, it wouldn't have gotten here.
88                                         resp.setStatus(HttpStatus.OK_200);
89                                 } else if (p instanceof X509Principal) {
90                                         // have to check Basic Auth here, because it might be CSP.
91                                         String authz = req.getHeader("Authorization");
92                                         if(authz.startsWith("Basic ")) {
93                                                 String decoded = Symm.base64noSplit.decode(authz.substring(6));
94                                                 int colon = decoded.indexOf(':');
95                                                 TimeTaken tt = trans.start("Direct Validation", Env.REMOTE);
96                                                 try {
97                                                         if(directAAFUserPass.validate(
98                                                                         decoded.substring(0,colon), 
99                                                                         CredVal.Type.PASSWORD , 
100                                                                         decoded.substring(colon+1).getBytes(),trans)) {
101                                                                 
102                                                                 resp.setStatus(HttpStatus.OK_200);
103                                                         } else {
104                                                                 // DME2 at this version crashes without some sort of response
105                                                                 resp.getOutputStream().print("");
106                                                                 resp.setStatus(HttpStatus.FORBIDDEN_403);
107                                                         }
108                                                 } finally {
109                                                         tt.done();
110                                                 }
111                                         }
112                                 } else if(p == null) {
113                                         trans.error().log("Transaction not Authenticated... no Principal");
114                                         resp.setStatus(HttpStatus.FORBIDDEN_403);
115                                 } else {
116                                         trans.checkpoint("Basic Auth Check Failed: This wasn't a Basic Auth Trans");
117                                         // For Auth Security questions, we don't give any info to client on why failed
118                                         resp.setStatus(HttpStatus.FORBIDDEN_403);
119                                 }
120                         }
121                 },"text/plain","*/*","*");
122                 
123                 /** 
124                  *  returns whether a given Credential is valid
125                  */
126                 authzAPI.route(POST, "/authn/validate", API.CRED_REQ, new Code(facade,"Is given Credential valid?",true) {
127                         @Override
128                         public void handle(
129                                         AuthzTrans trans, 
130                                         HttpServletRequest req,
131                                         HttpServletResponse resp) throws Exception {
132                                 
133                                 Result<Date> r = context.doesCredentialMatch(trans, req, resp);
134                                 if(r.isOK()) {
135                                         resp.setStatus(HttpStatus.OK_200);
136                                 } else {
137                                         // For Security, we don't give any info out on why failed, other than forbidden
138                                         // Can't do "401", because that is on the call itself
139                                         resp.setStatus(HttpStatus.FORBIDDEN_403);
140                                 }
141                         }
142                 });  
143
144                 /** 
145                  *  returns whether a given Credential is valid
146                  */
147                 authzAPI.route(GET, "/authn/cert/id/:id", API.CERTS, new Code(facade,"Get Cert Info by ID",true) {
148                         @Override
149                         public void handle(
150                                         AuthzTrans trans, 
151                                         HttpServletRequest req,
152                                         HttpServletResponse resp) throws Exception {
153                                 
154                                 Result<Void> r = context.getCertInfoByID(trans, req, resp, pathParam(req,":id") );
155                                 if(r.isOK()) {
156                                                 resp.setStatus(HttpStatus.OK_200); 
157                                 } else {
158                                                 // For Security, we don't give any info out on why failed, other than forbidden
159                                                 resp.setStatus(HttpStatus.FORBIDDEN_403);
160                                 }
161                         }
162                 });  
163
164
165
166
167         }
168         
169         /**
170          * Normal Init level APIs
171          * 
172          * @param authzAPI
173          * @param facade
174          * @throws Exception
175          */
176         public static void init(AAF_Service authzAPI, AuthzFacade facade) throws Exception {
177                 /**
178                  * Create a new ID/Credential
179                  */
180                 authzAPI.route(POST,"/authn/cred",API.CRED_REQ,new Code(facade,"Add a New ID/Credential", true) {
181                         @Override
182                         public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {                               Result<Void> r = context.createUserCred(trans, req);
183                                 if(r.isOK()) {
184                                         resp.setStatus(HttpStatus.CREATED_201);
185                                 } else {
186                                         context.error(trans,resp,r);
187                                 }
188                         }
189                 });
190                 
191                 /** 
192                  *  gets all credentials by Namespace
193                  */
194                 authzAPI.route(GET, "/authn/creds/ns/:ns", API.USERS, new Code(facade,"Get Creds for a Namespace",true) {
195                         @Override
196                         public void handle(
197                                         AuthzTrans trans, 
198                                         HttpServletRequest req,
199                                         HttpServletResponse resp) throws Exception {
200                                 
201                                 Result<Void> r = context.getCredsByNS(trans, resp, pathParam(req, "ns"));
202                                 if(r.isOK()) {
203                                         resp.setStatus(HttpStatus.OK_200); 
204                                 } else {
205                                         context.error(trans,resp,r);
206                                 }
207                         }
208
209                 });
210                 
211                 /** 
212                  *  gets all credentials by ID
213                  */
214                 authzAPI.route(GET, "/authn/creds/id/:id", API.USERS, new Code(facade,"Get Creds by ID",true) {
215                         @Override
216                         public void handle(
217                                         AuthzTrans trans, 
218                                         HttpServletRequest req,
219                                         HttpServletResponse resp) throws Exception {
220                                 
221                                 Result<Void> r = context.getCredsByID(trans, resp, pathParam(req, "id"));
222                                 if(r.isOK()) {
223                                         resp.setStatus(HttpStatus.OK_200); 
224                                 } else {
225                                         context.error(trans,resp,r);
226                                 }
227                         }
228
229                 });
230
231
232                 /**
233                  * Update ID/Credential (aka reset)
234                  */
235                 authzAPI.route(PUT,"/authn/cred",API.CRED_REQ,new Code(facade,"Update an ID/Credential", true) {
236                         @Override
237                         public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
238                                 
239                                 Result<Void> r = context.changeUserCred(trans, req);
240                                 if(r.isOK()) {
241                                         resp.setStatus(HttpStatus.OK_200);
242                                 } else {
243                                         context.error(trans,resp,r);
244                                 }
245                         }
246                 });
247
248                 /**
249                  * Extend ID/Credential
250                  * This behavior will accelerate getting out of P1 outages due to ignoring renewal requests, or
251                  * other expiration issues.
252                  * 
253                  * Scenario is that people who are solving Password problems at night, are not necessarily those who
254                  * know what the passwords are supposed to be.  Also, changing Password, without changing Configurations
255                  * using that password only exacerbates the P1 Issue.
256                  */
257                 authzAPI.route(PUT,"/authn/cred/:days",API.CRED_REQ,new Code(facade,"Extend an ID/Credential", true) {
258                         @Override
259                         public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
260                                 Result<Void> r = context.extendUserCred(trans, req, pathParam(req, "days"));
261                                 if(r.isOK()) {
262                                         resp.setStatus(HttpStatus.OK_200);
263                                 } else {
264                                         context.error(trans,resp,r);
265                                 }
266                         }
267                 });
268
269                 /**
270                  * Delete a ID/Credential by Object
271                  */
272                 authzAPI.route(DELETE,"/authn/cred",API.CRED_REQ,new Code(facade,"Delete a Credential", true) {
273                         @Override
274                         public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
275                                 Result<Void> r = context.deleteUserCred(trans, req);
276                                 if(r.isOK()) {
277                                         resp.setStatus(HttpStatus.OK_200);
278                                 } else {
279                                         context.error(trans,resp,r);
280                                 }
281                         }
282                 });
283
284         }
285 }