/* See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Esri Inc. licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.esri.gpt.framework.security.principal;
import com.esri.gpt.catalog.arcims.ImsPermissionDao;
import com.esri.gpt.catalog.arcims.ImsServiceException;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.security.credentials.CredentialsDeniedException;
import com.esri.gpt.framework.security.credentials.DistinguishedNameCredential;
import com.esri.gpt.framework.security.credentials.UsernamePasswordCredentials;
import com.esri.gpt.framework.security.identity.IdentityAdapter;
import com.esri.gpt.framework.security.identity.IdentityConfiguration;
import com.esri.gpt.framework.security.identity.IdentityException;
import com.esri.gpt.framework.security.identity.NotAuthorizedException;
import com.esri.gpt.framework.util.UuidUtil;
import java.sql.SQLException;
import java.util.logging.Level;
/**
* Represents a user with a metadata publishing role.
*/
public class Publisher extends User {
// class variables =============================================================
// instance variables ==========================================================
private String _folderUuid = "";
// constructors ================================================================
/** Default constructor. */
protected Publisher() {
super();
}
/**
* Constructs a publisher based upon the user associated with the
* current request context.
* @param context the current request context (contains the active user)
* @throws NotAuthorizedException if the user does not have publishing rights
* @throws IdentityException if an integrity violation occurs
* @throws ImsServiceException if an exception occurs when
* creating the default folder
* @throws SQLException if a database exception occurs
*/
public Publisher(RequestContext context)
throws NotAuthorizedException,
IdentityException,
ImsServiceException,
SQLException {
// initialize
User user = context.getUser();
setKey(user.getKey());
setLocalID(user.getLocalID());
setDistinguishedName(user.getDistinguishedName());
setName(user.getName());
// establish credentials
UsernamePasswordCredentials creds = new UsernamePasswordCredentials();
creds.setUsername(getName());
setCredentials(creds);
this.setAuthenticationStatus(user.getAuthenticationStatus());
// assert a publishing role, ensure proper ArcIMS permissions
assertPublisherRole();
ImsPermissionDao dao = new ImsPermissionDao(context);
dao.preparePublisher(this,true);
}
/**
* Constructs a publisher based upon the user associated with the
* current request context and a distinguished name on behalf of which a
* document will be published.
* @param context the current request context (contains the active user)
* @param userDN the DN associated with on behalf of which a document will be published.
* @throws CredentialsDeniedException if the supplied DN is invalid
* @throws NotAuthorizedException if the user does not have publishing rights
* @throws IdentityException if an integrity violation occurs
* @throws ImsServiceException if an exception occurs when
* creating the default folder
* @throws SQLException if a database exception occurs
*/
public Publisher(RequestContext context, String userDN)
throws CredentialsDeniedException,
NotAuthorizedException,
IdentityException,
ImsServiceException,
SQLException {
// check to see if this request is on behalf of a
// metadata management group
Group mgmtGroup = checkManagementGroup(context,userDN);
if (mgmtGroup != null) {
setKey(mgmtGroup.getKey());
setDistinguishedName(mgmtGroup.getDistinguishedName());
setName(mgmtGroup.getName());
IdentityConfiguration idConfig = context.getIdentityConfiguration();
Role pubRole = idConfig.getConfiguredRoles().get("gptPublisher");
if (pubRole != null) {
RoleSet roles = getAuthenticationStatus().getAuthenticatedRoles();
roles.addAll(pubRole.getFullRoleSet());
}
} else {
// authenticate the publisher based upon the supplied distinguished name
DistinguishedNameCredential dnCred = new DistinguishedNameCredential(userDN);
setCredentials(dnCred);
context.newIdentityAdapter().authenticate(this);
}
// establish credentials
UsernamePasswordCredentials creds = new UsernamePasswordCredentials();
creds.setUsername(getName());
setCredentials(creds);
// assert a publishing role, ensure proper ArcIMS permissions
assertPublisherRole();
ImsPermissionDao dao = new ImsPermissionDao(context);
dao.preparePublisher(this,true);
}
// properties ==================================================================
/**
* Asserts the administrator role.
* @throws NotAuthorizedException if the administrator role has not been granted
*/
private void assertAdministratorRole() throws NotAuthorizedException {
RoleSet roles = getAuthenticationStatus().getAuthenticatedRoles();
roles.assertRole("gptAdministrator");
}
/**
* Asserts the publisher role.
* @throws NotAuthorizedException if the publisher role has not been granted
*/
private void assertPublisherRole() throws NotAuthorizedException {
RoleSet roles = getAuthenticationStatus().getAuthenticatedRoles();
roles.assertRole("gptPublisher");
}
/**
* Gets the default folder name for this publisher.
* @return the default folder name
*/
public String getDefaultFolderName() {
return getName();
}
/**
* Gets the folder uuid for this publisher.
* @return the folder uuid
*/
public String getFolderUuid() {
return _folderUuid;
}
/**
* Sets the folder uuid for this publisher.
* @param folderUuid the folder uuid
*/
public void setFolderUuid(String folderUuid) {
_folderUuid = UuidUtil.addCurlies(folderUuid);
}
/**
* Gets the status indicating whether this publisher is an administrator.
* @return true if this publisher is an administrator
*/
public boolean getIsAdministrator() {
RoleSet roles = getAuthenticationStatus().getAuthenticatedRoles();
return roles.hasRole("gptAdministrator");
}
/**
* Gets the status indicating whether this publisher exists within a remote identity store.
* @return true if this publisher is a remote reference
*/
public boolean getIsRemote() {
return true;
}
// methods =====================================================================
/**
* Builds a collection of groups that can be selected by the current user to set
* access policy
*
* @param context
* the current request context (contains the active user)
* @return the collection of groups that can be selected
*/
public static Groups buildSelectableGroups(RequestContext context) {
IdentityAdapter idAdapter = context.newIdentityAdapter();
IdentityConfiguration idConfig = context.getIdentityConfiguration();
Groups selectableGroups = null;
User user = context.getUser();
RoleSet roles = user.getAuthenticationStatus().getAuthenticatedRoles();
boolean bIsAdministrator = roles.hasRole("gptAdministrator");
try {
if (bIsAdministrator) {
User selectableUser = new User();
selectableUser.setDistinguishedName("*");
idAdapter.readUserGroups(selectableUser);
selectableGroups = selectableUser.getGroups();
} else {
selectableGroups = user.getGroups();
}
Groups mgmtGroups = idConfig.getMetadataManagementGroups();
if ((mgmtGroups != null) && (mgmtGroups.size() > 0)) {
for (Group mgmtGroup : mgmtGroups.values()) {
boolean bAdd = bIsAdministrator;
if ((selectableGroups != null)
&& selectableGroups.containsKey(mgmtGroup.getKey())) {
bAdd = true;
}
if (bAdd) {
selectableGroups.add(mgmtGroup);
}
}
}
} catch (Throwable t) {
context.getLogger().log(Level.SEVERE, "Exception raised.", t);
}
selectableGroups.sort();
return selectableGroups;
}
/**
* Builds a collection of publishers (users) that can be selected by the current user.
* @param context the current request context (contains the active user)
* @param forManagement true if the list to build is in support of the metadata management page
* @return the collection of publishers that can be selected
*/
public static Users buildSelectablePublishers(RequestContext context,
boolean forManagement) {
IdentityAdapter idAdapter = context.newIdentityAdapter();
IdentityConfiguration idConfig = context.getIdentityConfiguration();
// add the current user to the list
Users users = new Users();
User user = context.getUser();
users.add(user);
RoleSet roles = user.getAuthenticationStatus().getAuthenticatedRoles();
boolean bIsAdministrator = roles.hasRole("gptAdministrator");
try {
if (bIsAdministrator && forManagement) {
// add the administrators
Role adminRole = idConfig.getConfiguredRoles().get("gptAdministrator");
if (adminRole != null) {
Users admins = idAdapter.readGroupMembers(adminRole.getDistinguishedName());
for (User u: admins.values()) users.add(u);
}
// add the publishers
Role pubRole = idConfig.getConfiguredRoles().get("gptPublisher");
if (pubRole != null) {
Users publishers = idAdapter.readGroupMembers(pubRole.getDistinguishedName());
for (User u: publishers.values()) users.add(u);
}
users.sort();
}
// add the metadata management groups
Groups userGroups = user.getGroups();
Groups mgmtGroups = idConfig.getMetadataManagementGroups();
Users mgmtUsers = new Users();
if ((mgmtGroups != null) && (mgmtGroups.size() > 0)){
for (Group mgmtGroup : mgmtGroups.values()) {
boolean bAdd = bIsAdministrator;
if ((userGroups != null) && userGroups.containsKey(mgmtGroup.getKey())) {
bAdd = true;
}
if (bAdd) {
User u = new User();
u.setKey(mgmtGroup.getKey());
u.setDistinguishedName(mgmtGroup.getDistinguishedName());
u.setName(mgmtGroup.getName());
mgmtUsers.add(u);
}
}
mgmtUsers.sort();
for (User u: mgmtUsers.values()) users.add(u);
}
} catch (Throwable t) {
context.getLogger().log(Level.SEVERE,"Exception raised.",t);
}
return users;
}
/**
* Checks to see if a supplied DN corresponds to a metadata management group.
*
* @param context
* the current request context (contains the active user)
* @param userDN
* the distinguished name to check
* @return the corresponding metadata management group or null
*/
private Group checkManagementGroup(RequestContext context, String userDN) {
IdentityConfiguration idConfig = context.getIdentityConfiguration();
Groups mgmtGroups = idConfig.getMetadataManagementGroups();
if (mgmtGroups != null) {
return mgmtGroups.get(userDN);
}
return null;
}
/**
* Creates a catalog administrator based upon the distinguished name credential supplied within the
* GPT configuration file (@catalogAdminDN).
* <p/>
* The administrative publisher is used during background processes such as synchronization.
* @param context the current request context
* @return a publisher with catalog metadata administration rights
* @throws CredentialsDeniedException if the configured administrative credentials were invalid
* @throws NotAuthorizedException if the associated user does not have administrative rights
* @throws IdentityException if an integrity violation occurs
* @throws ImsServiceException if an exception occurs when creating the default folder
* @throws SQLException if a database exception occurs
*/
public static Publisher makeSystemAdministrator(RequestContext context)
throws CredentialsDeniedException, IdentityException, SQLException,
NotAuthorizedException, ImsServiceException {
// create the publisher
String sAdminDN = context.getIdentityConfiguration().getCatalogAdminDN();
Publisher admin = new Publisher();
DistinguishedNameCredential dnCred = new DistinguishedNameCredential(sAdminDN);
admin.setCredentials(dnCred);
context.newIdentityAdapter().authenticate(admin);
// establish credentials
UsernamePasswordCredentials creds = new UsernamePasswordCredentials();
creds.setUsername(admin.getName());
admin.setCredentials(creds);
// assert a publishing role, ensure proper ArcIMS permissions
admin.assertAdministratorRole();
ImsPermissionDao dao = new ImsPermissionDao(context);
dao.preparePublisher(admin,true);
return admin;
}
}