Skip to content

Commit 79188ac

Browse files
committed
Merge branch 'releases/2.7.1'
2 parents fcea46a + be0e444 commit 79188ac

File tree

207 files changed

+9559
-4170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

207 files changed

+9559
-4170
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,4 @@ Here are some ways for you to get involved in the community:
402402
* Watch for upcoming articles on Cloud Foundry by
403403
[subscribing](http://blog.cloudfoundry.org) to the cloudfoundry.org
404404
blog
405+

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ dependencies {
198198
}
199199
}
200200

201-
apply plugin: 'flyway'
201+
apply plugin: 'org.flywaydb.flyway'
202202

203203
flyway {
204204
switch (databaseType()) {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.cloudfoundry.identity.uaa;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnore;
4+
5+
import java.util.Collections;
6+
import java.util.HashMap;
7+
import java.util.LinkedList;
8+
import java.util.List;
9+
import java.util.Map;
10+
11+
/*******************************************************************************
12+
* Cloud Foundry
13+
* Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved.
14+
* <p>
15+
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
16+
* You may not use this product except in compliance with the License.
17+
* <p>
18+
* This product includes a number of subcomponents with
19+
* separate copyright notices and license terms. Your use of these
20+
* subcomponents is subject to the terms and conditions of the
21+
* subcomponent's license, as noted in the LICENSE file.
22+
*******************************************************************************/
23+
public class ExternalIdentityProviderDefinition extends AbstractIdentityProviderDefinition {
24+
public static final String GROUP_ATTRIBUTE_NAME = "external_groups"; //can be a string or a list of strings
25+
public static final String EMAIL_ATTRIBUTE_NAME = "email"; //can be a string
26+
public static final String GIVEN_NAME_ATTRIBUTE_NAME = "given_name"; //can be a string
27+
public static final String FAMILY_NAME_ATTRIBUTE_NAME = "family_name"; //can be a string
28+
public static final String PHONE_NUMBER_ATTRIBUTE_NAME = "phone_number"; //can be a string
29+
public static final String USER_ATTRIBUTE_PREFIX = "user.attribute.";
30+
31+
public static final String EXTERNAL_GROUPS_WHITELIST = "externalGroupsWhitelist";
32+
public static final String ATTRIBUTE_MAPPINGS = "attributeMappings";
33+
34+
private List<String> externalGroupsWhitelist = new LinkedList<>();
35+
private Map<String, Object> attributeMappings = new HashMap<>();
36+
37+
public List<String> getExternalGroupsWhitelist() {
38+
return Collections.unmodifiableList(externalGroupsWhitelist);
39+
}
40+
41+
public void setExternalGroupsWhitelist(List<String> externalGroupsWhitelist) {
42+
this.externalGroupsWhitelist = new LinkedList<>(externalGroupsWhitelist!=null ? externalGroupsWhitelist : Collections.EMPTY_LIST);
43+
}
44+
45+
@JsonIgnore
46+
public void addWhiteListedGroup(String group) {
47+
this.externalGroupsWhitelist.add(group);
48+
}
49+
50+
public void setAttributeMappings(Map<String, Object> attributeMappings) {
51+
this.attributeMappings = new HashMap<>(attributeMappings!=null?attributeMappings:Collections.EMPTY_MAP);
52+
}
53+
54+
public Map<String, Object> getAttributeMappings() {
55+
return Collections.unmodifiableMap(attributeMappings);
56+
}
57+
58+
@JsonIgnore
59+
public void addAttributeMapping(String key, Object value) {
60+
attributeMappings.put(key, value);
61+
}
62+
}

common/src/main/java/org/cloudfoundry/identity/uaa/authentication/Origin.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ public class Origin {
2828
public static final String KEYSTONE = "keystone";
2929
public static final String SAML = "saml";
3030
public static final String NotANumber = "NaN";
31-
public static final String UNKNOWN = "unknown";
32-
3331

3432
public static String getUserId(Authentication authentication) {
3533
String id;

common/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthentication.java

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,38 @@
1212
*******************************************************************************/
1313
package org.cloudfoundry.identity.uaa.authentication;
1414

15-
import com.fasterxml.jackson.annotation.JsonCreator;
16-
import com.fasterxml.jackson.annotation.JsonIgnore;
17-
import com.fasterxml.jackson.annotation.JsonProperty;
15+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
16+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
1817
import org.springframework.security.core.Authentication;
1918
import org.springframework.security.core.GrantedAuthority;
19+
import org.springframework.util.LinkedMultiValueMap;
20+
import org.springframework.util.MultiValueMap;
2021

2122
import java.io.Serializable;
2223
import java.util.Collection;
24+
import java.util.HashMap;
2325
import java.util.List;
26+
import java.util.Map;
27+
import java.util.Set;
28+
29+
import static java.util.Collections.EMPTY_MAP;
2430

2531
/**
2632
* Authentication token which represents a user.
2733
*/
34+
@JsonSerialize(using = UaaAuthenticationSerializer.class)
35+
@JsonDeserialize(using = UaaAuthenticationDeserializer.class)
2836
public class UaaAuthentication implements Authentication, Serializable {
37+
2938
private List<? extends GrantedAuthority> authorities;
3039
private Object credentials;
3140
private UaaPrincipal principal;
3241
private UaaAuthenticationDetails details;
3342
private boolean authenticated;
3443
private long authenticatedTime = -1l;
44+
private long expiresAt = -1l;
45+
private Set<String> externalGroups;
46+
private Map<String, List<String>> userAttributes;
3547

3648
/**
3749
* Creates a token with the supplied array of authorities.
@@ -45,13 +57,22 @@ public UaaAuthentication(UaaPrincipal principal,
4557
this(principal, null, authorities, details, true, System.currentTimeMillis());
4658
}
4759

48-
@JsonCreator
49-
public UaaAuthentication(@JsonProperty("principal") UaaPrincipal principal,
50-
@JsonProperty("credentials") Object credentials,
51-
@JsonProperty("authorities") List<? extends GrantedAuthority> authorities,
52-
@JsonProperty("details") UaaAuthenticationDetails details,
53-
@JsonProperty("authenticated") boolean authenticated,
54-
@JsonProperty(value = "authenticatedTime", defaultValue = "-1") long authenticatedTime) {
60+
public UaaAuthentication(UaaPrincipal principal,
61+
Object credentials,
62+
List<? extends GrantedAuthority> authorities,
63+
UaaAuthenticationDetails details,
64+
boolean authenticated,
65+
long authenticatedTime) {
66+
this(principal, credentials, authorities, details, authenticated, authenticatedTime, -1);
67+
}
68+
69+
public UaaAuthentication(UaaPrincipal principal,
70+
Object credentials,
71+
List<? extends GrantedAuthority> authorities,
72+
UaaAuthenticationDetails details,
73+
boolean authenticated,
74+
long authenticatedTime,
75+
long expiresAt) {
5576
if (principal == null || authorities == null) {
5677
throw new IllegalArgumentException("principal and authorities must not be null");
5778
}
@@ -60,15 +81,29 @@ public UaaAuthentication(@JsonProperty("principal") UaaPrincipal principal,
6081
this.details = details;
6182
this.credentials = credentials;
6283
this.authenticated = authenticated;
63-
this.authenticatedTime = authenticatedTime == 0 ? -1 : authenticatedTime;
84+
this.authenticatedTime = authenticatedTime <= 0 ? -1 : authenticatedTime;
85+
this.expiresAt = expiresAt <= 0 ? -1 : expiresAt;
86+
}
87+
88+
public UaaAuthentication(UaaPrincipal uaaPrincipal,
89+
Object credentials,
90+
List<? extends GrantedAuthority> uaaAuthorityList,
91+
Set<String> externalGroups,
92+
Map<String, List<String>> userAttributes,
93+
UaaAuthenticationDetails details,
94+
boolean authenticated,
95+
long authenticatedTime,
96+
long expiresAt) {
97+
this(uaaPrincipal, credentials, uaaAuthorityList, details, authenticated, authenticatedTime, expiresAt);
98+
this.externalGroups = externalGroups;
99+
this.userAttributes = new HashMap<>(userAttributes);
64100
}
65101

66102
public long getAuthenticatedTime() {
67103
return authenticatedTime;
68104
}
69105

70106
@Override
71-
@JsonIgnore
72107
public String getName() {
73108
// Should we return the ID for the principal name? (No, because the
74109
// UaaUserDatabase retrieves users by name.)
@@ -97,14 +132,18 @@ public UaaPrincipal getPrincipal() {
97132

98133
@Override
99134
public boolean isAuthenticated() {
100-
return authenticated;
135+
return authenticated && (expiresAt > 0 ? expiresAt > System.currentTimeMillis() : true);
101136
}
102137

103138
@Override
104139
public void setAuthenticated(boolean isAuthenticated) {
105140
authenticated = isAuthenticated;
106141
}
107142

143+
public long getExpiresAt() {
144+
return expiresAt;
145+
}
146+
108147
@Override
109148
public boolean equals(Object o) {
110149
if (this == o) {
@@ -132,4 +171,28 @@ public int hashCode() {
132171
result = 31 * result + principal.hashCode();
133172
return result;
134173
}
174+
175+
public Set<String> getExternalGroups() {
176+
return externalGroups;
177+
}
178+
179+
public void setExternalGroups(Set<String> externalGroups) {
180+
this.externalGroups = externalGroups;
181+
}
182+
183+
public MultiValueMap<String,String> getUserAttributes() {
184+
return new LinkedMultiValueMap<>(userAttributes!=null?userAttributes: EMPTY_MAP);
185+
}
186+
187+
public Map<String,List<String>> getUserAttributesAsMap() {
188+
return userAttributes!=null ? new HashMap<>(userAttributes) : EMPTY_MAP;
189+
}
190+
191+
public void setUserAttributes(MultiValueMap<String, String> userAttributes) {
192+
this.userAttributes = new HashMap<>();
193+
for (Map.Entry<String, List<String>> entry : userAttributes.entrySet()) {
194+
this.userAttributes.put(entry.getKey(), entry.getValue());
195+
}
196+
}
197+
135198
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* *****************************************************************************
3+
* Cloud Foundry
4+
* Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved.
5+
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
6+
* You may not use this product except in compliance with the License.
7+
*
8+
* This product includes a number of subcomponents with
9+
* separate copyright notices and license terms. Your use of these
10+
* subcomponents is subject to the terms and conditions of the
11+
* subcomponent's license, as noted in the LICENSE file.
12+
* *****************************************************************************
13+
*/
14+
package org.cloudfoundry.identity.uaa.authentication;
15+
16+
import com.fasterxml.jackson.core.JsonParser;
17+
import com.fasterxml.jackson.core.JsonToken;
18+
import com.fasterxml.jackson.core.type.TypeReference;
19+
import com.fasterxml.jackson.databind.DeserializationContext;
20+
import com.fasterxml.jackson.databind.JsonDeserializer;
21+
import com.fasterxml.jackson.databind.JsonMappingException;
22+
import org.springframework.security.core.GrantedAuthority;
23+
24+
import java.io.IOException;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.Set;
28+
29+
import static java.util.Collections.EMPTY_LIST;
30+
import static java.util.Collections.EMPTY_MAP;
31+
import static java.util.Collections.EMPTY_SET;
32+
33+
public class UaaAuthenticationDeserializer extends JsonDeserializer<UaaAuthentication> implements UaaAuthenticationJsonBase {
34+
@Override
35+
public UaaAuthentication deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
36+
UaaAuthenticationDetails details = null;
37+
UaaPrincipal princpal = null;
38+
List<? extends GrantedAuthority> authorities = EMPTY_LIST;
39+
Set<String> externalGroups = EMPTY_SET;
40+
long expiresAt = -1;
41+
long authenticatedTime = -1;
42+
boolean authenticated = false;
43+
Map<String,List<String>> userAttributes = EMPTY_MAP;
44+
while (jp.nextToken() != JsonToken.END_OBJECT) {
45+
if (jp.getCurrentToken() == JsonToken.FIELD_NAME) {
46+
String fieldName = jp.getCurrentName();
47+
jp.nextToken();
48+
if (NULL_STRING.equals(jp.getText())) {
49+
//do nothing
50+
} else if (DETAILS.equals(fieldName)) {
51+
details = jp.readValueAs(UaaAuthenticationDetails.class);
52+
} else if (PRINCIPAL.equals(fieldName)) {
53+
princpal = jp.readValueAs(UaaPrincipal.class);
54+
} else if (AUTHORITIES.equals(fieldName)) {
55+
authorities = deserializeAuthorites(jp.readValueAs(new TypeReference<List<String>>(){}));
56+
} else if (EXTERNAL_GROUPS.equals(fieldName)) {
57+
externalGroups = jp.readValueAs(new TypeReference<Set<String>>(){});
58+
} else if (EXPIRES_AT.equals(fieldName)) {
59+
expiresAt = jp.getLongValue();
60+
} else if (AUTH_TIME.equals(fieldName)) {
61+
authenticatedTime = jp.getLongValue();
62+
} else if (AUTHENTICATED.equals(fieldName)) {
63+
authenticated = jp.getBooleanValue();
64+
} else if (USER_ATTRIBUTES.equals(fieldName)) {
65+
userAttributes = jp.readValueAs(new TypeReference<Map<String,List<String>>>() {});
66+
}
67+
}
68+
}
69+
if (princpal==null) {
70+
throw new JsonMappingException("Missing "+UaaPrincipal.class.getName());
71+
}
72+
return new UaaAuthentication(princpal,
73+
null,
74+
authorities,
75+
externalGroups,
76+
userAttributes,
77+
details,
78+
authenticated,
79+
authenticatedTime,
80+
expiresAt);
81+
}
82+
}

0 commit comments

Comments
 (0)