3577c13025e5ad1c328d4d52de242f739c328190
[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                                                 access.printf(Level.INIT, "MapBathConversion enabled with file %s\n",csv);
84                                         } catch (IOException e) {
85                                                 access.log(e);
86                                         }
87                                 }
88                         } catch (APIException | CadiException | LocatorException e) {
89                                 String msg = "Cannot initiate AAFRealm";
90                                 access.log(Level.INIT,msg,e.getMessage());
91                                 throw new RuntimeException(msg,e);
92                         }
93                 }
94                 supports = new HashSet<Class<? extends AuthenticationToken>>();
95                 supports.add(UsernamePasswordToken.class);
96         }
97
98         @Override
99         protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
100                 access.log(Level.DEBUG, "AAFRealm.doGetAuthenticationInfo",token);
101                 
102                 final UsernamePasswordToken upt = (UsernamePasswordToken)token;
103                 String user = upt.getUsername();
104                 String password=new String(upt.getPassword());
105                 if(mbc!=null) {
106                         try {
107                                 final String oldBath = "Basic " + Symm.base64noSplit.encode(user+':'+password);
108                                 String bath = mbc.convert(access, oldBath);
109                                 if(bath!=oldBath) {
110                                         bath = Symm.base64noSplit.decode(bath.substring(6));
111                                         int colon = bath.indexOf(':');
112                                         if(colon>=0) {
113                                                 user = bath.substring(0, colon);
114                                                 password = bath.substring(colon+1);
115                                         }
116                                 }
117                         } catch (IOException e) {
118                                 access.log(e);
119                         } 
120                 }
121                 String err;
122                 try {
123                         err = authn.validate(user,password);
124                 } catch (IOException e) {
125                         err = "Credential cannot be validated";
126                         access.log(e, err);
127                 }
128                 
129                 if(err != null) {
130                         access.log(Level.DEBUG, err);
131                         throw new AuthenticationException(err);
132                 }
133
134             return new AAFAuthenticationInfo(
135                         access,
136                         user,
137                         password
138             );
139         }
140
141         @Override
142         protected void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)throws AuthenticationException {
143                 if(ai instanceof AAFAuthenticationInfo) {
144                         if(!((AAFAuthenticationInfo)ai).matches(atoken)) {
145                                 throw new AuthenticationException("Credentials do not match");
146                         }
147                 } else {
148                         throw new AuthenticationException("AuthenticationInfo is not an AAFAuthenticationInfo");
149                 }
150         }
151
152
153         @Override
154         protected AAFAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
155                 access.log(Level.DEBUG, "AAFRealm.doGetAuthenthorizationInfo");
156                 Principal bait = (Principal)principals.getPrimaryPrincipal();
157                 List<Permission> pond = new ArrayList<>();
158                 authz.fishAll(bait,pond);
159                 
160                 return new AAFAuthorizationInfo(access,bait,pond);
161        
162         }
163
164         @Override
165         public boolean supports(AuthenticationToken token) {
166                 return supports.contains(token.getClass());
167         }
168
169         @Override
170         public String getName() {
171                 return AAF_REALM;
172         }
173
174 }