Рассмотрим два самых знаменитых облачных хранилища:Google Drive и OneDrive.

API документация по Google Drive: https://developers.google.com/drive/v2/reference/.

Загрузим на Google Drive PDF-файл.

1) Скачиваем и устанавливаем Google Data APIs (GData).

2) Переходим на сайт https://console.cloud.google.com/start.

3) Создаем новый или выбираем существующий проект.

4) Переходим в меню APIs & auth → APIs.

5) Включаем нужные API (Drive API и Drive SDK) в значение ON.

6) Переходим в меню APIs & auth → Registered apps и нажать Register app

7) Указать название приложения и выбрать тип Native.

8) Выбираем наше приложение и выбираем пункт Update (требуется указать почтовый адрес и название нашего приложения).

Воспользуемся примером кода "Uploading a new document or file with both metadata and content".

#Загружаем требуемые библиотеки(путь может быть изменен, Program Files)
Add-Type -Path"C:\Program Files (x86)\Google\Google Data API SDK\Redist\Google.GData.Documents.dll"
Add-Type -Path "C:\Program Files (x86)\Google\Google Data API SDK\Redist\Google.GData.Client.dll"

#Учетные данные Google Account
$glogin = 'Login'
$gpass = 'password'

#Файл для загрузки
$FileToUpload = "C:\PDF\wp__understanding-wmi-malware.pdf"
# Имя файла без расширения
$fname = [System.IO.Path]::GetFileNameWithoutExtension($FileToUpload)

#Указываем API, отделяя их запятой,список - https://support.google.com/a/answer/162106?hl=ru
$scopes = "https://docs.google.com/feeds/ https://docs.googleusercontent.com/"

#Подставляем данные из пункта №8
$param = New-Object Google.GData.Client.OAuth2Parameters -Property @{
ClientId = "ID"
ClientSecret = "Secret"
RedirectUri = "urn:ietf:wg:oauth:2.0:oob"
Scope = $scopes
}

#Получаем ссылку для авторизации OAuth
$url = [Google.GData.Client.OAuthUtil]::CreateOAuth2AuthorizationUrl($param)

#После перехода по ссылке получаем код
$ie = New-Object -ComObjectInternetExplorer.Application
$ie.Navigate($url)
While($ie.busy -eq $true)
{Start-Sleep -Milliseconds 500}
While ($ie.Document.Title -match "не подключены")
{Start-Sleep -Milliseconds 500}
If ($ie.Document.Title -match "Вход"){
$login=$ie.document.getElementByID("Email")
$login.Value=$glogin
$pass=$ie.document.getElementByID("Passwd")
$pass.Value=$gpass
$ie.document.getElementByID("signIn") | Foreach {$_.click()}
While ($ie.busy -eq $true)
{Start-Sleep -Milliseconds 500}
}

If ($ie.Document.Title -match "Запрос на разрешение") {
$ie.Document.Forms.Item(0) | where {$_.innerText -eq "Принять"} | Foreach {$_.click()}
While ($ie.busy -eq $true)
{Start-Sleep -Milliseconds 500}
If($ie.Document.Body.outerHTML -match 'value="(.+)"><script')
{$global:param.AccessCode = $matches[1]}
}
$ie.Quit()

#Получаем токен авторизации и создаем аутентификатор
[Google.GData.Client.OAuthUtil]::GetAccessToken($param)
$authenticator = New-Object Google.GData.Client.OAuth2Authenticator("Test",$param)
$rf = new-object Google.GData.Client.GOAuth2RequestFactory("apps", "Test", $param)

$service = New-Object Google.GData.Documents.DocumentsService("Test")
$service.RequestFactory = $rf

#Формируем документ на отправку
$dentry=New-Object Google.GData.Documents.DocumentEntry
$dentry.Title.Text="$fname"
$dentry.MediaSource=New-Object Google.GData.Client.MediaFileSource($FileToUpload,"application/pdf")
$createUploadUrl=New-Object System.Uri("https://docs.google.com/feeds/upload/create-session/default/private/full")
$link=New-Object Google.GData.Client.AtomLink($createUploadUrl)
$link.Rel = [Google.GData.Client.ResumableUpload.ResumableUploader]::CreateMediaRelation
$dentry.Links.Add($link)
$dentry.Service=$service

#Загрузка файла
$uploader=New-Object Google.GData.Client.ResumableUpload.ResumableUploader
Register-ObjectEvent -InputObject $uploader -EventName AsyncOperationProgress -Action {
Write-Progress -activity Upload -status 'Progress->' -percentcomplete $EventArgs.ProgressPercentage} | Out-Null
Register-ObjectEvent -InputObject $uploader -EventName AsyncOperationCompleted -Action {
Get-EventSubscriber | Unregister-Event -Force
Write-Host -ForegroundColor Yellow "Completed!!!"
} | Out-Null
$uploader.InsertAsync($authenticator, $dentry, (new-object object))

