Package com.ibm.sbt.opensocial.domino.security

Source Code of com.ibm.sbt.opensocial.domino.security.DominoSecurityTokenCodec

package com.ibm.sbt.opensocial.domino.security;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;
import org.apache.shindig.auth.AnonymousSecurityToken;
import org.apache.shindig.auth.BasicSecurityTokenCodec;
import org.apache.shindig.auth.BlobCrypterSecurityTokenCodec;
import org.apache.shindig.auth.SecurityToken;
import org.apache.shindig.auth.SecurityTokenCodec;
import org.apache.shindig.auth.SecurityTokenException;
import org.apache.shindig.config.ContainerConfig;

import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
* Security token codec responsible for encrypting/decrypting security tokens.
*
*/
@Singleton
public class DominoSecurityTokenCodec implements SecurityTokenCodec {
  private static final String CLASS = DominoSecurityTokenCodec.class.getName();
  private static final String SECURITY_TOKEN_TYPE = "gadgets.securityTokenType";
  private SecurityTokenCodec secureCodec;
  private SecurityTokenCodec insecureCodec;
  private Map<String, String> tokenTypes;
  private ContainerConfig config;
  private final Logger log;
  private ContainerConfig.ConfigObserver observer = new ContainerConfig.ConfigObserver() {
    @Override
    public void containersChanged(ContainerConfig config,
        Collection<String> changed, Collection<String> removed) {
      populateTokenTypes(config, changed, removed, DominoSecurityTokenCodec.this.tokenTypes);
    }
  };

  @Inject
  public DominoSecurityTokenCodec(ContainerConfig config, Logger log) {
    this.config = config;
    this.tokenTypes = Maps.newHashMap();
    this.log = log;
    config.addConfigObserver(observer, false);
    populateTokenTypes(config, config.getContainers(), Collections.EMPTY_LIST, this.tokenTypes);
  }

  private void populateTokenTypes(ContainerConfig config, Collection<String> added, Collection<String> removed,
      Map<String, String> tokenTypes) {
    synchronized(tokenTypes) {
      for (String container : added) {
        tokenTypes.put(container, config.getString(container, SECURITY_TOKEN_TYPE));
      }
      for(String container : removed) {
        tokenTypes.remove(container);
      }
    }
  }

  public SecurityToken createToken(Map<String, String> tokenParameters)
      throws SecurityTokenException {
    final String method = "createToken";
    // FIXME: This is so gross that I have to do this. Shindig needs to be fixed so I can
    // consistently get the container from tokenParameters.
    String token = tokenParameters.get(SecurityTokenCodec.SECURITY_TOKEN_NAME);
    if (token == null || token.length() == 0) {
      return new AnonymousSecurityToken();
    }

    String[] tokenParts = token.split(":");
    String container;
    if (tokenParts.length == 2) {
      // BlobCrypter. Part 0 is the container. Part 1 is the encrypted blob.
      container = tokenParts[0];
    } else {
      // BasicCrypter. 6 is the magic number that is private static final in
      // BasicBlobCrypterSecurityToken
      container = tokenParts[6];
    }
   
    SecurityTokenCodec codec = getCodec(container);
    if(codec == null) {
      //Shindig is really bad about making sure containers are encoded before they
      //are placed on URLs.  It basically makes the assumption that container ids do
      //not need to be encoded and just sticks them on the URLs.  This is the case when
      //it makes the request to the /rpc endpoint so just to be sure lets encode the container
      //and try to look up the token type
      try {
        String encodedContainer = URLEncoder.encode(container, "UTF-8");
        codec = getCodec(encodedContainer);
        if(codec!= null) {
          //Since the container was not properly encoded make sure it is correct in the token parameters
          putContainerInTokenParams(tokenParameters, encodedContainer);
        } else {
          throw new RuntimeException("Could not find security token codec for container " + container);
        }
      } catch (UnsupportedEncodingException e) {
        log.logp(Level.WARNING, CLASS, method, "Error while encoding container.");
      }
    }
     
    return codec.createToken(tokenParameters);
  }
 
  public void putContainerInTokenParams(Map<String, String> tokenParams, String container) {
    String token = StringUtils.defaultString(tokenParams.get(SecurityTokenCodec.SECURITY_TOKEN_NAME));
    String[] parts = token.split(":");
    if(parts.length == 2) {
      String newToken = container + ":" + parts[1];
      tokenParams.put(SecurityTokenCodec.SECURITY_TOKEN_NAME, newToken);
    }
  }

  public String encodeToken(SecurityToken token) throws SecurityTokenException {
    if (token == null) {
      return null;
    }
    return getCodec(token.getContainer()).encodeToken(token);
  }

  @Deprecated
  public int getTokenTimeToLive() {
    return getCodec("default").getTokenTimeToLive("defualt");
  }

  public int getTokenTimeToLive(String container) {
    return getCodec(container).getTokenTimeToLive(container);
  }

  private SecurityTokenCodec getCodec(String container) {
    synchronized(tokenTypes) {
      String tokenType = this.tokenTypes.get(container);
      return getCodecByType(tokenType);
    }
  }

  SecurityTokenCodec getCodecByType(String tokenType) {
    if ("insecure".equals(tokenType)) {
      if (this.insecureCodec == null) {
        this.insecureCodec = new BasicSecurityTokenCodec(this.config);
      }
      return this.insecureCodec;
    }

    if ("secure".equals(tokenType)) {
      if (this.secureCodec == null) {
        this.secureCodec = new BlobCrypterSecurityTokenCodec(this.config);
      }
      return this.secureCodec;
    }
    return null;
  }
}
TOP

Related Classes of com.ibm.sbt.opensocial.domino.security.DominoSecurityTokenCodec

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.