Laravel 5.4 protected documents on user permission - laravel-5.4

I have a Laravel project where users have roles with permissions(I'm using
Zizaco/entrust) and the app is accessable just for registered user.
The application holds uploaded documents but this documents should not available for public view, on the other side this documents should be accessable in function of users permission.
My question: how to go in this case, how to protect documents in function of users permission?

I'm not sure if this will help, but you can create a special Controller for downloading/showing a document, where you can check permissions of a actual user.
From Entrust documentation, you can check if user should be able to see the document:
$user->hasRole('owner'); //returns boolean
So you can use this code from below in a Controller:
$user = User::where('username', '=', 'Mark')->first();
$pathToFile = Storage::get('file.pdf');
if ($user->hasRole('admin'))
{
return response()->download($pathToFile); //if you want to display a file, then change download to file
}
else
{
abort(403, 'Unauthorized action.');
}
Remember about adding this line to your controller:
use Zizaco\Entrust\Traits\EntrustUserTrait;
You can read more about responses here: https://laravel.com/docs/5.4/responses and files here: https://laravel.com/docs/5.4/filesystem
Look here for short syntax which will help you implement file downloads in routes.php without creating a new controller.
https://github.com/Zizaco/entrust#short-syntax-route-filter

Related

Reading from a protected page in MediaWiki with a Bot User

Using an admin user I created a dedicated user to own the bot; I added this bot to the 'Bots' group. With this user I logged in and created a BotPassword for my app, and have granted it every possible permission a Bot can have.
I have the following config options defined in my LocalSettings.php
$wgGroupPermissions['*']['read'] = false;
$wgGroupPermissions['bot']['read'] = true;
From my app, I get can successfully login using the Login API - after getting the tokens:
Logging In
{
"login": {
"result":"Success",
"lguserid":11,
"lgusername":"botuser#example.org"
}
}
However, using the following parameters to query for a page:
ArrayList<BasicNameValuePair> queryParameters = new ArrayList<>();
queryParameters.add(new BasicNameValuePair("action", "query"));
queryParameters.add(new BasicNameValuePair("prop", "revisions"));
queryParameters.add(new BasicNameValuePair("rvprop", "content"));
queryParameters.add(new BasicNameValuePair("format", "json"));
queryParameters.add(new BasicNameValuePair("formatversion", "2"));
queryParameters.add(new BasicNameValuePair("rvslots", "main"));
queryParameters.add(new BasicNameValuePair("titles", pageName));
I get the error:
{
"error": {
"code":"readapidenied",
"info":"You need read permission to use this module.",
"docref":"See https://wiki.example.org/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."
}
}
If I give global read permissions in LocalSettings,
$wgGroupPermissions['*']['read'] = true;
Then my bot user is able to fetch the pages without any errors -
How can I grant permissions to this bot such that I can query for the contents of a page without getting a readapidenied error, while still keeping my Wiki private? Is the BotPassword account in different groups then the main user? If so, how can I change the groups of the bot?
I am running MediaWiki: 1.32.0 on PHP: 7.2.16 and I use ImapAuthorization for user login.
You need to set in Special:BotPasswords what permissions the bot can access. The idea is that your bot password will be stored less securely than your real password (probably included in some bot config file on some shared server) so you'll want to limit what it can be used for.

Mediawiki AuthManager and SessionManager SSO

