Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Open Subsurface Data Universe Software
Platform
System
Partition
Commits
8cc60607
Commit
8cc60607
authored
Mar 15, 2021
by
Rucha Deshpande
Browse files
Merge branch 'dev' of
codecommit://os-partition
into dev
parents
7224c494
1b28830e
Pipeline
#31947
failed with stages
in 40 minutes and 54 seconds
Changes
8
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/AuthorizationService.java
View file @
8cc60607
...
...
@@ -14,32 +14,84 @@
package
org.opengroup.osdu.partition.provider.aws.security
;
import
org.opengroup.osdu.core.aws.entitlements.RequestKeys
;
import
org.opengroup.osdu.core.common.entitlements.IEntitlementsAndCacheService
;
import
org.opengroup.osdu.core.common.model.http.AppException
;
import
org.opengroup.osdu.core.common.model.http.DpsHeaders
;
import
org.opengroup.osdu.partition.provider.interfaces.IAuthorizationService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.context.annotation.RequestScope
;
import
org.opengroup.osdu.core.aws.entitlements.Authorizer
;
import
org.opengroup.osdu.core.aws.ssm.SSMUtil
;
import
javax.annotation.PostConstruct
;
import
java.util.Map
;
@Component
@RequestScope
public
class
AuthorizationService
implements
IAuthorizationService
{
public
static
final
java
.
lang
.
String
PARTITION_GROUP
=
"reserved_aws_admin"
;
public
static
final
java
.
lang
.
String
PARTITION_ADMIN_ROLE
=
"service.partition.admin"
;
@Autowired
private
IEntitlementsAndCacheService
entitlementsAndCacheService
;
@Autowired
private
DpsHeaders
headers
;
@Value
(
"${aws.dynamodb.region}"
)
private
String
awsRegion
;
@Value
(
"${aws.environment}"
)
private
String
awsEnvironment
;
Authorizer
authorizer
;
String
memberEmail
=
null
;
SSMUtil
ssmUtil
=
null
;
String
spu_email
=
null
;
@PostConstruct
public
void
init
()
{
authorizer
=
new
Authorizer
(
awsRegion
,
awsEnvironment
);
if
(
ssmUtil
==
null
)
{
ssmUtil
=
new
SSMUtil
(
"/osdu/"
+
awsEnvironment
+
"/"
);
}
//get sp email
spu_email
=
ssmUtil
.
getSsmParameterAsString
(
"service-principal-user"
);
}
@Override
public
boolean
isDomainAdminServiceAccount
()
{
try
{
return
hasRole
(
PARTITION_ADMIN_ROLE
);
Map
<
String
,
String
>
dpsheaders
=
headers
.
getHeaders
();
String
authorizationContents
=
dpsheaders
.
get
(
RequestKeys
.
AUTHORIZATION_HEADER_KEY
);
if
(
authorizationContents
==
null
){
authorizationContents
=
dpsheaders
.
get
(
RequestKeys
.
AUTHORIZATION_HEADER_KEY
.
toLowerCase
());
}
//no JWT
if
(
authorizationContents
==
null
)
{
throw
AppException
.
createUnauthorized
(
"No JWT token. Access is Forbidden"
);
}
memberEmail
=
authorizer
.
validateJWT
(
authorizationContents
);
if
(
memberEmail
!=
null
)
{
if
(
memberEmail
.
equals
(
spu_email
)){
return
true
;
}
else
{
throw
AppException
.
createUnauthorized
(
"Unauthorized. The user is not Service Principal"
);
}
}
if
(
memberEmail
==
null
){
throw
AppException
.
createUnauthorized
(
"Unauthorized. The JWT token could not be validated"
);
}
}
catch
(
AppException
appE
)
{
throw
appE
;
...
...
@@ -47,15 +99,11 @@ public class AuthorizationService implements IAuthorizationService {
catch
(
Exception
e
)
{
throw
new
AppException
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
(),
"Authentication Failure"
,
e
.
getMessage
(),
e
);
}
return
false
;
}
private
boolean
hasRole
(
String
requiredRole
)
{
headers
.
put
(
DpsHeaders
.
DATA_PARTITION_ID
,
PARTITION_GROUP
);
String
user
=
entitlementsAndCacheService
.
authorize
(
headers
,
requiredRole
);
headers
.
put
(
DpsHeaders
.
USER_EMAIL
,
user
);
return
true
;
}
}
provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/EntitlementsClientFactory.java
deleted
100644 → 0
View file @
7224c494
// Copyright © 2020 Amazon Web Services
// Copyright 2017-2019, Schlumberger
//
// Licensed 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.opengroup.osdu.partition.provider.aws.security
;
import
org.opengroup.osdu.core.common.entitlements.EntitlementsAPIConfig
;
import
org.opengroup.osdu.core.common.entitlements.EntitlementsFactory
;
import
org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory
;
import
org.opengroup.osdu.core.common.http.json.HttpResponseBodyMapper
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.config.AbstractFactoryBean
;
import
org.springframework.stereotype.Component
;
import
javax.inject.Inject
;
@Component
public
class
EntitlementsClientFactory
extends
AbstractFactoryBean
<
IEntitlementsFactory
>
{
@Value
(
"${AUTHORIZE_API}"
)
private
String
AUTHORIZE_API
;
@Value
(
"${AUTHORIZE_API_KEY:}"
)
private
String
AUTHORIZE_API_KEY
;
@Inject
private
HttpResponseBodyMapper
httpResponseBodyMapper
;
@Override
protected
IEntitlementsFactory
createInstance
()
{
return
new
EntitlementsFactory
(
EntitlementsAPIConfig
.
builder
()
.
rootUrl
(
AUTHORIZE_API
)
.
apiKey
(
AUTHORIZE_API_KEY
)
.
build
(),
httpResponseBodyMapper
);
}
@Override
public
Class
<?>
getObjectType
()
{
return
IEntitlementsFactory
.
class
;
}
}
\ No newline at end of file
provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/EntitlementsAndCacheServiceImpl.java
deleted
100644 → 0
View file @
7224c494
// Copyright © 2020 Amazon Web Services
// Copyright 2017-2019, Schlumberger
//
// Licensed 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.opengroup.osdu.partition.provider.aws.service
;
import
org.apache.http.HttpStatus
;
import
org.opengroup.osdu.core.common.model.entitlements.Acl
;
import
org.opengroup.osdu.core.common.model.http.DpsHeaders
;
import
org.opengroup.osdu.core.common.cache.ICache
;
import
org.opengroup.osdu.core.common.model.storage.RecordMetadata
;
import
org.opengroup.osdu.core.common.util.Crc32c
;
import
org.opengroup.osdu.core.common.model.entitlements.EntitlementsException
;
import
org.opengroup.osdu.core.common.model.entitlements.Groups
;
import
org.opengroup.osdu.core.common.model.http.AppException
;
import
org.opengroup.osdu.core.common.http.HttpResponse
;
import
org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory
;
import
org.opengroup.osdu.core.common.entitlements.IEntitlementsService
;
import
org.opengroup.osdu.core.common.logging.JaxRsDpsLog
;
import
org.opengroup.osdu.core.common.entitlements.IEntitlementsAndCacheService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
@Service
public
class
EntitlementsAndCacheServiceImpl
implements
IEntitlementsAndCacheService
{
private
static
final
String
ERROR_REASON
=
"Access denied"
;
private
static
final
String
ERROR_MSG
=
"The user is not authorized to perform this action"
;
@Autowired
private
IEntitlementsFactory
factory
;
@Autowired
private
ICache
<
String
,
Groups
>
cache
;
@Autowired
private
JaxRsDpsLog
logger
;
@Override
public
String
authorize
(
DpsHeaders
headers
,
String
...
roles
)
{
Groups
groups
=
this
.
getGroups
(
headers
);
if
(
groups
.
any
(
roles
))
{
return
groups
.
getDesId
();
}
else
{
throw
new
AppException
(
HttpStatus
.
SC_FORBIDDEN
,
ERROR_REASON
,
ERROR_MSG
);
}
}
@Override
public
boolean
isValidAcl
(
DpsHeaders
headers
,
Set
<
String
>
acls
)
{
Groups
groups
=
this
.
getGroups
(
headers
);
if
(
groups
.
getGroups
()
==
null
||
groups
.
getGroups
().
isEmpty
())
{
this
.
logger
.
error
(
"Error on getting groups for user: "
+
headers
.
getUserEmail
());
throw
new
AppException
(
HttpStatus
.
SC_INTERNAL_SERVER_ERROR
,
"Unknown error"
,
"Unknown error happened when validating ACL"
);
}
String
email
=
groups
.
getGroups
().
get
(
0
).
getEmail
();
if
(!
email
.
matches
(
"^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"
))
{
this
.
logger
.
error
(
"Email address is invalid for this group: "
+
groups
.
getGroups
().
get
(
0
));
throw
new
AppException
(
HttpStatus
.
SC_INTERNAL_SERVER_ERROR
,
"Unknown error"
,
"Unknown error happened when validating ACL"
);
}
String
domain
=
email
.
split
(
"@"
)[
1
];
for
(
String
acl
:
acls
)
{
if
(!
acl
.
split
(
"@"
)[
1
].
equalsIgnoreCase
(
domain
))
{
return
false
;
}
}
return
true
;
}
@Override
public
boolean
hasOwnerAccess
(
DpsHeaders
headers
,
String
[]
ownerList
)
{
Groups
groups
=
this
.
getGroups
(
headers
);
Set
<
String
>
aclList
=
new
HashSet
<>();
for
(
String
owner
:
ownerList
)
{
aclList
.
add
(
owner
.
split
(
"@"
)[
0
]);
}
String
[]
acls
=
new
String
[
aclList
.
size
()];
return
groups
.
any
(
aclList
.
toArray
(
acls
));
}
@Override
public
List
<
RecordMetadata
>
hasValidAccess
(
List
<
RecordMetadata
>
recordsMetadata
,
DpsHeaders
headers
)
{
Groups
groups
=
this
.
getGroups
(
headers
);
List
<
RecordMetadata
>
result
=
new
ArrayList
<>();
for
(
RecordMetadata
recordMetadata
:
recordsMetadata
)
{
Acl
storageAcl
=
recordMetadata
.
getAcl
();
if
(
hasAccess
(
storageAcl
,
groups
))
{
result
.
add
(
recordMetadata
);
}
else
{
this
.
logger
.
warning
(
"Post ACL check fails: "
+
recordMetadata
.
getId
());
}
}
return
result
;
}
private
boolean
hasAccess
(
Acl
storageAcl
,
Groups
groups
)
{
String
[]
viewers
=
storageAcl
.
getViewers
();
String
[]
owners
=
storageAcl
.
getOwners
();
Set
<
String
>
aclList
=
new
HashSet
<>();
for
(
String
viewer
:
viewers
)
{
aclList
.
add
(
viewer
.
split
(
"@"
)[
0
]);
}
for
(
String
owner
:
owners
)
{
aclList
.
add
(
owner
.
split
(
"@"
)[
0
]);
}
String
[]
acls
=
new
String
[
aclList
.
size
()];
if
(
groups
.
any
(
aclList
.
toArray
(
acls
)))
{
return
true
;
}
else
{
return
false
;
}
}
protected
Groups
getGroups
(
DpsHeaders
headers
)
{
String
cacheKey
=
this
.
getGroupCacheKey
(
headers
);
Groups
groups
=
this
.
cache
.
get
(
cacheKey
);
if
(
groups
==
null
)
{
IEntitlementsService
service
=
this
.
factory
.
create
(
headers
);
try
{
groups
=
service
.
getGroups
();
this
.
cache
.
put
(
cacheKey
,
groups
);
this
.
logger
.
info
(
"Entitlements cache miss"
);
}
catch
(
EntitlementsException
e
)
{
e
.
printStackTrace
();
HttpResponse
response
=
e
.
getHttpResponse
();
this
.
logger
.
error
(
String
.
format
(
"Error requesting entitlements service %s"
,
response
));
throw
new
AppException
(
e
.
getHttpResponse
().
getResponseCode
(),
ERROR_REASON
,
ERROR_MSG
,
e
);
}
}
return
groups
;
}
protected
static
String
getGroupCacheKey
(
DpsHeaders
headers
)
{
String
key
=
String
.
format
(
"entitlement-groups:%s:%s"
,
headers
.
getPartitionIdWithFallbackToAccountId
(),
headers
.
getAuthorization
());
return
Crc32c
.
hashToBase64EncodedString
(
key
);
}
}
provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/util/SSMHelper.java
View file @
8cc60607
...
...
@@ -14,24 +14,10 @@
package
org.opengroup.osdu.partition.provider.aws.util
;
import
java.net.URI
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
javax.inject.Inject
;
import
com.amazonaws.auth.AWSCredentialsProvider
;
import
com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement
;
import
com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder
;
import
com.amazonaws.services.simplesystemsmanagement.model.DeleteParametersRequest
;
import
com.amazonaws.services.simplesystemsmanagement.model.DeleteParametersResult
;
import
com.amazonaws.services.simplesystemsmanagement.model.GetParametersByPathRequest
;
import
com.amazonaws.services.simplesystemsmanagement.model.GetParametersByPathResult
;
import
com.amazonaws.services.simplesystemsmanagement.model.ParameterType
;
import
com.amazonaws.services.simplesystemsmanagement.model.PutParameterRequest
;
import
com.amazonaws.services.simplesystemsmanagement.model.PutParameterResult
;
import
com.amazonaws.services.simplesystemsmanagement.model.Parameter
;
import
com.amazonaws.services.simplesystemsmanagement.model.*
;
import
org.opengroup.osdu.core.aws.iam.IAMConfig
;
import
org.opengroup.osdu.partition.model.Property
;
import
org.opengroup.osdu.partition.provider.aws.AwsServiceConfig
;
...
...
@@ -39,10 +25,7 @@ import org.springframework.stereotype.Component;
import
javax.inject.Inject
;
import
java.net.URI
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.*
;
import
java.util.stream.Collectors
;
@Component
...
...
@@ -57,8 +40,8 @@ public final class SSMHelper {
public
SSMHelper
()
{
amazonAWSCredentials
=
IAMConfig
.
amazonAWSCredentials
();
ssmManager
=
AWSSimpleSystemsManagementClientBuilder
.
standard
()
.
withCredentials
(
amazonAWSCredentials
)
.
build
();
.
withCredentials
(
amazonAWSCredentials
)
.
build
();
}
// public boolean secretExists(String secretName) {
...
...
@@ -90,10 +73,10 @@ public final class SSMHelper {
do
{
GetParametersByPathRequest
request
=
new
GetParametersByPathRequest
()
.
withPath
(
ssmPath
)
.
withRecursive
(
true
)
.
withNextToken
(
nextToken
)
.
withWithDecryption
(
true
);
.
withPath
(
ssmPath
)
.
withRecursive
(
true
)
.
withNextToken
(
nextToken
)
.
withWithDecryption
(
true
);
GetParametersByPathResult
result
=
ssmManager
.
getParametersByPath
(
request
);
nextToken
=
result
.
getNextToken
();
...
...
@@ -123,9 +106,9 @@ public final class SSMHelper {
do
{
GetParametersByPathRequest
request
=
new
GetParametersByPathRequest
()
.
withPath
(
ssmPath
)
.
withRecursive
(
true
)
.
withNextToken
(
nextToken
);
.
withPath
(
ssmPath
)
.
withRecursive
(
true
)
.
withNextToken
(
nextToken
);
GetParametersByPathResult
result
=
ssmManager
.
getParametersByPath
(
request
);
nextToken
=
result
.
getNextToken
();
...
...
@@ -161,10 +144,10 @@ public final class SSMHelper {
String
ssmPath
=
getSsmPathForPartititionSecret
(
partitionName
,
secretName
);
PutParameterRequest
request
=
new
PutParameterRequest
()
.
withName
(
ssmPath
)
.
withType
(
ParameterType
.
SecureString
)
.
withOverwrite
(
true
)
.
withValue
(
String
.
valueOf
(
secretValue
));
.
withName
(
ssmPath
)
.
withType
(
ParameterType
.
SecureString
)
.
withOverwrite
(
true
)
.
withValue
(
String
.
valueOf
(
secretValue
));
PutParameterResult
result
=
ssmManager
.
putParameter
(
request
);
...
...
@@ -190,7 +173,7 @@ public final class SSMHelper {
ssmParamPaths
=
ssmParamPaths
.
subList
(
subListCount
,
ssmParamPaths
.
size
());
DeleteParametersRequest
request
=
new
DeleteParametersRequest
()
.
withNames
(
paramsToDelete
);
.
withNames
(
paramsToDelete
);
DeleteParametersResult
result
=
ssmManager
.
deleteParameters
(
request
);
...
...
@@ -218,22 +201,22 @@ public final class SSMHelper {
.
withRecursive
(
true
)
.
withNextToken
(
nextToken
);
result
=
ssmManager
.
getParametersByPath
(
request
);
result
=
ssmManager
.
getParametersByPath
(
request
);
for
(
Parameter
p:
result
.
getParameters
())
{
String
dp
=
(
p
.
getName
().
substring
(
ssmPath
.
length
()).
split
(
"/"
)[
0
]);
uniquePartitions
.
add
(
dp
);
}
nextToken
=
result
.
getNextToken
();
}
while
(
nextToken
!=
null
);
for
(
Parameter
p:
result
.
getParameters
())
{
String
dp
=
(
p
.
getName
().
substring
(
ssmPath
.
length
()).
split
(
"/"
)[
0
]);
uniquePartitions
.
add
(
dp
);
}
partitions
.
addAll
(
uniquePartitions
);
partitions
.
addAll
(
uniquePartitions
);
return
partitions
;
...
...
provider/partition-aws/src/main/resources/application.properties
View file @
8cc60607
...
...
@@ -34,6 +34,9 @@ aws.dynamodb.table.prefix=${ENVIRONMENT}-
aws.dynamodb.region
=
${AWS_REGION}
aws.dynamodb.endpoint
=
dynamodb.${AWS_REGION}.amazonaws.com
aws.environment
=
${ENVIRONMENT}
## AWS ElastiCache configuration
aws.elasticache.cluster.endpoint
=
${CACHE_CLUSTER_ENDPOINT}
aws.elasticache.cluster.port
=
${CACHE_CLUSTER_PORT}
...
...
testing/partition-test-aws/build-aws/run-tests.sh
View file @
8cc60607
...
...
@@ -28,17 +28,6 @@ echo "$SCRIPT_SOURCE_DIR"
(
cd
"
$SCRIPT_SOURCE_DIR
"
/../bin
&&
./install-deps.sh
)
#### ADD REQUIRED ENVIRONMENT VARIABLES HERE ###############################################
# The following variables are automatically populated from the environment during integration testing
# see os-deploy-aws/build-aws/integration-test-env-variables.py for an updated list
# AWS_COGNITO_CLIENT_ID
# PARTITION_URL
export
AWS_COGNITO_AUTH_FLOW
=
USER_PASSWORD_AUTH
export
AWS_COGNITO_AUTH_PARAMS_PASSWORD
=
$ADMIN_PASSWORD
export
AWS_COGNITO_AUTH_PARAMS_USER
=
$ADMIN_USER
export
AWS_COGNITO_AUTH_PARAMS_USER_NO_ACCESS
=
$USER_NO_ACCESS
export
AWS_COGNITO_CLIENT_ID
=
$AWS_COGNITO_CLIENT_ID
export
DOMAIN
=
testing.com
export
PARTITION_BASE_URL
=
$PARTITION_BASE_URL
export
CLIENT_TENANT
=
common
export
MY_TENANT
=
opendes
...
...
testing/partition-test-aws/pom.xml
View file @
8cc60607
...
...
@@ -71,7 +71,7 @@
<dependency>
<groupId>
org.opengroup.osdu.core.aws
</groupId>
<artifactId>
os-core-lib-aws
</artifactId>
<version>
0.3.1
6
</version>
<version>
0.3.1
7
</version>
</dependency>
<dependency>
...
...
testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/util/AwsTestUtils.java
View file @
8cc60607
...
...
@@ -16,39 +16,78 @@
package
org.opengroup.osdu.partition.util
;
import
com.amazonaws.auth.AWSCredentialsProvider
;
import
com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement
;
import
com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder
;
import
com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest
;
import
com.amazonaws.services.simplesystemsmanagement.model.GetParameterResult
;
import
com.google.common.base.Strings
;
import
org.opengroup.osdu.core.aws.cognito.AWSCognitoClient
;
import
io.jsonwebtoken.Claims
;
import
io.jsonwebtoken.Jws
;
import
io.jsonwebtoken.Jwts
;
import
io.jsonwebtoken.SignatureAlgorithm
;
import
org.opengroup.osdu.core.aws.entitlements.ServicePrincipal
;
import
org.opengroup.osdu.core.aws.iam.IAMConfig
;
import
org.opengroup.osdu.core.aws.secrets.SecretsManager
;
import
java.security.KeyPair
;
import
java.security.KeyPairGenerator
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.PrivateKey
;
import
java.security.PublicKey
;
import
java.util.Base64
;
import
java.security.*
;
import
java.util.Date
;
public
class
AwsTestUtils
extends
TestUtils
{
private
AWSCognitoClient
cognitoClient
;
public
AwsTestUtils
()
{
cognitoClient
=
new
AWSCognitoClient
();
}
String
client_credentials_secret
;
String
client_credentials_clientid
;
ServicePrincipal
sp
;
private
String
awsOauthCustomScope
;
private
final
static
String
ENVIRONMENT
=
"ENVIRONMENT"
;
private
final
static
String
REGION
=
"AWS_REGION"
;
private
AWSCredentialsProvider
amazonAWSCredentials
;
private
AWSSimpleSystemsManagement
ssmManager
;
String
sptoken
=
null
;
@Override
public
synchronized
String
getAccessToken
()
throws
Exception
{
if
(
Strings
.
isNullOrEmpty
(
token
))
{