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