How to display admin panel in frontend for non-admin users - wordpress-theming

I had been using a plugin called "Easy Author Image" to display and upload images as profile picture. This plugin actually triggers the "meta-upload.php" file in "wp-admin". When I log-in as admin in my frontend and upload a file, it works perfectly fine but when I tried using a non-admin role it didn't allow me to access the upload page. I tried the following code but still it didn't work.
function allow_nonadmin_uploads() {
if ( current_user_can('contributor') && !current_user_can('upload_files') ){
$jobseeker = get_role('contributor');
$jobseeker->add_cap('upload_files');
}
}
add_action('admin_init', 'allow_nonadmin_uploads');
add_action('init', 'allow_nonadmin_uploads');

Related

Google Apps Script does not load when embedded into iFrame

I am trying to embed my Google Apps Script WebApp into an iFrame on another domain but the webapp is not loaded and I only see a white screen. There is also no error in the webinspector.
The Webapp is published with: Execute as me and Access has anyone within Given Domain.
According to this I implemented my doGet method like this:
function doGet(e) {
return HtmlService
.createHtmlOutputFromFile('html/index')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
and the IFrame looks like this:
<iframe src="https://script.google.com/a/my_domain/macros/s/ADjidojcojv/exec" title="test" width="558" height="300"></iframe>
When the user is logged into Google the webapp is displayed. However when the user is not logged in a grey image with account.google.com refused to connect
I think the reason is that there is a redirect to the google sign in which does not allow to be displayed. Furthermore in this case there is also another redirect to a SAML SSO application. So when you normally sign in into google you will redirect to the SAML SSO login.
What are my options here?
[Edit]
I found someone with the exact same problem and one possible solution. Apparently there is no easy way of doing this...
When publishing web-apps with access: "anyone", it is needed for the end user to be logged in. Otherwise, the user is redirected to Google login page. Google's login page does not allow itself to be iframed. If you're logged in, the web app isn't redirected to Google's login page and this error doesn't appear, else it appears.
Possible solutions:
Warn users beforehand that they must login
Publish using access: "Anyone even anonymous"
If that's not possible, It is possible to detect whether the iframed page has window loaded or not using window.length(one of the few properties that is accessible cross origin), which will be 0 if page refused to connect and more than 0 in a web-app, because your page is iframed. Then it is possible to redirect the user to the login page.
<!DOCTYPE html>
<html>
<body>
body
<iframe
src="https://script.google.com/macros/s/[SCRIPT_ID]/exec"
>Loading
</iframe>
<script>
(() => {
console.log("loading page");
const f = document.querySelector("iframe");
f.onload = (e) => {
console.log("iframe onload");
const fw = f.contentWindow;
if (fw.length > 0) console.info("logged in");
else {
alert("Please Login!");
window.location = "https://accounts.google.com";
}
};
})();
</script>
</body>
</html>
References:
Same origin policy

Conflict of displayDialogAsync and html5-history-api

I have an application by mean-stack that hosts a website and an Excel add-in. html5 is enabled, and it has
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script src="https://cdn.rawgit.com/devote/HTML5-History-API/master/history.js"></script>
In the Excel add-in, I have a button that opens a page in the website by Dialog API:
$scope.openDialog = function () {
Office.context.ui.displayDialogAsync("https://localhost:3000/preview/tmp/6wr-4PqdBrYQwjp3AAAD", {}, function () {})
}
When I click on this button in Excel Online in Chrome, it opens a dialog box with the following url (note that # and several %2F are systematically appended), but it does not prevent from well displaying the page.
https://localhost:3000/preview/tmp/6wr-4PqdBrYQwjp3AAAD?_host_Info=excel|web|16.00|en-us|b6f37f78-e519-7d03-0069-b9c4317a362c|isDialog#%2Fpreview%2Ftmp%2F6wr-4PqdBrYQwjp3AAAD%3F_host_Info=excel%7Cweb%7C16.00%7Cen-us%7Cb6f37f78-e519-7d03-0069-b9c4317a362c%7CisDialog
However, when I click on this button in Excel Online in Firefox, the url changes quickly to the following url, which turns out to display the homepage of the website:
https://localhost:3000/home#%2Fpreview%2Ftmp%2F6wr-4PqdBrYQwjp3AAAD%3F_host_Info=excel%7Cweb%7C16.00%7Cen-gb%7C919fff78-e51f-dc20-0c3c-871b7d0ec25d%7CisDialog
So my questions are:
1) Why does Office.context.ui.displayDialogAsync add systematically # and %2F to the url of my website? Is it possible to prevent this from happening?
2) Is it possible to make a url (regardless of # and %2F) that Firefox accept?
Edit 1: It seems that if I don't use html5-history-api, it will work. So does not know how to disable html5-history-api for that displayDialogAsync? (The reason why I have to use html5-history-api after office.js is here.)
It is not displayDialogAsync that is doing this. It is a frequent issue with Angular routing and Angular location strategy. Search for "angular app is adding hash to my urls" and you will find a lot of information about it and solutions.

Display HTML page stored in SharePoint documents folder

I'm working on a SharePoint web part that displays a number of different reports in different divs on the page. In one of these divs, I need to display the HTML from a page we have stored in the 'Documents' container within SharePoint. The info in the HTML page is retrieved from several different parts of the application, and is displayed differently, so basically we're using it as the source data. I'm trying to figure out how to access the page from within the app and hopefully store the link to the file as a configurable setting so I can set it up for our dev/test/prod environments.
I've loaded the HTML file into the 'Documents' folder, and if I browse to it manually it displays fine but if I use the following:
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (System.Net.WebClient client = new System.Net.WebClient())
{
string htmlCode = client.DownloadString(url);
}
}
I get a 403 error and in the response header the message, "Before opening files from this location you must first browse to the website and select the option to login automatically".
I thought the RunWithElevatedPriveleges would pass the credentials through but I'm pretty new to SharePoint. Not sure if I'm using the right approach, any help is appreciated.
Put the pages into a standard document library, then use the page viewer web part. The site asset library is used for other customization purposes. You don't even need SharePoint Designer. Page viewer should be set as a "Web Page" because the web page viewer becomes essentially an IFRAME.
If still trouble... it may be a setting at the Web Application level thats causing issues with non-Microsoft files
Go to Central Admin > Manage Web Applications. I then chose my Web Application and clicked on the "General Settings" button. I then changed the Browser File Handling from "Strict" to "Permissive" and that fixed my issue. I've included an attachment of the setting so you can read the text associated with it.
Figured it out. There were a number of permissions problems but once those were sorted this code worked:
using (SPSite site = new SPSite(SPContext.Current.Site.ID))
{
using (SPWeb web = site.OpenWeb())
{
SPFolder folder = web.GetFolder("MainFolder/Lists/MainFolderDocs");
if (folder.Exists)
{
SPFile file = web.GetFile("/MainFolder/Lists/MainFolderDocs/Mainlist.html");
if (file.Exists)
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(file.OpenBinaryStream()))
{
string htmlCode = reader.ReadToEnd();
lChecklist.Text = htmlCode;
}
}
}
}
}

