using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using FastReport.Export;
using FastReport.Cloud.OAuth;
using FastReport.Cloud.StorageClient.SkyDrive;
using FastReport.Utils;
namespace FastReport.Cloud.StorageClient.GoogleDrive
{
///
/// Google Drive cloud storage client.
///
public class GoogleDriveStorageClient : 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 GoogleDriveStorageClient() : base()
{
this.clientInfo = new ClientInfo("", "", "");
authCode = "";
accessToken = "";
}
///
/// Initializes a new instance of the class.
///
/// The storage client info.
public GoogleDriveStorageClient(ClientInfo clientInfo) : base()
{
this.clientInfo = clientInfo;
authCode = "";
accessToken = "";
}
///
/// Initializes a new instance of the class.
///
/// Client ID.
/// Client Secret.
public GoogleDriveStorageClient(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("code", authCode);
data.Add("client_id", clientInfo.Id);
data.Add("client_secret", clientInfo.Secret);
data.Add("redirect_uri", @"urn:ietf:wg:oauth:2.0:oob");
data.Add("grant_type", "authorization_code");
return Encoding.UTF8.GetBytes(HttpUtils.UrlDataEncode(data));
}
#endregion // Private Methods
#region Protected Methods
///
protected override void SaveMemoryStream(MemoryStream ms)
{
try
{
System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0 | 0x300 | 0xc00);
string uri = String.Format(@"https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart&access_token={0}", accessToken);
WebRequest request = WebRequest.Create(uri);
request.Method = HttpMethod.Post;
RequestUtils.SetProxySettings(request, ProxySettings);
request.ContentType = "multipart/related; boundary=foo_bar_baz";
List content = new List();
StringBuilder sb = new StringBuilder("--foo_bar_baz\r\n");
sb.Append("Content-Type: application/json; charset=UTF-8\r\n");
sb.Append("\r\n");
sb.Append("{\r\n");
sb.AppendFormat("\"title\": \"{0}\"\r\n", Filename);
sb.Append("}\r\n");
sb.Append("\r\n");
sb.Append("--foo_bar_baz\r\n");
sb.Append("Content-Type: application/octet-stream\r\n");
sb.Append("\r\n");
content.AddRange(Encoding.UTF8.GetBytes(sb.ToString()));
int msLength = Convert.ToInt32(ms.Length);
byte[] msBuffer = new byte[msLength];
ms.Read(msBuffer, 0, msLength);
content.AddRange(msBuffer);
sb = new StringBuilder("\r\n");
sb.Append("--foo_bar_baz--");
content.AddRange(Encoding.UTF8.GetBytes(sb.ToString()));
int length = content.Count;
byte[] buffer = new byte[length];
buffer = content.ToArray();
request.ContentLength = buffer.Length;
using (Stream rs = request.GetRequestStream())
{
rs.Write(buffer, 0, buffer.Length);
}
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
}
catch (Exception ex)
{
throw new CloudStorageException(ex.Message, ex);
}
}
#endregion // Proteced Methods
#region Public Methods
///
/// Gets the authorization URL.
///
/// The authorization URL stirng.
public string GetAuthorizationUrl()
{
return String.Format(@"https://accounts.google.com/o/oauth2/auth?scope={0}&redirect_uri={1}&response_type=code&client_id={2}",
"https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file",
"urn:ietf:wg:oauth:2.0:oob", clientInfo.Id);
}
///
/// Gets the access token.
///
/// The access token string.
public string GetAccessToken()
{
System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0 | 0x300 | 0xc00);
string uri = String.Format(@"?client_id={0}&client_secret={1}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code&code={2}", clientInfo.Id, clientInfo.Secret, authCode);
WebRequest request = WebRequest.Create(@"https://accounts.google.com/o/oauth2/token");
request.Method = HttpMethod.Post;
RequestUtils.SetProxySettings(request, ProxySettings);
request.ContentType = "application/x-www-form-urlencoded";
byte[] content = BuildGetAccessTokenRequestContent();
request.ContentLength = content.Length;
//!!! need exception
using (Stream rs = request.GetRequestStream())
{
rs.Write(content, 0, content.Length);
}
WebResponse response = request.GetResponse();
accessToken = Parser.ParseGoogleDriveToken(response.GetResponseStream());
return accessToken;
}
#endregion // Public Methods
}
}