private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "XXXXXXXXX",
ClientSecret = "XXXXXXXXXXXX"
},
Scopes = new[] { AnalyticsService.Scope.AnalyticsReadonly, AnalyticsService.Scope.AnalyticsEdit },
DataStore = new FileDataStore("Analytics.Auth.Store")//new FileDataStore("Drive.Api.Auth.Store")
});
I am using above code for google console web application(Google Analytic) but it gives error System.UnauthorizedAccessException: Access to the path 'Analytics.Auth.Store' is denied.
FileDataStore stores the data in %AppData% on the pc. You need to make sure that you have access to that.
If you are planning on running this from a webserver you should not be using FileDataStore. You should create your own implementation of iDataStore, this will enable you to store the refresh tokens in the database.
Example:
///
/// Saved data store that implements .
/// This Saved data store stores a StoredResponse object.
///
class SavedDataStore : IDataStore
{
public StoredResponse _storedResponse { get; set; }
///
/// Constructs Load previously saved StoredResponse.
///
///Stored response
public SavedDataStore(StoredResponse pResponse)
{
this._storedResponse = pResponse;
}
public SavedDataStore()
{
this._storedResponse = new StoredResponse();
}
///
/// Stores the given value. into storedResponse
/// .
///
///The type to store in the data store
///The key
///The value to store in the data store
public Task StoreAsync(string key, T value)
{
var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value);
JObject jObject = JObject.Parse(serialized);
// storing access token
var test = jObject.SelectToken("access_token");
if (test != null)
{
this._storedResponse.access_token = (string)test;
}
// storing token type
test = jObject.SelectToken("token_type");
if (test != null)
{
this._storedResponse.token_type = (string)test;
}
test = jObject.SelectToken("expires_in");
if (test != null)
{
this._storedResponse.expires_in = (long?)test;
}
test = jObject.SelectToken("refresh_token");
if (test != null)
{
this._storedResponse.refresh_token = (string)test;
}
test = jObject.SelectToken("Issued");
if (test != null)
{
this._storedResponse.Issued = (string)test;
}
return TaskEx.Delay(0);
}
///
/// Deletes StoredResponse.
///
///The key to delete from the data store
public Task DeleteAsync(string key)
{
this._storedResponse = new StoredResponse();
return TaskEx.Delay(0);
}
///
/// Returns the stored value for_storedResponse
///The type to retrieve
///The key to retrieve from the data store
/// The stored object
public Task GetAsync(string key)
{
TaskCompletionSource tcs = new TaskCompletionSource();
try
{
string JsonData = Newtonsoft.Json.JsonConvert.SerializeObject(this._storedResponse);
tcs.SetResult(Google.Apis.Json.NewtonsoftJsonSerializer.Instance.Deserialize(JsonData));
}
catch (Exception ex)
{
tcs.SetException(ex);
}
return tcs.Task;
}
///
/// Clears all values in the data store.
///
public Task ClearAsync()
{
this._storedResponse = new StoredResponse();
return TaskEx.Delay(0);
}
///// Creates a unique stored key based on the key and the class type.
/////The object key
/////The type to store or retrieve
//public static string GenerateStoredKey(string key, Type t)
//{
// return string.Format("{0}-{1}", t.FullName, key);
//}
}
Then instead of using FileDataStore you use your new SavedDataStore
//Now we load our saved refreshToken.
StoredResponse myStoredResponse = new StoredResponse(tbRefreshToken.Text);
// Now we pass a SavedDatastore with our StoredResponse.
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = "YourClientId", ClientSecret = "YourClientSecret" },
new[] { AnalyticsService.Scope.AnalyticsReadonly},
"user",
CancellationToken.None,
new SavedDataStore(myStoredResponse)).Result; }
This is because you dont have write access to AppData folder on a Webserver and FileDataStore uses that folder by default.
You can use a different folder by giving full path as parameter
FileDataStore(string folder, bool fullPath = false)
sample implementation
static FileDataStore GetFileDataStore()
{
var path = HttpContext.Current.Server.MapPath("~/App_Data/Drive.Api.Auth.Store");
var store = new FileDataStore(path, fullPath: true);
return store;
}
This way FileDataStore uses the App_Data folder of your application to write the TokenResponse. Dont forget to give write access to App_Data folder on the Webserver
You can read more about this at here and here
Related
I have multi-level json coming from aws secret and I want to bind this json or secret with the configuration of c# so that I can use it in the whole project.
public class AmazonSecretsManagerConfigurationProvider : ConfigurationProvider
{
private readonly string _region;
private readonly string _secretName;
/// <summary>
/// Initializes a new instance of the <see cref="AmazonSecretsManagerConfigurationProvider"/> class.
/// </summary>
/// <param name="region"></param>
/// <param name="secretName"></param>
public AmazonSecretsManagerConfigurationProvider(string region, string secretName)
{
_region = region;
_secretName = secretName;
}
public override void Load()
{
var secret = GetSecret();
Dictionary<string, object> data = JsonConvert.DeserializeObject<Dictionary<string, object>>(secret);
Dictionary<string, string> Data = data.ToDictionary(k => k.Key, k => k.Value.ToString());
}
private string GetSecret()
{
var request = new GetSecretValueRequest
{
SecretId = "awsseceret",
VersionStage = "AWSCURRENT" // VersionStage defaults to AWSCURRENT if unspecified.
};
string accesskey = "################";
string secretkey = "#######################";
using (var client =
new AmazonSecretsManagerClient(accesskey, secretkey, RegionEndpoint.GetBySystemName(this._region)))
{
var response = client.GetSecretValueAsync(request).Result;
string secretString;
if (response.SecretString != null)
{
secretString = response.SecretString;
}
else
{
var memoryStream = response.SecretBinary;
var reader = new StreamReader(memoryStream);
secretString =
System.Text.Encoding.UTF8
.GetString(Convert.FromBase64String(reader.ReadToEnd()));
}
return secretString;
}
}
}
}
I get aws secretString in the secret variable but how can I bind this to the configuration?
I'm using the below class to handle cookies and use them to store/read values in my ASP.NET MVC application (such as shopping cart items, etc.)
1.I want to know if values are stored without any security in the browser and anyone can look inside its content (using the below implementation)? I checked that values are stored as some hexadecimal values but I doubt that any specific encryption/security exists in this implementation.
2.How can I modify this class to store cookie values as encrypted information?
using System;
using System.Web;
namespace My.Application.Sample
{
public class CookieStore
{
public static void SetCookie(string key, string value)
{
SetCookie(key, value, TimeSpan.FromDays(14));
}
public static void SetCookie(string key, string value, TimeSpan expires)
{
string encodedValue = HttpUtility.UrlEncode(value);
HttpCookie encodedCookie = new HttpCookie(key, encodedValue);
if (HttpContext.Current.Request.Cookies[key] != null)
{
var cookieOld = HttpContext.Current.Request.Cookies[key];
cookieOld.Expires = DateTime.Now.Add(expires);
cookieOld.Value = encodedCookie.Value;
HttpContext.Current.Response.Cookies.Add(cookieOld);
}
else
{
encodedCookie.Expires = DateTime.Now.Add(expires);
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
}
/// <summary>
/// Return value stored in a cookie by defined key, if not found returns empty string
/// </summary>
/// <param name="key"></param>
/// <returns> never returns null! :) </returns>
public static string GetCookie(string key)
{
string value = string.Empty;
try
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[key];
//if (cookie != null)
//{
// // For security purpose, we need to encrypt the value.
// HttpCookie decodedCookie = HttpSecureCookie.Decode(cookie);
// value = decodedCookie.Value;
//}
if (cookie != null)
{
string encodedValue = cookie.Value;
value = HttpUtility.UrlDecode(encodedValue);
}
}
catch (Exception)
{
}
return value;
}
}
}
You can use the Protect and Unprotect methods to encrypt cookies. Note that both bytes have the same key value. Data encrypted with Protect can only be decrypted with Unprotect.
encrypted method
public string encryptedCookie(string value)
{
var cookieText = Encoding.UTF8.GetBytes(value);
var encryptedValue = Convert.ToBase64String(MachineKey.Protect(cookieText, "ProtectCookie"));
return encryptedValue;
}
decrypted method
public string decryptedCookie(string value)
{
var bytes = Convert.FromBase64String(value);
var output = MachineKey.Unprotect(bytes, "ProtectCookie");
string result = Encoding.UTF8.GetString(output);
return result;
}
Instead of "ProtectCookie", you can use your unique key.
I have about 50 users of a WPF application that need to have a search routine run when their phone rings. Part of this solution is have a WCF service that each WPF instance registers with. The WCF service gets the callback using OperationContext.Current.GetCallbackChannel. The idea is that when a call is received, the WCF service is notified; identifying the WPF instance and running a search based on the incoming phone number. This means that the representative does not have to perform a search manually.
The problem is that the service seems to stop working after an unspecified amount of time and I don't know why. It is hosted on IIS 7. Is there some setting on IIS that needs to be set?
It's a very simple setup, currently. Here is the entire code for the service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PhoenixCommunicationService : IPhoenixCommunicationService
{
/// <summary>
/// List of registered Phoenix applications
/// </summary>
private static readonly List<PhoenixInstance> _callbackList = new List<PhoenixInstance>();
private class PhoenixInstance
{
public string UserName { get; set; }
public string Environment { get; set; }
public IPhoenixCallBack CallBack { get; set; }
}
/// <summary>
/// Returns a list of all users logged into a particular environment (DEV, QA, Live)
/// </summary>
/// <param name="enviornment">Environment to check</param>
/// <returns></returns>
public List<string> GetUserList(string enviornment)
{
List<string> retVal = new List<string>();
try
{
var userList = _callbackList.Where(l => l.Environment == enviornment).ToList();
foreach (var user in userList)
{
retVal.Add(user.UserName);
}
}
catch { }
return retVal;
}
/// <summary>
/// Register each Phoenix application
/// </summary>
public void RegisterPhoenixUser(string userName, string environment)
{
try
{
var search = _callbackList.FirstOrDefault(c => string.Equals(c.UserName, userName, StringComparison.CurrentCultureIgnoreCase) && c.Environment == environment);
if (search != null)
{
_callbackList.Remove(search);
}
IPhoenixCallBack callBack = OperationContext.Current.GetCallbackChannel<IPhoenixCallBack>();
_callbackList.Add(new PhoenixInstance
{
UserName = userName,
Environment = environment,
CallBack = callBack
});
}
catch (Exception ex)
{
using (EventLog eventLog = new EventLog("Application"))
{
eventLog.Source = "Application";
eventLog.WriteEntry(String.Format("PhoenixCommunicationService failed to register user {0}. {1}", userName, ex.Message), EventLogEntryType.Information, 101, 1);
}
}
finally
{
foreach (var pu in _callbackList)
{
pu.CallBack.PhoenixUserRegistered(userName, environment);
}
}
}
/// <summary>
/// Removes the application from the Registered List
/// </summary>
public void WithdrawRegisteredPhoenixUser()
{
string userName = string.Empty;
string environment = string.Empty;
try
{
IPhoenixCallBack callBack = OperationContext.Current.GetCallbackChannel<IPhoenixCallBack>();
// Remove the application from the list of registered applications
for (int x = _callbackList.Count - 1; x >= 0; x--)
{
var pu = _callbackList[x];
if (pu.CallBack == callBack)
{
userName = pu.UserName;
environment = pu.Environment;
_callbackList.RemoveAt(x);
break;
}
}
}
catch (Exception ex)
{
using (EventLog eventLog = new EventLog("Application"))
{
eventLog.Source = "Application";
eventLog.WriteEntry(String.Format("PhoenixCommunicationService failed to withdraw registered user. {0}", ex.Message), EventLogEntryType.Information, 101, 1);
}
}
finally
{
if (!String.IsNullOrEmpty(userName))
{
foreach (var pu in _callbackList)
{
pu.CallBack.PhoenixUserLoggedOff(userName, environment);
}
}
}
}
/// <summary>
/// Removes the application from the Registered List
/// </summary>
/// <param name="userName">User to remove</param>
/// <param name="environment">Environment to remove from</param>
public void WithdrawRegisteredPhoenixUserName(string userName, string environment)
{
try
{
// Remove the application from the list of registered applications
for (int x = _callbackList.Count - 1; x >= 0; x--)
{
var pu = _callbackList[x];
if (string.Equals(pu.UserName, userName, StringComparison.CurrentCultureIgnoreCase) && pu.Environment == environment)
{
userName = pu.UserName;
environment = pu.Environment;
_callbackList.RemoveAt(x);
break;
}
}
}
catch (Exception ex)
{
using (EventLog eventLog = new EventLog("Application"))
{
eventLog.Source = "Application";
eventLog.WriteEntry(String.Format("PhoenixCommunicationService failed to withdraw registered user {0}. {1}", userName, ex.Message), EventLogEntryType.Information, 101, 1);
}
}
finally
{
if (!String.IsNullOrEmpty(userName))
{
foreach (var pu in _callbackList)
{
pu.CallBack.PhoenixUserLoggedOff(userName, environment);
}
}
}
}
}
It is setup as a single instance. All the methods work perfectly for a while. As a matter of fact, the GetUserList() method has never failed. But I cannot Register new users after some time.
If anyone has suggestions, I'd love to hear them.
I'm using the Google .NET API to get analytics data from google analytics.
this is me code to start the authentication:
IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = googleApiClientId,
ClientSecret = googleApiClientSecret
},
Scopes = new[] {
Google.Apis.Analytics.v3.AnalyticsService.Scope.AnalyticsReadonly
},
DataStore = new Google.Apis.Util.Store.FileDataStore("Test_GoogleApi")
});
it users the FileDataStore which stores in local user profile as a file. I'm running this code inside an ASP.NET application so I can't really use that FileDataStore so what I will need is some other way to get the data.
Google.Apis.Util.Store contains only the FileDataStore and an interface of IDataStore. Before I go and implement my own DataStore - are there any other DataStore objects out there available for download?
Thanks
The source for Google's FileDataStore is available here.
I've written a simple Entity Framework (version 6) implementation of IDataStore as shown below.
If you're looking to put this in a separate project, as well as EF you'll need the Google.Apis.Core nuget package installed.
public class Item
{
[Key]
[MaxLength(100)]
public string Key { get; set; }
[MaxLength(500)]
public string Value { get; set; }
}
public class GoogleAuthContext : DbContext
{
public DbSet<Item> Items { get; set; }
}
public class EFDataStore : IDataStore
{
public async Task ClearAsync()
{
using (var context = new GoogleAuthContext())
{
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
await objectContext.ExecuteStoreCommandAsync("TRUNCATE TABLE [Items]");
}
}
public async Task DeleteAsync<T>(string key)
{
if (string.IsNullOrEmpty(key))
{
throw new ArgumentException("Key MUST have a value");
}
using (var context = new GoogleAuthContext())
{
var generatedKey = GenerateStoredKey(key, typeof(T));
var item = context.Items.FirstOrDefault(x => x.Key == generatedKey);
if (item != null)
{
context.Items.Remove(item);
await context.SaveChangesAsync();
}
}
}
public Task<T> GetAsync<T>(string key)
{
if (string.IsNullOrEmpty(key))
{
throw new ArgumentException("Key MUST have a value");
}
using (var context = new GoogleAuthContext())
{
var generatedKey = GenerateStoredKey(key, typeof(T));
var item = context.Items.FirstOrDefault(x => x.Key == generatedKey);
T value = item == null ? default(T) : JsonConvert.DeserializeObject<T>(item.Value);
return Task.FromResult<T>(value);
}
}
public async Task StoreAsync<T>(string key, T value)
{
if (string.IsNullOrEmpty(key))
{
throw new ArgumentException("Key MUST have a value");
}
using (var context = new GoogleAuthContext())
{
var generatedKey = GenerateStoredKey(key, typeof (T));
string json = JsonConvert.SerializeObject(value);
var item = await context.Items.SingleOrDefaultAsync(x => x.Key == generatedKey);
if (item == null)
{
context.Items.Add(new Item { Key = generatedKey, Value = json});
}
else
{
item.Value = json;
}
await context.SaveChangesAsync();
}
}
private static string GenerateStoredKey(string key, Type t)
{
return string.Format("{0}-{1}", t.FullName, key);
}
}
I know this question was answered some time ago, however I thought this would be a good place to share my findings for those having similar difficulty finding examples. I have found it to be difficult to find documentation/samples on using the Google APIs .Net library for an Desktop or MVC Web application. I finally found a good example in the tasks example you can find in the samples repository on the Google Project site here <- That really really helped me out.
I ended up snagging the source for the FileDataStore and created an AppDataStore class and placed it in my App_Code folder. You can find the source here, though it was a simple change really - changing the folder to point to ~/App_Data instead.
The last piece of the puzzle I'm looking into figuring out is getting the offline_access token.
Edit: Here's the code for convenience:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Util.Store;
using Google.Apis.Json;
namespace Google.Apis.Util.Store {
public class AppDataFileStore : IDataStore {
readonly string folderPath;
/// <summary>Gets the full folder path.</summary>
public string FolderPath { get { return folderPath; } }
/// <summary>
/// Constructs a new file data store with the specified folder. This folder is created (if it doesn't exist
/// yet) under <see cref="Environment.SpecialFolder.ApplicationData"/>.
/// </summary>
/// <param name="folder">Folder name.</param>
public AppDataFileStore(string folder) {
folderPath = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/"), folder);
if (!Directory.Exists(folderPath)) {
Directory.CreateDirectory(folderPath);
}
}
/// <summary>
/// Stores the given value for the given key. It creates a new file (named <see cref="GenerateStoredKey"/>) in
/// <see cref="FolderPath"/>.
/// </summary>
/// <typeparam name="T">The type to store in the data store.</typeparam>
/// <param name="key">The key.</param>
/// <param name="value">The value to store in the data store.</param>
public Task StoreAsync<T>(string key, T value) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentException("Key MUST have a value");
}
var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value);
var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T)));
File.WriteAllText(filePath, serialized);
return TaskEx.Delay(0);
}
/// <summary>
/// Deletes the given key. It deletes the <see cref="GenerateStoredKey"/> named file in
/// <see cref="FolderPath"/>.
/// </summary>
/// <param name="key">The key to delete from the data store.</param>
public Task DeleteAsync<T>(string key) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentException("Key MUST have a value");
}
var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T)));
if (File.Exists(filePath)) {
File.Delete(filePath);
}
return TaskEx.Delay(0);
}
/// <summary>
/// Returns the stored value for the given key or <c>null</c> if the matching file (<see cref="GenerateStoredKey"/>
/// in <see cref="FolderPath"/> doesn't exist.
/// </summary>
/// <typeparam name="T">The type to retrieve.</typeparam>
/// <param name="key">The key to retrieve from the data store.</param>
/// <returns>The stored object.</returns>
public Task<T> GetAsync<T>(string key) {
if (string.IsNullOrEmpty(key)) {
throw new ArgumentException("Key MUST have a value");
}
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T)));
if (File.Exists(filePath)) {
try {
var obj = File.ReadAllText(filePath);
tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(obj));
}
catch (Exception ex) {
tcs.SetException(ex);
}
}
else {
tcs.SetResult(default(T));
}
return tcs.Task;
}
/// <summary>
/// Clears all values in the data store. This method deletes all files in <see cref="FolderPath"/>.
/// </summary>
public Task ClearAsync() {
if (Directory.Exists(folderPath)) {
Directory.Delete(folderPath, true);
Directory.CreateDirectory(folderPath);
}
return TaskEx.Delay(0);
}
/// <summary>Creates a unique stored key based on the key and the class type.</summary>
/// <param name="key">The object key.</param>
/// <param name="t">The type to store or retrieve.</param>
public static string GenerateStoredKey(string key, Type t) {
return string.Format("{0}-{1}", t.FullName, key);
}
}
}
I had to set the approval prompt to force in order to get the offline access token.
var req = HttpContext.Current.Request;
var oAuthUrl = Flow.CreateAuthorizationCodeRequest(new UriBuilder(req.Url.Scheme, req.Url.Host, req.Url.Port, GoogleCalendarUtil.CallbackUrl).Uri.ToString()) as GoogleAuthorizationCodeRequestUrl;
oAuthUrl.Scope = string.Join(" ", new[] { CalendarService.Scope.CalendarReadonly });
oAuthUrl.ApprovalPrompt = "force";
oAuthUrl.State = AuthState;
You basicly need to create your own implimitation of Idatastore and then use that.
IDataStore StoredRefreshToken = new myDataStore();
// Oauth2 Autentication.
using (var stream = new System.IO.FileStream("client_secret.json", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { AnalyticsService.Scope.AnalyticsReadonly },
"user", CancellationToken.None, StoredRefreshToken).Result;
}
Check here for a basic example of an implimitation of Idatastore. Google Oauth loading stored refresh token
Update:
Several versions of this can be found in my Authentication sample project on GitHub Google-Dotnet-Samples / Authentication / Diamto.Google.Authentication
Update 2
Updated database datastore exmaples
There are implementations for Windows 8 applications and Windows Phone available here:
WP Data Store
WinRT Data Store
Take a look in the following thread Deploying ASP.NET to Windows Azure cloud, application gives error when running on cloud before you are going to implement your own DataStore.
In the future we might also have a EF DataStore. Remember that it's an open source project so you may implement it and send it to review :) Take a look in our contribution page (https://code.google.com/p/google-api-dotnet-client/wiki/BecomingAContributor)
Our Web App is hosted on Azure so I needed to create an IDataStore for that.
I used Azure Table Storage as our data store.
Here's a gist of my attempt
Feedback and suggestions are welcome
For one of my projects we utilize a Content Delivery Network (EdgeCast) and I was wondering if anyone knew of an existing (open source) library for C# that we could leverage? In a nutshell, I am investigating the ability to create directories, upload files, and allow some general maintenance (rename files, delete files) via our admin panel. Any insight would be appreciated.
NOTE: My code to do this. I don't know if they have an updated API at this point so please check. This code is circa 2009 (as-is, no warranties, use at your own risk, etc).
EdgeCast.cs
using System;
using edgeCastWS = [DOMAIN].com.edgecast.api.EdgeCastWebServices;
namespace [DOMAIN].IO.ContentDeliveryNetwork
{
/// <summary>
/// <b>Authentication</b>
/// <para>Each web service call will include a string parameter called strCredential which will ensure that customers may only access data related to their own accounts. This credential is a string made up of a few separate pieces of information.</para>
/// <para>A typical credential a customer would use may look like: “c:bas:user#email.com:password”</para>
/// <para> * The field format of this string is delimited with a colon “:” character.</para>
/// <para> * The first field is the type of client which is calling the web service. “c” represents an individual customer.</para>
/// <para> * The second field is the security type. “bas” represents Basic Authentication.</para>
/// <para> * With basic authentication the third field is the username which is usually in email address notation.</para>
/// <para> * With basic authentication the fourth field is the password associated with the user.</para>
/// <para>If the username and password are not valid, then the credential will prevent the specified function from proceeding. A SOAP exception will be generated and sent back to the client that called the function. The message contained in the exception will contain the string “Access Denied.”</para>
/// </summary>
public class EdgeCast : IDisposable
{
#region Declarations
[ThreadStatic]
private static EdgeCast _current;
private static EdgeCastCredential _credential = null;
private static string _customerID = string.Empty;
private static edgeCastWS _edgeCastWS = null;
#endregion
#region Constructor
public EdgeCast()
{
if (_current != null)
{
throw new InvalidOperationException("Only one ContentDeliveryNetwork may be created on a given thread.");
}
_current = this;
_edgeCastWS = new edgeCastWS();
ConstructCredentials();
_customerID = AppSettings.EdgeCast_CustomerID;
}
#endregion
#region API Methods
/// <summary>
/// Purges a file from all of the EdgeCast caching servers. This process may take a few minutes to fully complete.
/// </summary>
/// <param name="Path">This is path of the file or folder to purge, in URL format. To specify a folder, please put a trailing slash at the end of the URL. All files under that folder will be purged</param>
/// <param name="MediaType">HTTP Large Object = 3, HTTP Small Object = 8, Flash = 2, Windows = 1</param>
/// <returns>An integer that indicates whether or not the transaction was successful. 0 represents yes, -1 represents no</returns>
internal static short PurgeFileFromEdge(string Path, int MediaType)
{
return _edgeCastWS.PurgeFileFromEdge(_credential.Credential, _customerID, Path, MediaType);
}
/// <summary>
/// Loads a file to disk on all of the EdgeCast caching servers. This process may take a few minutes to fully complete.
/// </summary>
/// <param name="Path">This is path of the file to load, in URL format. Folders may not be loaded and will be ignored</param>
/// <param name="MediaType">HTTP Large Object = 3, HTTP Small Object = 8</param>
/// <returns>An integer that indicates whether or not the transaction was successful. 0 represents yes, -1 represents no</returns>
internal static short LoadFileToEdge(string Path, int MediaType)
{
return _edgeCastWS.LoadFileToEdge(_credential.Credential, _customerID, Path, MediaType);
}
/// <summary>
/// This method call is used to add a token authentication directory. All additions and changes should be processed every 30 minutes
/// </summary>
/// <param name="Dir">Directory Path should be starting from the root. Example: /directory1/directory2</param>
/// <param name="MediaType">Use 1 for Windows, 2 for Flash, 3 for HTTP Caching / Progressive download.</param>
/// <returns></returns>
internal static short TokenDirAdd(string Dir, int MediaType)
{
return _edgeCastWS.TokenDirAdd(_credential.Credential, _customerID, Dir, MediaType);
}
internal static string TokenEncrypt(string Key, string Args)
{
return _edgeCastWS.TokenEncrypt(_credential.Credential, Key, Args);
}
internal static short TokenKeyUpdate(string Key, int MediaType)
{
return _edgeCastWS.TokenKeyUpdate(_credential.Credential, _customerID, Key, MediaType);
}
#endregion
#region FTP Methods
/// <summary>
/// Does a FTP Upload of a file on the local system
/// </summary>
/// <param name="targetPath">The full path to save to on the FTP server (.\Campaigns\Prod\[Company GUID])</param>
/// <param name="sourceFileName">The full path and filename of the file to be uploaded (C:\[DOMAIN]\files\[filename])</param>
internal static void FTP_UploadFile(string targetPath, string sourceFileName)
{
string[] dirs = targetPath.Split(new char[] { '\\', '/' });
using (FTPFactory myFTP = new FTPFactory())
{
myFTP.login();
myFTP.setBinaryMode(true);
// Make sure the directories are there and change down to the bottom most directory...
foreach (string dirName in dirs)
{
bool dirExists = true;
try { myFTP.chdir(dirName); }
catch { dirExists = false; }
if (!dirExists)
{
myFTP.mkdir(dirName);
myFTP.chdir(dirName);
}
}
// upload the file now...
myFTP.upload(sourceFileName);
}
}
/// <summary>
/// Returns a string array of files in the target directory
/// </summary>
/// <param name="targetPath">The target directory</param>
/// <returns>string array or null if no files found</returns>
internal static string[] FTP_GetFileList(string targetPath)
{
string[] dirs = targetPath.Split(new char[] { '\\', '/' });
string[] files = null;
using (FTPFactory myFTP = new FTPFactory())
{
myFTP.login();
myFTP.setBinaryMode(true);
// Make sure the directories are there and change down to the bottom most directory...
foreach (string dirName in dirs)
{
bool dirExists = true;
try { myFTP.chdir(dirName); }
catch { dirExists = false; }
if (!dirExists)
{
myFTP.mkdir(dirName);
myFTP.chdir(dirName);
}
}
// get the list of files now...
files = myFTP.getFileList("*.*");
}
return files;
}
/// <summary>
/// Checks to see if a file exists
/// </summary>
/// <param name="targetPath">The CDN directory path to look in</param>
/// <param name="targetFile">The file to look for</param>
/// <returns>true = found, false = not found</returns>
internal static bool FTP_DoesFileExist(string targetPath, string targetFile)
{
bool retFlag = true;
string[] dirs = targetPath.Split(new char[] { '\\', '/' });
using (FTPFactory myFTP = new FTPFactory())
{
myFTP.login();
myFTP.setBinaryMode(true);
// change to the target directory - if it does not exists, neither does the file! simple...
foreach (string dirName in dirs)
{
try { myFTP.chdir(dirName); }
catch { retFlag = false; }
}
if (retFlag)
{
try { retFlag = myFTP.getFileSize(targetFile) > 0; }
catch { retFlag = false; }
}
}
return retFlag;
}
internal static bool FTP_DoesFileExist(string targetFile)
{
string targetPath = targetFile.Replace(#"http://", "");
targetPath = targetPath.Replace(#"https://", "");
targetPath = targetPath.Replace(#"cdn1.[DOMAIN].com/", "");
targetPath = targetPath.Replace(#"/", #"\");
targetPath = targetPath.Substring(0, targetPath.LastIndexOf(#"\"));
targetFile = targetFile.Substring(targetFile.LastIndexOf(#"/") + 1);
return FTP_DoesFileExist(targetPath, targetFile);
}
#endregion
#region Helper Methods
static private string ConstructCredentials()
{
_credential = new EdgeCastCredential();
return _credential.Credential;
}
static private string ConstructCredentials(string credentials)
{
_credential = new EdgeCastCredential(credentials);
return _credential.Credential;
}
static private string ConstructCredentials(string typeOfClient, string securityType, string userName, string password)
{
_credential = new EdgeCastCredential(typeOfClient, securityType, userName, password);
return _credential.Credential;
}
#endregion
#region IDisposable Members
public void Dispose()
{
_current = null;
}
#endregion
}
}
EdgeCastCredential.cs
using System;
using rivSecurity = [DOMAIN].Security.Cryptography.Internal;
namespace [DOMAIN].IO.ContentDeliveryNetwork
{
internal class EdgeCastCredential
{
#region Properties
public string TypeOfClient;
public string SecurityType;
public string UserName;
public string Password;
public string Credential { get { return String.Format("{0}:{1}:{2}:{3}", TypeOfClient, SecurityType, UserName, Password); } }
#endregion
#region Constructor
public EdgeCastCredential()
{
TypeOfClient = AppSettings.EdgeCast_TypeOfClient;
SecurityType = AppSettings.EdgeCast_SecurityType;
UserName = rivSecurity.Decrypt(AppSettings.EdgeCast_UserName);
Password = rivSecurity.Decrypt(AppSettings.EdgeCast_Password);
}
public EdgeCastCredential(string credentials)
{
string[] parts = credentials.Split(new char[] { ':' });
}
public EdgeCastCredential(string typeOfClient, string securityType, string userName, string password)
{
TypeOfClient = typeOfClient;
SecurityType = securityType;
UserName = userName;
Password = password;
}
#endregion
}
}
Never mind. I created a FTP library and used what little they had for an API. I can not now read/upload/delete files and purge the CDN.