Skip to content

Instantly share code, notes, and snippets.

@conwid
Created Jun 16, 2019
Embed
What would you like to do?
public static class BlogBackupFunction
{
private static string blogUrl;
private static string clientSecret;
private static string clientId;
private static string userName;
private static string password;
private static string backupContainer;
private static string loginEndpoint = "ghost/api/v0.1/authentication/token";
private static string backupEndpoint = "ghost/api/v0.1/db/?access_token={0}";
private static string revokeEndpoint = "ghost/api/v0.1/authentication/revoke";
[FunctionName("backupfunction")]
// Run at 2:30 UTC every day
public static async Task Run([TimerTrigger("0 30 2 * * *")]TimerInfo myTimer, Binder binder, TraceWriter log)
{
InitConfig(log);
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(blogUrl);
var formContent = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"grant_type","password" },
{"username",userName },
{"password",password },
{"client_id",clientId },
{"client_secret",clientSecret }
});
log.Info("Getting access token...");
var response = await client.PostAsync(loginEndpoint, formContent);
log.Info("Access token response downloaded, examining result...");
if (response.IsSuccessStatusCode)
{
log.Info("Response OK.");
await SuccessCallback(client, response, binder, log);
}
else
{
var content = await response.Content.ReadAsStringAsync();
log.Error($"Error downloading access token: {content}");
}
}
}
private static void InitConfig(TraceWriter log)
{
blogUrl = ConfigurationManager.AppSettings["BlogUrl"];
clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
clientId = ConfigurationManager.AppSettings["ClientId"];
userName = ConfigurationManager.AppSettings["UserEmail"];
password = ConfigurationManager.AppSettings["Password"];
backupContainer = ConfigurationManager.AppSettings["BackupContainer"];
log.Info("Config read.");
log.Info($"Blog url: {blogUrl}");
log.Info($"Client secret: {clientSecret}");
log.Info($"Client id: {clientId}");
log.Info($"User email: {userName}");
log.Info($"Password: {password}");
log.Info($"Backup container: {backupContainer}");
}
private static async Task SuccessCallback(HttpClient client, HttpResponseMessage response, Binder binder, TraceWriter log)
{
var content = await response.Content.ReadAsStringAsync();
var accessToken = JObject.Parse(content)["access_token"].Value<string>();
var refreshToken = JObject.Parse(content)["refresh_token"].Value<string>();
log.Info("Getting export...");
var backup = await client.GetAsync(string.Format(backupEndpoint, accessToken));
log.Info("Export downloaded, examining result...");
if (backup.IsSuccessStatusCode)
{
log.Info("Response OK, saving contents to blob");
var backupContent = await backup.Content.ReadAsStringAsync();
var attributes = new Attribute[]
{
new BlobAttribute($"{backupContainer}/export_{DateTime.UtcNow.ToString("yyyyMMdd_HHmmss")}.json")
};
using (var writer = await binder.BindAsync<TextWriter>(attributes))
{
writer.Write(backupContent);
}
}
else
{
var errorContent = await backup.Content.ReadAsStringAsync();
log.Error($"Error during export: {errorContent}");
}
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
try
{
await InvalidateRefreshToken(client, log, refreshToken);
}
catch (Exception ex)
{
log.Error("Error invalidating refresh token", ex);
}
try
{
await InvalidateAccessToken(client, log, accessToken);
}
catch (Exception ex)
{
log.Error("Error invalidating access token", ex);
}
}
private static async Task InvalidateRefreshToken(HttpClient client, TraceWriter log, string refreshToken)
{
var revokeRefreshContent = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"token_type_hint","refresh_token" },
{"token",refreshToken },
{"client_id",clientId },
{"client_secret",clientSecret }
});
var resp = await client.PostAsync(revokeEndpoint, revokeRefreshContent);
if (resp.IsSuccessStatusCode)
{
log.Info("Refresh token invalidated");
}
else
{
var errorContent = await resp.Content.ReadAsStringAsync();
log.Error($"Error invalidating refresh token: {errorContent}");
}
}
private static async Task InvalidateAccessToken(HttpClient client, TraceWriter log, string accessToken)
{
var revokeAcsContent = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"token_type_hint","access_token" },
{"token",accessToken },
{"client_id",clientId },
{"client_secret",clientSecret }
});
log.Info("Invalidating access token...");
var resp = await client.PostAsync(revokeEndpoint, revokeAcsContent);
if (resp.IsSuccessStatusCode)
{
log.Info("Access token invalidated");
}
else
{
var errorContent = await resp.Content.ReadAsStringAsync();
log.Error($"Error invalidating access token: {errorContent}");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment