View Javadoc
1   /*
2    * Copyright 2012-2013 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.security.oauth2.provider.approval;
18  
19  import java.util.Collection;
20  import java.util.Date;
21  import java.util.HashSet;
22  
23  import org.springframework.security.oauth2.common.OAuth2AccessToken;
24  import org.springframework.security.oauth2.provider.OAuth2Authentication;
25  import org.springframework.security.oauth2.provider.approval.Approval.ApprovalStatus;
26  import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
27  import org.springframework.security.oauth2.provider.token.TokenStore;
28  
29  /**
30   * An {@link ApprovalStore} that works with an existing {@link TokenStore}, extracting implicit {@link Approval
31   * Approvals} from the content of tokens already in the store. Useful interface so that users can list and revoke
32   * approvals even if they are not really represented in such a way internally. For full fine-grained control of user
33   * approvals don't use a TokenStore at all, and don't use this ApprovalStore with Approval-based
34   * {@link AuthorizationServerTokenServices} implementations.
35   * 
36   * @author Dave Syer
37   * 
38   */
39  public class TokenApprovalStore implements ApprovalStore {
40  
41  	private TokenStore store;
42  
43  	/**
44  	 * @param store the token store to set
45  	 */
46  	public void setTokenStore(TokenStore store) {
47  		this.store = store;
48  	}
49  
50  	/**
51  	 * This implementation is a no-op. We assume that the {@link TokenStore} is populated elsewhere, by (for example) a
52  	 * token services instance that knows more about granted tokens than we could possibly infer from the approvals.
53  	 * 
54  	 * @see org.springframework.security.oauth2.provider.approval.ApprovalStore#addApprovals(java.util.Collection)
55  	 */
56  	@Override
57  	public boolean addApprovals(Collection<Approval> approvals) {
58  		return true;
59  	}
60  
61  	/**
62  	 * Revoke all tokens that match the client and user in the approvals supplied.
63  	 * 
64  	 * @see org.springframework.security.oauth2.provider.approval.ApprovalStore#revokeApprovals(java.util.Collection)
65  	 */
66  	@Override
67  	public boolean revokeApprovals(Collection<Approval> approvals) {
68  		boolean success = true;
69  		for (Approval approval : approvals) {
70  			Collection<OAuth2AccessToken> tokens = store.findTokensByClientIdAndUserName(approval.getClientId(), approval.getUserId());
71  			for (OAuth2AccessToken token : tokens) {
72  				OAuth2Authentication authentication = store.readAuthentication(token);
73  				if (authentication != null
74  						&& approval.getClientId().equals(authentication.getOAuth2Request().getClientId())) {
75  					store.removeAccessToken(token);
76  				}
77  			}
78  		}
79  		return success;
80  	}
81  
82  	/**
83  	 * Extract the implied approvals from any tokens associated with the user and client id supplied.
84  	 * 
85  	 * @see org.springframework.security.oauth2.provider.approval.ApprovalStore#getApprovals(java.lang.String,
86  	 * java.lang.String)
87  	 */
88  	@Override
89  	public Collection<Approval> getApprovals(String userId, String clientId) {
90  		Collection<Approval> result = new HashSet<Approval>();
91  		Collection<OAuth2AccessToken> tokens = store.findTokensByClientIdAndUserName(clientId, userId);
92  		for (OAuth2AccessToken token : tokens) {
93  			OAuth2Authentication authentication = store.readAuthentication(token);
94  			if (authentication != null) {
95  				Date expiresAt = token.getExpiration();
96  				for (String scope : token.getScope()) {
97  					result.add(new Approval(userId, clientId, scope, expiresAt, ApprovalStatus.APPROVED));
98  				}
99  			}
100 		}
101 		return result;
102 	}
103 
104 }