Is it possible to get access to my chrome extension localStorage from my website?

I built a chrome extension that saves data to localStorage from the background page (using the chrome.storage.sync.set).
Now, say that I want to build a website and access to the extension's data on the localStorage from the website, is it possible to access this data from the website domain? maybe I can add something to the manifest file to allow that?
You would have to inject a content script into your web site and then have your background script pass the localStorage to your content script. As for communication between your content script and the script on your web site, you'll have to get creative.
I am assuming here that you are aware of the message passing procedures between the content script and background script.
Now, I don't think your website can make a request to the extension and "pull" data from it, but you can certainly have your extension "push" data to your website.
This is how you can do it:
Content Script
The content script should check if the site open in the website is your website, say www.yourwebsite.com
if (currentUrl == "www.yourwebsite.com")
{
....
}
If it is indeed your website, pull the required data from the background script
if (currentUrl == "www.yourwebsite.com")
{
chrome.extension.sendRequest({ "getLocalStorageData": true, "dataFieldName": "favouriteColor" }, handleLocalStorageResult);
}
function handleLocalStorageResult(dataValue)
{
.....
}
On receiving the data in method handleLocalStorageResult, inject the data into the page's html so that your website's javascript can read it
if (currentUrl == "www.yourwebsite.com")
{
chrome.extension.sendRequest({ "getLocalStorageData": true, "dataFieldName": "favouriteColor" }, handleLocalStorageResult);
}
function handleLocalStorageResult(dataValue)
{
var localStorageDataDiv = $('<div>').appendTo('body');
localStorageDataDiv.attr('id', 'extensionData');
localStorageDataDiv.html(dataValue);
}
Your WebSite's Javascript
Now your website's javascript can read the data
var data = $('#extensionData').html();
alert('My Extension's LocalStorage Data is ' + data);
Answers to date do not mention that content scripts and the webpage share their localStorage object. If your content script writes to localStorage, the webpage will be later able to read it, and vice versa.

Can I add a page tab app to a differenrt App profile page?

I wanted to know if I can add a page tab app I created to a different App profile page like I can add it to regular pages on Facebook. I can't see all my app profile pages(only regular pages are listed) when I click under a profile app page the link "Add to My Page".
Yes you can do that by visiting a link:
http://www.facebook.com/add.php?pages=1&api_key=APP_ID
This will bring you list of all pages (including application pages) you own, or you can specify directly which page should be used to add application to:
http://facebook.com/add.php?pages=1&api_key=APP_ID&page=PAGE_ID
If you want to do it using Graph SDK (in kind of background, silent mode - avoiding the user interaction), then you need to make a call like this
You need to get the manage_pages permission first, and then
if (accessToken) {
var data = {
"access_token": accessToken,
"app_id":applicationId
}
FB.api("/" + pageId + "/tabs", 'post', data, function(response) {
//success or failure, check it out
});
}
It will install the application on your application profile as a tab :)
Hope it will help.