using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using FastReport.Export;
using FastReport.Cloud.OAuth;
using FastReport.Utils;
namespace FastReport.Cloud.StorageClient.SkyDrive
{
///
/// SkyDrive cloud storage client.
///
public class SkyDriveStorageClient : CloudStorageClient
{
#region Fields
private ClientInfo clientInfo;
private string authCode;
private string accessToken;
#endregion // Fields
#region Properties
///
/// Gets or sets the client info.
///
public ClientInfo ClientInfo
{
get { return clientInfo; }
set { clientInfo = value; }
}
///
/// Gets or sets the authorization code.
///
public string AuthCode
{
get { return authCode; }
set { authCode = value; }
}
///
/// Gets or sets the access token.
///
public string AccessToken
{
get { return accessToken; }
set { accessToken = value; }
}
#endregion // Properties
#region Constructors
///
/// Initializes a new instance of the class.
///
public SkyDriveStorageClient() : base()
{
clientInfo = new ClientInfo("", "", "");
authCode = "";
accessToken = "";
}
///
/// Initializes a new instance of the class.
///
/// The client info.
public SkyDriveStorageClient(ClientInfo clientInfo) : base()
{
this.clientInfo = clientInfo;
authCode = "";
accessToken = "";
}
///
/// Initializes a new instance of the class.
///
/// Client ID.
/// Client Secret.
public SkyDriveStorageClient(string clientId, string clientSecret) : base()
{
this.clientInfo = new ClientInfo("", clientId, clientSecret);
authCode = "";
accessToken = "";
}
#endregion // Constructors
#region Private Methods
private byte[] BuildGetAccessTokenRequestContent()
{
Dictionary data = new Dictionary();
data.Add("client_id", clientInfo.Id);
data.Add("redirect_uri", @"https://login.microsoftonline.com/common/oauth2/nativeclient");
data.Add("grant_type", "authorization_code");
data.Add("code", authCode);
return Encoding.UTF8.GetBytes(HttpUtils.UrlDataEncode(data));
}
#endregion // Private Methods
#region Protected Methods
///
protected override void SaveMemoryStream(MemoryStream ms)
{
string url = String.Format(@"https://graph.microsoft.com/v1.0/me/drive/items/root:/{0}:/content", Filename);
try
{
System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0 | 0x300 | 0xc00);
WebRequest request = WebRequest.Create(url);
request.Method = HttpMethod.Put;
RequestUtils.SetProxySettings(request, ProxySettings);
request.Headers.Add("Authorization", $"Bearer {accessToken}");
int length = Convert.ToInt32(ms.Length);
byte[] buffer = new byte[length];
ms.Read(buffer, 0, length);
request.ContentLength = buffer.Length;
request.ContentType = "application/octet-stream";
using (Stream rs = request.GetRequestStream())
{
rs.Write(buffer, 0, length);
}
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
}
catch (Exception ex)
{
throw new CloudStorageException(ex.Message, ex);
}
}
#endregion // Protected Methods
#region Public Methods
///
/// Gets the authorization URL.
///
/// The authorization URL string.
public string GetAuthorizationUrl()
{
return String.Format($@"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&client_id={clientInfo.Id}&scope=files.readwrite offline_access&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient");
}
///
/// Gets the access token.
///
/// The access token value.
public string GetAccessToken()
{
System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0 | 0x300 | 0xc00);
WebRequest request = WebRequest.Create(@"https://login.microsoftonline.com/common/oauth2/v2.0/token");
request.Method = HttpMethod.Post;
RequestUtils.SetProxySettings(request, ProxySettings);
request.ContentType = "application/x-www-form-urlencoded";
byte[] content = BuildGetAccessTokenRequestContent();
request.ContentLength = content.Length;
using (Stream rs = request.GetRequestStream())
{
rs.Write(content, 0, content.Length);
}
using (WebResponse response = request.GetResponse())
{
accessToken = Parser.ParseSkyDriveToken(response.GetResponseStream());
}
return accessToken;
}
#endregion // Public Methods
}
}