8
8
using Google . Apis . Auth . OAuth2 . Flows ;
9
9
using Google . Apis . Auth . OAuth2 . Responses ;
10
10
11
- namespace Improbable . SpatialOS . Platform . Common {
11
+ namespace Improbable . SpatialOS . Platform . Common
12
+ {
12
13
/// <inheritdoc />
13
14
/// <summary>
14
15
/// This is the abstract base class for SpatialOS platform credentials. Clients should use a concrete credential provider
15
16
/// such as <see cref="PlatformRefreshTokenCredential" /> instead of trying to instantiate this class directly.
16
17
/// </summary>
17
- public abstract class PlatformCredential : UserCredential {
18
+ public abstract class PlatformCredential : UserCredential
19
+ {
18
20
/// <inheritdoc />
19
21
/// <summary>
20
22
/// </summary>
@@ -29,17 +31,19 @@ protected PlatformCredential(IAuthorizationCodeFlow flow, string userId, TokenRe
29
31
/// <summary>
30
32
/// This provides support to automatically acquire access tokens from SpatialOS refresh tokens.
31
33
/// </summary>
32
- public class PlatformRefreshTokenCredential : PlatformCredential {
34
+ public class PlatformRefreshTokenCredential : PlatformCredential
35
+ {
33
36
private const string DefaultTokenFileEnvVar = "SPATIALOS_REFRESH_TOKEN_FILE" ;
34
37
private const string DummyUserId = "dummy_user_id" ;
35
38
private const string AuthorizationServerUrl = "https://auth.improbable.io/auth/v1/authcode" ;
36
39
private const string TokenServerUrl = "https://auth.improbable.io/auth/v1/token" ;
37
- private const string RefreshTokenNotFoundMessage = "Please check if environment variable " + DefaultTokenFileEnvVar + " is set to the correct path or try running `spatial init` to fetch and store a new refresh token locally." ;
40
+ private const string RefreshTokenNotFoundMessage = "Please check if environment variable " + DefaultTokenFileEnvVar + " is set to the correct path or try running `spatial init` to fetch and store a new refresh token locally." ;
38
41
39
42
private static readonly Lazy < PlatformRefreshTokenCredential > AutoDetectedLazy =
40
43
new Lazy < PlatformRefreshTokenCredential > ( GetTokenCredentialAutomatically ) ;
41
44
42
- private static readonly ClientSecrets DefaultSecrets = new ClientSecrets {
45
+ private static readonly ClientSecrets DefaultSecrets = new ClientSecrets
46
+ {
43
47
// This client ID is purposely chosen to be compatible with the default settings of the spatial CLI tool
44
48
// so that the SDK can reuse the refresh token retrieved and stored via spatial CLI.
45
49
ClientId = "improbable_cli_client_go" ,
@@ -48,7 +52,7 @@ public class PlatformRefreshTokenCredential : PlatformCredential {
48
52
"SuperTrouperBeamsAreGonnaBlindMeButIWontFeelBlueLifeIAwaysDoCauseSomewhereInTheCrowdTheresYou"
49
53
} ;
50
54
51
- private static readonly IEnumerable < string > DefaultScopes = new List < string > { "[*]:*" } ;
55
+ private static readonly IEnumerable < string > DefaultScopes = new List < string > { "[*]:*" } ;
52
56
53
57
/// <summary>
54
58
/// Initializes a new instance of the <see cref="PlatformRefreshTokenCredential" /> class that uses the supplied
@@ -58,18 +62,23 @@ public class PlatformRefreshTokenCredential : PlatformCredential {
58
62
/// <param name="tokenServerUrl">The URL of the OAuth token server. Defaults to Improbable's production OAuth token server.</param>
59
63
/// <param name="scopes">The scope to request for the OAuth server. Defaults to "[*]:*".</param>
60
64
/// <param name="authServerUrl">The URL of the OAuth auth server. Defaults to Improbable's production OAuth auth server.</param>
65
+ /// <param name="clientSecrets">The client secrets for the SpatialOS refresh token.</param>
61
66
public PlatformRefreshTokenCredential ( string refreshToken , string authServerUrl = null ,
62
- string tokenServerUrl = null , IEnumerable < string > scopes = null )
67
+ string tokenServerUrl = null , IEnumerable < string > scopes = null , ClientSecrets clientSecrets = null )
63
68
: base (
64
- new AuthorizationCodeFlow ( new AuthorizationCodeFlow . Initializer (
65
- authServerUrl ?? AuthorizationServerUrl ,
66
- tokenServerUrl ?? TokenServerUrl ) {
67
- Scopes = scopes ?? DefaultScopes ,
68
- ClientSecrets = DefaultSecrets
69
- } ) ,
69
+ new AuthorizationCodeFlow (
70
+ new AuthorizationCodeFlow . Initializer (
71
+ authServerUrl ?? AuthorizationServerUrl ,
72
+ tokenServerUrl ?? TokenServerUrl
73
+ )
74
+ {
75
+ Scopes = scopes ?? DefaultScopes ,
76
+ ClientSecrets = clientSecrets ?? DefaultSecrets
77
+ } ) ,
70
78
DummyUserId ,
71
- new TokenResponse { RefreshToken = refreshToken }
72
- ) { }
79
+ new TokenResponse { RefreshToken = refreshToken }
80
+ )
81
+ { }
73
82
74
83
/// <inheritdoc />
75
84
/// <summary>
@@ -104,19 +113,36 @@ private static PlatformRefreshTokenCredential GetTokenCredentialAutomatically()
104
113
} ;
105
114
106
115
var tokenFile = possibleTokenFiles . FirstOrDefault ( File . Exists ) ;
107
- if ( tokenFile = = null )
116
+ if ( tokenFile ! = null )
108
117
{
109
- // None of the possible token files exists
110
- throw new NoRefreshTokenFoundException ( RefreshTokenNotFoundMessage ) ;
118
+ try
119
+ {
120
+ var refreshToken = File . ReadAllText ( tokenFile ) ;
121
+ return new PlatformRefreshTokenCredential ( refreshToken ) ;
122
+ }
123
+ catch ( IOException )
124
+ {
125
+ throw new NoRefreshTokenFoundException ( RefreshTokenNotFoundMessage ) ;
126
+ }
111
127
}
112
128
113
- try {
114
- var refreshToken = File . ReadAllText ( tokenFile ) ;
115
- return new PlatformRefreshTokenCredential ( refreshToken ) ;
116
- }
117
- catch ( IOException ) {
118
- throw new NoRefreshTokenFoundException ( RefreshTokenNotFoundMessage ) ;
129
+ // None of the possible token files exists. Last fallback is the credentials set in the environment of server workers.
130
+ var serverRefreshToken = Environment . GetEnvironmentVariable ( "IMPROBABLE_PLATFORM_REFRESH_TOKEN" ) ;
131
+ if ( serverRefreshToken != "" )
132
+ {
133
+ var clientSecrets = new ClientSecrets
134
+ {
135
+ ClientId = Environment . GetEnvironmentVariable ( "IMPROBABLE_CLIENT_ID" ) ,
136
+ ClientSecret = Environment . GetEnvironmentVariable ( "IMPROBABLE_CLIENT_SECRET" )
137
+ } ;
138
+ if ( clientSecrets . ClientId != "" && clientSecrets . ClientSecret != "" )
139
+ {
140
+ var credentials = new PlatformRefreshTokenCredential ( serverRefreshToken , null , null , null , clientSecrets ) ;
141
+ }
119
142
}
143
+
144
+ // Fail if no form of credentials could be found.
145
+ throw new NoRefreshTokenFoundException ( RefreshTokenNotFoundMessage ) ;
120
146
}
121
147
}
122
148
}
0 commit comments