Sonar Fixes, Formatting
[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 }