API документация по OneDrive: https://msdn.microsoft.com/ru-ru/library/office/dn641952.aspx

В качестве примеры создадим веб-приложение не привязанное к какой-либо платформе (только HTML, CSS и JavaScript). Приложение должно содержать следующие функции:

  • Отображать содержимое OneDrive (папки, файлы) с возможностью навигации по папкам
  • Создавать, переименовывать и удалять папки/файлы
  • Осуществлять поиск в OneDrive

Отображаться должны только файлы текущего пользователя.

Веб-приложение будет построено на AngularJS 1.x без использования какого-либо серверного кода. В качестве UI Framework будет использован Bootstrap.

Для авторизации будет использован Azure AD Authentication Library (ADAL). В случае с AngularJS для реализации такой аутентификации достаточно подключить следующие js-файлы:

<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.7/js/adal.min.js"></script>
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.7/js/adal-angular.min.js"></script>

После чего авторизация будет инициироваться вызовом метода:

//AngularJS ADAL login
adalAuthenticationService.login();

Logout соответственно:

//AngularJS ADAL logout
adalAuthenticationService.logOut();

Создавая решения на базе Office 365 и Microsoft API, задача авторизации пользователя решается крайне просто: два js-файла и две сроки кода. Безопасность и разграничение прав пользователей также на стороне Office 365.

Для доступа к OneDrive пользователя будем использовать Microsoft API. Здесь мы имеем единый endpoint, что сильно облегчает работу. Например для получения информации о файлах и папках в корне OneDrive для текущего пользователя достаточно выполнить запрос:

GET https://graph.microsoft.com/v1.0/me/drive/root/children

Чтобы подключаться к Microsoft API необходимо зарегистрировать своё приложение Azure Portal и предоставить ему соответствующие права.

1) Создаем приложение. Переходим к списку приложений (Active Directory - {ДОМЕН} - Applications) и нажимаем Add:

Приложение мы создаем своё, а не выбираем существующее из галереи, выбираем "Add an application my organization is developing":

Затем указываем имя приложения, выбираем ""Web application and/or web api", задаем любой App ID URI.

Адрес Sign-On необходимо указывать существующий. При несовпадении URL-адреса, с которого происходит авторизация, с теми, что указаны в настройках приложения будет выдано исключение.

AADSTS50011: The reply address '{URL}' does not match the reply addresses configured for the application

Для работы нам понадобиться CLIENT ID. Скопировать его можно со страницы настройки приложения:

2) Права приложения. Создаваемому приложению необходимо предоставить соответствующие права (для работы с OneDrive):

  • Files.Read
  • Files.ReadWrite

Этих прав достаточно для создания/изменения/удаления элементов, изменения прав на файлы, папки, поиск. Настройка прав на той же странице конфигурации приложения:

3) Visual Studio

Была использована Visual Studio 2015 и шаблон веб-приложения ASP.NET 5. Visual Studio можно было бы не использовать вовсе, ограничившись бесплатной Visual Studio Code для работы с кодом и npm или Bower для установки пакетов.

Серверная часть приложения - это файл satrtup.cs:

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.StaticFiles;
namespace Zhukov.Blog.Graph.AngularJS {
public class Startup {
public void Configure(IApplicationBuilder app) {
app.UseIISPlatformHandler();
DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("default.html");
// Файл по умолчанию
app.UseDefaultFiles(options);
// Статические файлы
app.UseStaticFiles(); }
public static void Main(string[] args) => WebApplication.Run(args);
} }

Единственная его задача - указать файл по умолчанию (default.html) и разрешить использование статичных файлов (метод UseStaticFiles). Все остальное - JavaScript, HTML и CSS.

Пакеты, которые используются в приложении:

Инициализация приложения выглядит примерно вот так:

// CLIENT ID from https://manage.windowsazure.com
var clientId = '27015206-d28a-45a6-a952-a1e987edf216';
// OneDrive App
var oneDriveApp = angular.module('MicrosoftGraphSPA', [ 'ngRoute', 'AdalAngular', 'angular-loading-bar' ]).config(config);
function config($routeProvider, $httpProvider, adalAuthenticationServiceProvider, cfpLoadingBarProvider) {
// Routing
// ADAL
adalAuthenticationServiceProvider.init( {
clientId: clientId, //CLIENT ID
endpoints: {
'https://graph.microsoft.com': 'https://graph.microsoft.com' }
}, $httpProvider);
// Hide loading spinner
cfpLoadingBarProvider.includeSpinner = false; };

