001/** 002 * Copyright 2015 DuraSpace, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fcrepo.auth.common; 017 018import static org.fcrepo.auth.common.ServletContainerAuthenticationProvider.EVERYONE; 019 020import org.modeshape.jcr.security.AdvancedAuthorizationProvider; 021import org.modeshape.jcr.security.SecurityContext; 022import org.modeshape.jcr.value.Path; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026import java.security.Principal; 027 028/** 029 * The security context for Fedora servlet users. These users are not 030 * necessarily authenticated by the container, i.e. users may include the 031 * general public. This security context delegates all access decisions to the 032 * configured authorization delegate. 033 * 034 * @author Gregory Jansen 035 */ 036public class FedoraUserSecurityContext implements SecurityContext, 037 AdvancedAuthorizationProvider { 038 039 private static final Logger LOGGER = LoggerFactory 040 .getLogger(FedoraUserSecurityContext.class); 041 042 private Principal userPrincipal = null; 043 044 private FedoraAuthorizationDelegate fad = null; 045 046 private boolean loggedIn = true; 047 048 /** 049 * Constructs a new security context. 050 * 051 * @param userPrincipal the user principal associated with this security 052 * context 053 * @param fad the authorization delegate 054 */ 055 protected FedoraUserSecurityContext(final Principal userPrincipal, 056 final FedoraAuthorizationDelegate fad) { 057 this.fad = fad; 058 this.userPrincipal = userPrincipal; 059 060 if (this.fad == null) { 061 LOGGER.warn("This security context must have a FAD injected"); 062 throw new IllegalArgumentException( 063 "This security context must have a FAD injected"); 064 } 065 } 066 067 /** 068 * {@inheritDoc} 069 * 070 * @see org.modeshape.jcr.security.SecurityContext#isAnonymous() 071 */ 072 @Override 073 public boolean isAnonymous() { 074 return this.userPrincipal == null; 075 } 076 077 /** 078 * {@inheritDoc} 079 * 080 * @see SecurityContext#getUserName() 081 */ 082 @Override 083 public final String getUserName() { 084 return getEffectiveUserPrincipal().getName(); 085 } 086 087 /** 088 * {@inheritDoc} 089 * 090 * @see SecurityContext#hasRole(String) 091 */ 092 @Override 093 public final boolean hasRole(final String roleName) { 094 // Under this custom PEP regime, all users have modeshape read and write 095 // roles. 096 if ("read".equals(roleName)) { 097 return true; 098 } else if ("write".equals(roleName)) { 099 return true; 100 } else if ("admin".equals(roleName)) { 101 return true; 102 } 103 return false; 104 } 105 106 /** 107 * Get the user principal associated with this context. 108 * 109 * @return the user principal associated with this security context 110 */ 111 public Principal getEffectiveUserPrincipal() { 112 if (this.loggedIn && this.userPrincipal != null) { 113 return this.userPrincipal; 114 } 115 return EVERYONE; 116 } 117 118 /** 119 * {@inheritDoc} 120 * 121 * @see org.modeshape.jcr.security.SecurityContext#logout() 122 */ 123 @Override 124 public void logout() { 125 this.loggedIn = false; 126 } 127 128 /* 129 * (non-Javadoc) 130 * @see 131 * org.modeshape.jcr.security.AdvancedAuthorizationProvider#hasPermission 132 * (org.modeshape.jcr.security.AdvancedAuthorizationProvider.Context, 133 * org.modeshape.jcr.value.Path, java.lang.String[]) 134 */ 135 @Override 136 public boolean hasPermission(final Context context, final Path absPath, 137 final String... actions) { 138 if (!this.loggedIn) { 139 return false; 140 } 141 142 // this permission is required for login 143 if (absPath == null) { 144 return actions.length == 1 && "read".equals(actions[0]); 145 } 146 147 // delegate 148 if (fad != null) { 149 return fad.hasPermission(context.getSession(), absPath, actions); 150 } 151 return false; 152 } 153}