Skip to content

Commit 52a8191

Browse files
authored
Parse credentials in from environment for server workers. (#35)
1 parent a1566b0 commit 52a8191

File tree

1 file changed

+50
-24
lines changed

1 file changed

+50
-24
lines changed

apis/platform_common/Credential.cs

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
using Google.Apis.Auth.OAuth2.Flows;
99
using Google.Apis.Auth.OAuth2.Responses;
1010

11-
namespace Improbable.SpatialOS.Platform.Common {
11+
namespace Improbable.SpatialOS.Platform.Common
12+
{
1213
/// <inheritdoc />
1314
/// <summary>
1415
/// This is the abstract base class for SpatialOS platform credentials. Clients should use a concrete credential provider
1516
/// such as <see cref="PlatformRefreshTokenCredential" /> instead of trying to instantiate this class directly.
1617
/// </summary>
17-
public abstract class PlatformCredential : UserCredential {
18+
public abstract class PlatformCredential : UserCredential
19+
{
1820
/// <inheritdoc />
1921
/// <summary>
2022
/// </summary>
@@ -29,17 +31,19 @@ protected PlatformCredential(IAuthorizationCodeFlow flow, string userId, TokenRe
2931
/// <summary>
3032
/// This provides support to automatically acquire access tokens from SpatialOS refresh tokens.
3133
/// </summary>
32-
public class PlatformRefreshTokenCredential : PlatformCredential {
34+
public class PlatformRefreshTokenCredential : PlatformCredential
35+
{
3336
private const string DefaultTokenFileEnvVar = "SPATIALOS_REFRESH_TOKEN_FILE";
3437
private const string DummyUserId = "dummy_user_id";
3538
private const string AuthorizationServerUrl = "https://auth.improbable.io/auth/v1/authcode";
3639
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.";
3841

3942
private static readonly Lazy<PlatformRefreshTokenCredential> AutoDetectedLazy =
4043
new Lazy<PlatformRefreshTokenCredential>(GetTokenCredentialAutomatically);
4144

42-
private static readonly ClientSecrets DefaultSecrets = new ClientSecrets {
45+
private static readonly ClientSecrets DefaultSecrets = new ClientSecrets
46+
{
4347
// This client ID is purposely chosen to be compatible with the default settings of the spatial CLI tool
4448
// so that the SDK can reuse the refresh token retrieved and stored via spatial CLI.
4549
ClientId = "improbable_cli_client_go",
@@ -48,7 +52,7 @@ public class PlatformRefreshTokenCredential : PlatformCredential {
4852
"SuperTrouperBeamsAreGonnaBlindMeButIWontFeelBlueLifeIAwaysDoCauseSomewhereInTheCrowdTheresYou"
4953
};
5054

51-
private static readonly IEnumerable<string> DefaultScopes = new List<string> {"[*]:*"};
55+
private static readonly IEnumerable<string> DefaultScopes = new List<string> { "[*]:*" };
5256

5357
/// <summary>
5458
/// Initializes a new instance of the <see cref="PlatformRefreshTokenCredential" /> class that uses the supplied
@@ -58,18 +62,23 @@ public class PlatformRefreshTokenCredential : PlatformCredential {
5862
/// <param name="tokenServerUrl">The URL of the OAuth token server. Defaults to Improbable's production OAuth token server.</param>
5963
/// <param name="scopes">The scope to request for the OAuth server. Defaults to "[*]:*".</param>
6064
/// <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>
6166
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)
6368
: 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+
}),
7078
DummyUserId,
71-
new TokenResponse {RefreshToken = refreshToken}
72-
) { }
79+
new TokenResponse { RefreshToken = refreshToken }
80+
)
81+
{ }
7382

7483
/// <inheritdoc />
7584
/// <summary>
@@ -104,19 +113,36 @@ private static PlatformRefreshTokenCredential GetTokenCredentialAutomatically()
104113
};
105114

106115
var tokenFile = possibleTokenFiles.FirstOrDefault(File.Exists);
107-
if (tokenFile == null)
116+
if (tokenFile != null)
108117
{
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+
}
111127
}
112128

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+
}
119142
}
143+
144+
// Fail if no form of credentials could be found.
145+
throw new NoRefreshTokenFoundException(RefreshTokenNotFoundMessage);
120146
}
121147
}
122148
}

0 commit comments

Comments
 (0)