Мы опустили роутинг в листинге выше. Помимо него в конфигурации приложения (метод config) указывает ClientId соответствующий созданному в Azure Portal приложению на шаге 1 и скрываем индикатор загрузки для loading bar, оставив только progress bar.

4) Сервис. Для взаимодействия с Microsoft API создадим фабрику oneDriveFactory. Логика её проста - формировать и отправлять запросы с учетом авторизации текущего пользователя. Вот сокращенный листинг:

angular
.module('MicrosoftGraphSPA')
.constant('graphUrl', 'https://graph.microsoft.com/v1.0')
.factory('oneDriveFactory', [
'$http', 'graphUrl',
function($http, graphUrl) {
var oneDriveFactory = {};
// Получение содержимого из корня
OneDrive oneDriveFactory.getRoot = function() {
return $http({
method: 'GET',
url: graphUrl + '/me/drive/root/children' }); };
// Переименование файла или папки
oneDriveFactory.saveItem = function(itemId, name) {
return $http({
method: 'PATCH',
url: graphUrl + '/me/drive/items/' + itemId,
data: {
name: name } }); };
// Создание новой папки
oneDriveFactory.addFolder = function(parentId, name) {
var url = parentId ? graphUrl + '/me/drive/items/' + parentId + '/children' : graphUrl + '/me/drive/root/children';
return $http({
method: 'POST',
url: url, data: {
name: name, folder: {} } }); }
// Удаление файла или папки
oneDriveFactory.removeItem = function(itemId) {
return $http({
method: 'DELETE',
url: graphUrl + '/me/drive/items/' + itemId }); }
return oneDriveFactory; } ]);

Любая операция в Office 365 при использовании Microsoft API - это всегда HTTP-запрос с параметрами, что крайне облегчает разработку решений.

5) Контроллер. Контроллеры для вызова методов фабрики также крайне прост. Листинг контроллера для результатов поиска:

(function () {
angular
.module('MicrosoftGraphSPA')
.controller('SearchController', [
'$scope', '$rootScope', '$http', '$location', 'oneDriveFactory',
function ($scope, $rootScope, $http, $location, oneDriveFactory) {
// Запрос
$scope.query = $location.search().q;
// Элементы
$scope.items = null;
// Загрузка элементов из Office 365
$scope.loadItems = function () {
oneDriveFactory.searchItems($scope.query)
.then(
function (response) {
// Заполняем items
$scope.items = response.data.value;
}, $rootScope.responseError); }
// Если указан поисковый запрос, то заполняем items
if ($scope.query) {
$scope.loadItems(); } } ]); })();

6) Роутинг. Приложение содержит три вида представления:

  • Корень пользовательского OneDrive (представление по умолчанию);
  • Просмотр содержимого папки;
  • Отображение результатов поиска.

Соответственно листинг роутинга:

$routeProvider
// Routing
.when('/onedrive', { //Root
templateUrl: 'views/onedrive.html',
controller: 'OneDriveController',
controllerAs: 'controller' })
.when('/onedrive/search', { //Search
templateUrl: 'views/search.html',
controller: 'SearchController',
controllerAs: 'controller' })
.when('/onedrive/:itemId', { //File/Folder
templateUrl: 'views/onedrive.html',
controller: 'OneDriveController',
controllerAs: 'controller' })
.otherwise({ //Root by default
redirectTo: '/onedrive' });

7) Интерфейс. В случае с отображением результатов поиска представление выглядит следующим образом:

<ul class="breadcrumb">
<li><a href="#/">Microsoft Graph SPA</a></li>
<li><a href="#/onedrive">OneDrive</a></li>
<li class="active">Search</li>
</ul>
<!-- Search results -->
<div class="row">
<table class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Size</th>
<th>Created</th>
<th>Created By</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items | orderBy: 'folder'">
<td>
<i class="fa" ng-class="item.folder ? 'fa-folder' : 'fa-file'" aria-hidden="true"></i>
<a href="#/onedrive/{{item.id}}">{{ item.name }}</a>
</td>
<td>{{ item.file ? (item.size | bytes) : ''}}</td>
<td>{{ item.createdDateTime | date:'medium' }}</td>
<td>{{ item.createdBy.user.displayName }}</td>
</tr>
</tbody>
</table>
</div>

Навигация сверху и таблица под ней:

Предыдущий урок СОДЕРЖАНИЕ Следующий урок

Виктория Пряжникова


2016-12-06 • Просмотров [ 101 ]