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 } }