001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.oauth2.sdk.id; 019 020 021import java.io.Serializable; 022import java.security.SecureRandom; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.List; 027 028import net.minidev.json.JSONAware; 029import net.minidev.json.JSONValue; 030 031import com.nimbusds.jose.util.Base64URL; 032import com.nimbusds.oauth2.sdk.util.StringUtils; 033 034 035/** 036 * The base class for representing identifiers and identities. Provides 037 * constructors that generate Base64URL-encoded secure random identifier 038 * values. 039 * 040 * <p>Extending classes must override the {@link #equals} method. 041 */ 042public class Identifier implements Serializable, Comparable<Identifier>, JSONAware { 043 044 045 /** 046 * The default byte length of generated identifiers. 047 */ 048 public static final int DEFAULT_BYTE_LENGTH = 32; 049 050 051 /** 052 * Returns a string list representation of the specified identifier 053 * collection. 054 * 055 * @param ids The identifiers, {@code null} if not specified. 056 * 057 * @return The string list, empty list if not specified. 058 */ 059 public static List<String> toStringList(final Collection<? extends Identifier> ids) { 060 if (ids == null) { 061 return Collections.emptyList(); 062 } 063 List<String> stringList = new ArrayList<>(ids.size()); 064 for (Identifier id: ids) { 065 stringList.add(id.getValue()); 066 } 067 return stringList; 068 } 069 070 071 /** 072 * The secure random generator. 073 */ 074 protected static final SecureRandom secureRandom = new SecureRandom(); 075 076 077 /** 078 * The identifier value. 079 */ 080 private final String value; 081 082 083 /** 084 * Creates a new identifier with the specified value. 085 * 086 * @param value The identifier value. Must not be {@code null} or empty 087 * string. 088 */ 089 public Identifier(final String value) { 090 091 if (StringUtils.isBlank(value)) 092 throw new IllegalArgumentException("The value must not be null or empty string"); 093 094 this.value = value; 095 } 096 097 098 /** 099 * Creates a new identifier with a randomly generated value of the 100 * specified byte length, Base64URL-encoded. 101 * 102 * @param byteLength The byte length of the value to generate. Must be 103 * greater than one. 104 */ 105 public Identifier(final int byteLength) { 106 107 if (byteLength < 1) 108 throw new IllegalArgumentException("The byte length must be a positive integer"); 109 110 byte[] n = new byte[byteLength]; 111 112 secureRandom.nextBytes(n); 113 114 value = Base64URL.encode(n).toString(); 115 } 116 117 118 /** 119 * Creates a new identifier with a randomly generated 256-bit 120 * (32-byte) value, Base64URL-encoded. 121 */ 122 public Identifier() { 123 124 this(DEFAULT_BYTE_LENGTH); 125 } 126 127 128 /** 129 * Returns the value of this identifier. 130 * 131 * @return The value. 132 */ 133 public String getValue() { 134 135 return value; 136 } 137 138 139 /** 140 * Returns the JSON string representation of this identifier. 141 * 142 * @return The JSON string. 143 */ 144 @Override 145 public String toJSONString() { 146 147 return "\"" + JSONValue.escape(value) + '"'; 148 } 149 150 151 /** 152 * @see #getValue 153 */ 154 @Override 155 public String toString() { 156 157 return getValue(); 158 } 159 160 161 @Override 162 public int compareTo(final Identifier other) { 163 164 return getValue().compareTo(other.getValue()); 165 } 166 167 168 @Override 169 public boolean equals(final Object o) { 170 if (this == o) return true; 171 if (o == null || getClass() != o.getClass()) return false; 172 173 Identifier that = (Identifier) o; 174 175 return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; 176 177 } 178 179 180 @Override 181 public int hashCode() { 182 return getValue() != null ? getValue().hashCode() : 0; 183 } 184}