96af26edac3db179e8d9ad22df39ef18255723cd
[aaf/cadi.git] / shiro / src / main / java / org / onap / aaf / cadi / shiro / AAFRealm.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 package org.onap.aaf.cadi.shiro;
22
23 import java.io.IOException;
24 import java.security.Principal;
25 import java.util.ArrayList;
26 import java.util.HashSet;
27 import java.util.List;
28
29 import org.apache.shiro.authc.AuthenticationException;
30 import org.apache.shiro.authc.AuthenticationInfo;
31 import org.apache.shiro.authc.AuthenticationToken;
32 import org.apache.shiro.authc.UsernamePasswordToken;
33 import org.apache.shiro.realm.AuthorizingRealm;
34 import org.apache.shiro.subject.PrincipalCollection;
35 import org.onap.aaf.cadi.Access.Level;
36 import org.onap.aaf.cadi.CadiException;
37 import org.onap.aaf.cadi.LocatorException;
38 import org.onap.aaf.cadi.Permission;
39 import org.onap.aaf.cadi.PropAccess;
40 import org.onap.aaf.cadi.Symm;
41 import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;
42 import org.onap.aaf.cadi.aaf.v2_0.AAFCon;
43 import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;
44 import org.onap.aaf.cadi.config.Config;
45 import org.onap.aaf.cadi.filter.MapBathConverter;
46 import org.onap.aaf.cadi.util.CSV;
47 import org.onap.aaf.misc.env.APIException;
48
49 public class AAFRealm extends AuthorizingRealm {
50         public static final String AAF_REALM = "AAFRealm";
51         
52         private PropAccess access;
53         private AAFCon<?> acon;
54         private AAFAuthn<?> authn;
55         private HashSet<Class<? extends AuthenticationToken>> supports;
56         private AAFLurPerm authz;
57         private MapBathConverter mbc;
58         
59
60         /**
61          * 
62          * There appears to be no configuration objects or references available for CADI to start with.
63          *  
64          */
65         public AAFRealm () {
66                 access = new PropAccess(); // pick up cadi_prop_files from VM_Args
67                 mbc = null;
68                 String cadi_prop_files = access.getProperty(Config.CADI_PROP_FILES);
69                 if(cadi_prop_files==null) {
70                         String msg = Config.CADI_PROP_FILES + " in VM Args is required to initialize AAFRealm.";
71                         access.log(Level.INIT,msg);
72                         throw new RuntimeException(msg);
73                 } else {
74                         try {
75                                 acon = AAFCon.newInstance(access);
76                                 authn = acon.newAuthn();
77                                 authz = acon.newLur(authn);
78                                 
79                                 final String csv = access.getProperty(Config.CADI_BATH_CONVERT);
80                                 if(csv!=null) {
81                                         try {
82                                                 mbc = new MapBathConverter(access, new CSV(csv));
83                                         } catch (IOException e) {
84                                                 access.log(e);
85                                         }
86                                 }
87                         } catch (APIException | CadiException | LocatorException e) {
88                                 String msg = "Cannot initiate AAFRealm";
89                                 access.log(Level.INIT,msg,e.getMessage());
90                                 throw new RuntimeException(msg,e);
91                         }
92                 }
93                 supports = new HashSet<Class<? extends AuthenticationToken>>();
94                 supports.add(UsernamePasswordToken.class);
95         }
96
97         @Override
98         protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
99                 access.log(Level.DEBUG, "AAFRealm.doGetAuthenticationInfo",token);
100                 
101                 final UsernamePasswordToken upt = (UsernamePasswordToken)token;
102                 String user = upt.getUsername();
103                 String password=new String(upt.getPassword());
104                 if(mbc!=null) {
105                         try {
106                                 final String oldBath = "Basic " + Symm.base64noSplit.encode(user+':'+password);
107                                 String bath = mbc.convert(access, oldBath);
108                                 if(bath!=oldBath) {
109                                         bath = Symm.base64noSplit.decode(bath.substring(6));
110                                         int colon = bath.indexOf(':');
111                                         if(colon>=0) {
112                                                 user = bath.substring(0, colon);
113                                                 password = bath.substring(colon+1);
114                                         }
115                                 }
116                         } catch (IOException e) {
117                                 access.log(e);
118                         } 
119                 }
120                 String err;
121                 try {
122                         err = authn.validate(user,password);
123                 } catch (IOException e) {
124                         err = "Credential cannot be validated";
125                         access.log(e, err);
126                 }
127                 
128                 if(err != null) {
129                         access.log(Level.DEBUG, err);
130                         throw new AuthenticationException(err);
131                 }
132
133             return new AAFAuthenticationInfo(
134                         access,
135                         user,
136                         password
137             );
138         }
139
140         @Override
141         protected void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)throws AuthenticationException {
142                 if(ai instanceof AAFAuthenticationInfo) {
143                         if(!((AAFAuthenticationInfo)ai).matches(atoken)) {
144                                 throw new AuthenticationException("Credentials do not match");
145                         }
146                 } else {
147                         throw new AuthenticationException("AuthenticationInfo is not an AAFAuthenticationInfo");
148                 }
149         }
150
151
152         @Override
153         protected AAFAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
154                 access.log(Level.DEBUG, "AAFRealm.doGetAuthenthorizationInfo");
155                 Principal bait = (Principal)principals.getPrimaryPrincipal();
156                 List<Permission> pond = new ArrayList<>();
157                 authz.fishAll(bait,pond);
158                 
159                 return new AAFAuthorizationInfo(access,bait,pond);
160        
161         }
162
163         @Override
164         public boolean supports(AuthenticationToken token) {
165                 return supports.contains(token.getClass());
166         }
167
168         @Override
169         public String getName() {
170                 return AAF_REALM;
171         }
172
173 }