/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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 org.surfnet.oaaas.model; import org.apache.commons.lang.StringUtils; import org.springframework.util.Assert; import org.surfnet.oaaas.auth.principal.AuthenticatedPrincipal; import javax.persistence.*; import javax.validation.constraints.NotNull; import javax.xml.bind.annotation.*; import java.util.List; /** * Representation of an <a * href="http://tools.ietf.org/html/draft-ietf-oauth-v2-30#section-1.4" * >AccessToken</a> * */ @SuppressWarnings("serial") @Entity @Table(name = "accesstoken") @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement public class AccessToken extends AbstractEntity { @Column(unique = true) @NotNull private String token; @Column(unique = true, nullable = true) private String refreshToken; @Transient @XmlTransient private AuthenticatedPrincipal principal; @Lob @Column(length = 16384) @NotNull @XmlTransient private String encodedPrincipal; @ManyToOne(optional = false) @JoinColumn(name = "client_id", nullable = false, updatable = false) @XmlTransient private Client client; /** * Absolute point in time (ms since epoch) when token expires. */ @Column @XmlTransient private long expires; @ElementCollection(fetch= FetchType.EAGER) private List<String> scopes; @Column @NotNull private String resourceOwnerId; public AccessToken() { super(); } public AccessToken(String token, AuthenticatedPrincipal principal, Client client, long expires, List<String> scopes) { this(token, principal, client, expires, scopes, null); } public AccessToken(String token, AuthenticatedPrincipal principal, Client client, long expires, List<String> scopes, String refreshToken) { super(); this.token = token; this.principal = principal; this.encodePrincipal(); this.resourceOwnerId = principal.getName(); this.client = client; this.expires = expires; this.scopes = scopes; this.refreshToken = refreshToken; invariant(); } private void invariant() { Assert.notNull(token, "Token may not be null"); Assert.notNull(client, "Client may not be null"); Assert.notNull(principal, "AuthenticatedPrincipal may not be null"); Assert.isTrue(StringUtils.isNotBlank(principal.getName()), "AuthenticatedPrincipal#name may not be null"); } @PreUpdate @PrePersist public void encodePrincipal() { if (principal != null) { this.encodedPrincipal = principal.serialize(); } } @PostLoad @PostPersist @PostUpdate public void decodePrincipal() { if (StringUtils.isNotBlank(encodedPrincipal)) { this.principal = AuthenticatedPrincipal.deserialize(encodedPrincipal); } } /** * @return the token */ public String getToken() { return token; } /** * @param token * the token to set */ public void setToken(String token) { this.token = token; } /** * @return the client */ public Client getClient() { return client; } /** * @param client * the client to set */ public void setClient(Client client) { this.client = client; } /** * @return the absolute point in time when this token expires. Use {@link #getExpiresIn()} in external communication. * @see #getExpiresIn() */ public long getExpires() { return expires; } /** * Nr of seconds relative to 'now', when token is to expire. * @see #getExpires() */ @XmlElement public long getExpiresIn() { if (expires == 0L) { return 0L; } else { long currInMs = System.currentTimeMillis(); return Math.round((expires - currInMs) / 1000.0); } } /** * @param expires * the expires to set */ public void setExpires(long expires) { this.expires = expires; } /** * @return the scopes */ public List<String> getScopes() { return scopes; } /** * @param scopes * the scopes to set */ public void setScopes(List<String> scopes) { this.scopes = scopes; } /** * @return the principal */ public AuthenticatedPrincipal getPrincipal() { return principal; } /** * @return the encodedPrincipal */ public String getEncodedPrincipal() { return encodedPrincipal; } /** * @return the refreshToken */ public String getRefreshToken() { return refreshToken; } /** * @param refreshToken * the refreshToken to set */ public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } /** * @return the resourceOwnerId */ public String getResourceOwnerId() { return resourceOwnerId; } @XmlElement public String getClientId() { return client.getClientId(); } }