/// <summary> /// Creates a new instance of tenant app catalog context for some operations (Deploy, Retract, Remove). /// </summary> /// <param name="action">Current action.</param> /// <returns>A <see cref="PnPContext" /> instance.</returns> protected async Task <PnPContext> GetTenantAppCatalogContextIfNeededAsync(AppManagerAction action) { if (this is TenantAppManager && (action == AppManagerAction.Deploy || action == AppManagerAction.Retract || action == AppManagerAction.Remove)) { return(await GetTenantAppCatalogContextAsync().ConfigureAwait(false)); } else { return(context); } }
/// <summary> /// Generic method to execute an action like Deploy, Install, etc. /// </summary> /// <param name="id">A unique app id.</param> /// <param name="action">Action of type <see cref="AppManagerAction"/> </param> /// <param name="postObject">Optional dictionary with HTTP POST parameters.</param> /// <returns></returns> protected async Task <bool> ExecuteAppActionAsync(Guid id, AppManagerAction action, Dictionary <string, object> postObject = null) { var apiCall = new ApiCall($"_api/web/{Scope}appcatalog/AvailableApps/GetById('{id}')/{action}", ApiType.SPORest); if (postObject != null) { var jsonBody = JsonSerializer.Serialize(postObject); apiCall.JsonBody = jsonBody; } var pnpContext = await GetTenantAppCatalogContextIfNeededAsync(action).ConfigureAwait(false); return(await ExecuteWithDisposeAsync(pnpContext, async() => { await(pnpContext.Web as Web).RawRequestAsync(apiCall, HttpMethod.Post).ConfigureAwait(false); return true; }).ConfigureAwait(false)); }
protected override void GetContentFromMessage(List <byte> payload) { AppManagerAction messageType = (AppManagerAction)payload[0]; byte[] data = payload.ToArray(); //Get the app/watch guid byte[] AppGuid = new byte[16]; for (int i = 0; i < 16; i++) { AppGuid[i] = payload[i + 1]; } App = new Guid(AppGuid); //Get the bundle id BundleId.Add(payload[17]); BundleId.Add(payload[18]); BundleId.Add(payload[19]); BundleId.Add(payload[20]); }
private async Task <bool> BaseRequest(Guid id, AppManagerAction action, bool switchToAppCatalogContext, Dictionary <string, object> postObject, AppCatalogScope scope, int timeoutSeconds = 200) { var isCloned = false; var context = _context; if (switchToAppCatalogContext == true && scope == AppCatalogScope.Tenant) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); #pragma warning disable CA2000 // Dispose objects before losing scope context = context.Clone(appcatalogUri); #pragma warning restore CA2000 // Dispose objects before losing scope isCloned = true; } var returnValue = false; context.Web.EnsureProperty(w => w.Url); #pragma warning disable CA2000 // Dispose objects before losing scope var httpClient = PnPHttpClient.Instance.GetHttpClient(context); #pragma warning restore CA2000 // Dispose objects before losing scope httpClient.Timeout = new TimeSpan(0, 0, timeoutSeconds); var method = action.ToString(); var requestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps/GetByID('{id}')/{method}"; using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl)) { request.Headers.Add("accept", "application/json;odata=nometadata"); await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false); if (postObject != null) { var jsonBody = JsonSerializer.Serialize(postObject); var requestBody = new StringContent(jsonBody); if (MediaTypeHeaderValue.TryParse("application/json;odata=nometadata;charset=utf-8", out MediaTypeHeaderValue sharePointJsonMediaType)) { requestBody.Headers.ContentType = sharePointJsonMediaType; } request.Content = requestBody; } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { returnValue = true; } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } if (isCloned) { context.Dispose(); } return(await Task.Run(() => returnValue)); }
#pragma warning disable CA2000 private async Task <bool> BaseRequest(Guid id, AppManagerAction action, bool switchToAppCatalogContext, Dictionary <string, object> postObject, AppCatalogScope scope, int timeoutSeconds = 200) { var isCloned = false; var context = _context; if (switchToAppCatalogContext == true && scope == AppCatalogScope.Tenant) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); isCloned = true; } var returnValue = false; var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); if (string.IsNullOrEmpty(accessToken)) { context.SetAuthenticationCookiesForHandler(handler); } using (var httpClient = new PnPHttpProvider(handler)) { httpClient.Timeout = new TimeSpan(0, 0, timeoutSeconds); var method = action.ToString(); var requestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps/GetByID('{id}')/{method}"; using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl)) { request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Add("X-RequestDigest", await context.GetRequestDigestAsync().ConfigureAwait(false)); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } request.Headers.Add("X-RequestDigest", await context.GetRequestDigestAsync(handler.CookieContainer).ConfigureAwait(false)); } if (postObject != null) { var jsonBody = JsonSerializer.Serialize(postObject); var requestBody = new StringContent(jsonBody); if (MediaTypeHeaderValue.TryParse("application/json;odata=nometadata;charset=utf-8", out MediaTypeHeaderValue sharePointJsonMediaType)) { requestBody.Headers.ContentType = sharePointJsonMediaType; } request.Content = requestBody; } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { returnValue = true; } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } } if (isCloned) { context.Dispose(); } return(await Task.Run(() => returnValue)); }
public AppManagerMessage(AppManagerAction action, uint appId, uint appIndex) : this(action) { this._appId = appId; this._appIndex = appIndex; }
public AppManagerMessage(AppManagerAction action) : base(Endpoint.AppManager) { this._action = action; }
protected override void GetContentFromMessage(List <byte> payload) { const int AppInfoSize = 78; AppManagerAction messageType = (AppManagerAction)payload[0]; byte[] data = payload.ToArray(); switch (messageType) { case AppManagerAction.ListApps: byte[] numBanks = new byte[4]; byte[] numApps = new byte[4]; Array.Copy(data, 1, numBanks, 0, 4); Array.Copy(data, 5, numApps, 0, 4); if (BitConverter.IsLittleEndian) { Array.Reverse(numBanks); Array.Reverse(numApps); } uint appBanksAvailable = BitConverter.ToUInt32(numBanks, 0); uint appsInstalled = BitConverter.ToUInt32(numApps, 0); this.InstalledApplications = new InstalledApplications(appBanksAvailable); for (int i = 0; i < appsInstalled; i++) { byte[] id = new byte[4]; byte[] index = new byte[4]; byte[] name = new byte[32]; byte[] company = new byte[32]; byte[] flags = new byte[4]; byte[] version = new byte[2]; int offset = 1 + 8 + (i * AppInfoSize); Array.Copy(data, offset, id, 0, 4); Array.Copy(data, offset + 4, index, 0, 4); Array.Copy(data, offset + 8, name, 0, 32); Array.Copy(data, offset + 40, company, 0, 32); Array.Copy(data, offset + 72, flags, 0, 4); Array.Copy(data, offset + 76, version, 0, 2); if (BitConverter.IsLittleEndian) { Array.Reverse(id); Array.Reverse(index); Array.Reverse(flags); Array.Reverse(version); } int nameLength = Array.IndexOf(name, (byte)0); int companyLength = Array.IndexOf(company, (byte)0); this.InstalledApplications.ApplicationsInstalled.Add( new InstalledApplication() { Id = BitConverter.ToUInt32(id, 0), Index = BitConverter.ToUInt32(index, 0), Name = Encoding.UTF8.GetString(name, 0, nameLength), Company = Encoding.UTF8.GetString(company, 0, companyLength), Flags = BitConverter.ToUInt32(flags, 0), Version = BitConverter.ToUInt16(version, 0) }); } break; case AppManagerAction.RemoveApp: byte[] rawResult = new byte[4]; Array.Copy(data, 1, rawResult, 0, 4); if (BitConverter.IsLittleEndian) { Array.Reverse(rawResult); } this.Result = (AppManagerResult)BitConverter.ToInt32(rawResult, 0); break; } }
private async Task <bool> BaseRequest(Guid id, AppManagerAction action, bool switchToAppCatalogContext, Dictionary <string, object> postObject, AppCatalogScope scope) { var context = _context; if (switchToAppCatalogContext == true && scope == AppCatalogScope.Tenant) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); } var returnValue = false; var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { var method = action.ToString(); string requestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps/GetByID('{id}')/{method}"; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } request.Headers.Add("X-RequestDigest", await context.GetRequestDigest()); if (postObject != null) { var jsonBody = JsonConvert.SerializeObject(postObject); var requestBody = new StringContent(jsonBody); MediaTypeHeaderValue sharePointJsonMediaType; MediaTypeHeaderValue.TryParse("application/json;odata=nometadata;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; request.Content = requestBody; } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { var responseJson = JObject.Parse(responseString); returnValue = true; } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } return(await Task.Run(() => returnValue)); }