I am currently using 1.24.x and using LoginForm class and FauxRequest to login the remote (and create it locally if it doesn't exist) but this feature is being removed in 1.27.x so I am forced to write with a new standard using AuthManager and SessionMamager. I also will be upgrading to 1.31 as soon as LTS version of it comes out.
While reading, AuthManager and SessionManager, I just can't understand how can I authenticate external users. I also looked at the extension pluggableSSO which uses PluggableAuth but can't understand it as well.
Can someone please point me to a straightforward example of how can I authenticate a user if I have a user id and user name? and if that user doesn't exist, how can I create one and authenticate them locally?
Thanks
If someone like me who is very new to MediaWiki, there is a solution for SSO called PluggableAuth and Auth_Remoteuser.
I picked PluggableAuth which is implemented based on AuthManager and it is very easy to integrate.
All we need is to define a global variable $PluggableAuth_Class and implement the following methods in it:
public function authenticate( &$id, &$username, &$realname, &$email, &$errorMessage )
public function saveExtraAttributes( $id )
public function deauthenticate( User &$user )
More information can be found on:
PluggableAuth

Use built-in rbac or build own?

Following scenario:
I have a multi tenant web application in Yii2' advanced template.
This application has three portals:
- backend
- dashboard
- frontend
Each portal has its own user table for authentication.
(-frontend_user,
-dashboard_user,
-backend_user)
Frontend and dashboard can reached with the tenant's name at the end, e.g.:
When a user tries to login to dashboard or frontend I have to check if they have a right to login.
This happen via contingency table (e.g.: dashboard_user_tenant)
Now I want to build a rbac for the dashboard application.
But roles should not hang at the dashboard user but at dashboard_user_tenant (the contingency table),
because rights can change in each tenant's dashboard.
Yii2 has its own rbac system, but as I understand so far, it doesn't fit on my needs.
Any chances to customize Yii2's rbac or is it better to build my own custom solution? Maybe my own component?
I hope my description is clear enough :)
I had a similar desire in one of my projects, but I didn't create my own full RBAC system, instead I overwrote a way of checking for the roles
In my User component class, I extend the \yii\web\User, and also overwrite the can() function of that class. That lets me use my own way of checking for the appropriate permissions. For example
<?php
namespace app\modules\users\models;
use Yii;
use yii\web\User as WebUser;
use app\modules\users\models\UserPermissionManager;
class User extends WebUser
{
public function can( $operation, $params = [], $allowCaching = true )
{
if(Yii::$app->user->isGuest)
{
return false;
}
return ( new UserPermissionManager() )->has( $operation );
}
}
In the UserPermissionManager class, it queries a database table that is full of permissions such as "users:access", "users:edit", etc
They all have a certain user level assigned to them which relates to the user level I have set in my Users database table.
All the can() function needs to do is return true or false, depending on if this user has the permission to do what it's being asked. You can handle this however you like really.
It's quite a big system to explain fully in one post but I hope it's helped slightly, feel free to let me know if I can explain anything any better!

Not receiving "webViewLink" in response?

After turning on Google Drive API access from the management console and getting my Client ID keys, I followed the sample code (using Python 2.7) and I am able to insert a folder, set the appropriate permissions (type=anyone,role=reader), and insert a text/html type file into the new folder.
However the JSON file resource objects I receive from executing insert on the drive service have no 'webViewLink' field! There are 'webContentLink' and 'selfLink' fields but 'webViewLink', which is necessary for static HTML publishing, seems to be missing.
Most perplexing. If this feature hasn't been turned on yet or if I need to configure my account settings to allow HTML publishing please let me know. Any other help would be most appreciated ;)
The webViewLink property is only returned for public folders, and not the single files inside such folders. You can use that as the base url to construct links to your files.
The WebViewLink file property can be retrieved by doing something like this:
$file = $service->files->get($file_id, array('fields' => 'webViewLink'));
$web_link_view = $file->getWebViewLink();
OR
$sheetsList = $drive_service->files->listFiles([
'fields' => 'files(id, name, webViewLink, webContentLink)',
]);
$web_link_view = $sheetsList->current()->getWebViewLink();
Pay attention that you should load the file specifying which fields you wanna bring with it (In this case, webViewLink). If you don't do that, only id and name will be available.
If you also need to configure file permissions, you can do something like:
$permissions = new \Google_Service_Drive_Permission();
$permissions->setRole('writer');
$permissions->setType('anyone');
$drive_service->permissions->create($file_id, $permissions);
Possible values for setRole() and setType() can be found here: https://developers.google.com/drive/api/v3/reference/permissions/create

AS3.0 facebook api: getSession() returns null for user name

I'm starting a facebook app using iframe method.
I am using flex and so far I am able to connect to fb (login and out). Now I am trying to retrieve current logged in user name. In the document I see this function is what I need. Facebook.getSession().
A tutorial in adobe site uses desktop api and it works for desktop (AIR app) but not for web app. (yes, i fixed Facebook.getSession() instead of FacebookDesktop.getSession();
Also, I am able to see the uid but not the user. User returns null. I am guessing this is because uid is a string and user is an object. But on the desktop app, FacebookDesktop.getSession().user.name returns the name perfectly. but on the web, it does not.
Any help on this would be appreciated because I have been banging my head on this for 2 days.
It turns out that when you use FacebookDesktop to log in, it automatically makes an API call to the me object to get the information about the user. For some reason the Facebook class does not do this for you. In your login handler, you have make the call. So your login handler will contain something like:
if (success)
{
Facebook.api("/me", api_getMeHandler);
}
Once you get the /ME object you can directly read the user name:
protected function api_getMeHandler(result:Object,fail:Object):void{
// load name and birthday
var fbName:String="";
if( result.name != null) {
fbName = result.name;
bottomLabel.text = fbName + "Logged IN";
}
else {
bottomLabel.text = "User Name NULL";
}
}
I am working with the 1.5 Version, which includes the AS class wrapper for JS.