80e6dc403ced7f936a68a153f61c21a2395b8ccc
[aaf/authz.git] / cadi / client / src / main / java / org / onap / aaf / cadi / client / AbsAuthentication.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.cadi.client;
23
24 import java.io.IOException;
25
26 import org.onap.aaf.cadi.SecuritySetter;
27 import org.onap.aaf.cadi.Symm;
28 import org.onap.aaf.cadi.config.SecurityInfoC;
29
30 /**
31  * AbsAuthentication is a class representing how to Authenticate onto a Client.
32  * 
33  * Methods of setting Authentication on a Client vary, so CLIENT is a Generic Type
34  * This allows the ability to apply security onto Different Client Types, as they come 
35  * into vogue, or change over time.
36  * 
37  * Password is encrypted at rest.
38  *  
39  * @author Jonathan
40  *
41  * @param <CLIENT>
42  */
43 public abstract class AbsAuthentication<CLIENT> implements SecuritySetter<CLIENT> {
44         // HTTP Header for Authentication is "Authorization".  This was from an early stage of internet where 
45         // Access by Credential "Authorized" you for everything on the site.  Since those early days, it became
46         // clear that "full access" wasn't appropriate, so the split between Authentication and Authorization
47         // came into being... But the Header remains.
48         public static final String AUTHORIZATION = "Authorization";
49         private static final Symm symm;
50
51         protected static final String REPEAT_OFFENDER = "This call is aborted because of repeated usage of invalid Passwords";
52         private static final int MAX_TEMP_COUNT = 10;
53         private static final int MAX_SPAM_COUNT = 10000;
54         private static final long WAIT_TIME = 1000*60*4L;
55         private final byte[] headValue;
56         private String user;
57         protected final SecurityInfoC<CLIENT> securityInfo;
58         protected long lastMiss;
59         protected int count;
60         
61         static {
62                 try {
63                         symm = Symm.encrypt.obtain();
64                 } catch (IOException e) {
65                         throw new RuntimeException("Cannot create critical internal encryption key",e);
66                 }
67                 
68         }
69
70         public AbsAuthentication(final SecurityInfoC<CLIENT> securityInfo, final String user, final byte[] headValue) throws IOException {
71                 this.headValue = headValue==null?null:symm.encode(headValue);
72                 this.user = user;
73                 this.securityInfo = securityInfo;
74                 lastMiss=0L;
75                 count=0;
76         }
77
78         protected String headValue() throws IOException {
79                 if(headValue==null) {
80                         return "";
81                 } else {
82                         return new String(symm.decode(headValue));
83                 }
84         }
85         
86         protected void setUser(String id) {
87                 user = id;
88         }
89         
90         @Override
91         public String getID() {
92                 return user;
93         }
94
95         public boolean isDenied() {
96                 if(lastMiss>0 && lastMiss>System.currentTimeMillis()) {
97                         return true;
98                 } else {
99                         lastMiss=0L;
100                         return false;
101                 }
102         }
103
104         public synchronized int setLastResponse(int httpcode) {
105                 if(httpcode == 401) {
106                         ++count;
107                         if(lastMiss==0L && count>MAX_TEMP_COUNT) {
108                                 lastMiss=System.currentTimeMillis()+WAIT_TIME;
109                         }
110                         //                              if(count>MAX_SPAM_COUNT) {
111                         //                                      System.err.printf("Your service has %d consecutive bad service logins to AAF. \nIt will now exit\n",
112                         //                                                      count);
113                         //                                      System.exit(401);
114                         //                              }
115                         if(count%1000==0) {
116                                 System.err.printf("Your service has %d consecutive bad service logins to AAF. AAF Access will be disabled after %d\n",
117                                                 count,MAX_SPAM_COUNT);
118                         }
119
120                 } else {
121                         lastMiss=0;
122                 }
123                 return count;
124         }
125
126         public int count() {
127                 return count;
128         }
129
130 }