there are websites which create custom sessions for users, giving them unique link to the exact session user has created. E.g. it would like something like https/website.com/session/UniqueRandomID. I guess I understand how custom routes in ExpressJS work, but I'm not quite sure how can I allow a user to create those and later allow other users to connect only to those which have been already created..
Is there a common way of doing it and what may I be missing on the topic?
I tried searching the expressJS documentation.
The term "session" has a rather specific meaning in web site development (it refers to data associated with a given browser's visit to a site and is used for things like tracking the logged in state of a user) so I'll use the term "project" in this answer.
When the user creates a project, store all the information about that project in a database. Include, as part of this information an identifier. You probably want this to be a GUID or similar (there are libraries which will generates these for you) rather than something sequential (like an automatically generated database primary key).
The first page of the React Guide explains routing. Create a route that uses a route parameter for the project ID.
Use that project ID to get the data about the project from your database.
If there isn't any for that ID, return an error.
app.get('/projects/:projectId', async (req, res) => {
const projectData = await getProjectData(req.params.projectId);
if (projectData) {
return res.render('projectView', projectData);
}
res.sendStatus(404);
})
Related
I'm making a web app where users can create pages, edit them, and delete them. In developing the prototype, I have a user access a route such as:
localhost:8000/mypage/1
The "1" in the URL refers to the ID in the database, so that the controller can fetch the appropriate associated data and populate the page accordingly.
The obvious problem here is that a user can plug in any number to that URL and edit someone else's page.
One obvious fix would be to add logic that checks whether or not page '1' belongs to the Auth::user(). But this would be an if statement that I have to add to every controller that carries out such function.
When I think about other sites, they never have ID's in the URL, or if they do, they look 'encrypted' in some form. What is the best practice for changing an ID into some uninterpretable string that I frequently see done on other websites?
Thank you for any help.
why don't you just use a middleware that check if the route can be acceded by the user? then you can call it with
$this->middleware('middlewareName');
in the controller that you need it or even in the web.php if you want a whole set of routes protected
I made OnBeforeinitialize hook. I need place there code which register new user if user doesn't exists in database.
Which MediaWiki class and functions should be used?
If you need to create users, chances are you are doing something wrong. Users should be created on login/signup (use a PrimaryAuthenticationProvider to tell the system to create them), or when they are authenticated based on request data (use a SessionProvider). There is also User::newSystemUser but it's only meant for scripts.
Even if I don't know, what you really want to do, where the data for the user should came from, and why you want to do this in the BeforeInitialize hook (so, in fact, any useful information to really know and understand what you want to achieve is missing, therefore, you'll get an answer to your concrete question without any guarantee, that it works like you expected in your use case). However, to create a new user, you can use the createNew function of the User class. You should check, if the user is already present in the database.
EDIT:
An usage example:
$user = User::createNew( 'Testuser', [ 'email' => 'email_from#external_source.com' ] );
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!
I need to create my own REST API.
I just saw strongloop and loopback and I thought it will be perfect for my project.
In fact, I was able to get mysql connected using strongloop. However, I had to create something called a "model" and I did it. But, it was like creating a new model from scratch and use it for persisting on the Datasource.
Instead, what I was looking for, is to get a REST API directly from my model on the DB.
I mean taking the models from each table on the DB and then set them up as web services.
Is that possible?
I am newbie on these technologies, although I think it is an interesting question.
Thanks
I'm not sure of a Node tool to do what you're asking, but in other languages / databases you have some choices!
The only one I'm really familiar with is postgrest.
postgrest: You import your data into a Postgres database (similar to MySQL), and it generates a REST API on top of your tables instantly. Bam. Done. I've used this and it was amazingly awesome. You can also deploy it directly on Heroku.
StrongLoop actually has a "discovery" tool for just this purpose! Read up on that page, but here's the basic code to do it. Just drop this code in a file inside /server/boot/ (the docs are wrong on that, it must be in the directory I mention). Of course, you'll need to tailor it for your use case:
var loopback = require('loopback');
var ds = loopback.createDataSource('mysql', {
"host": "yourhost",
"port": 1234,
"database": "foobar",
"username": "someuser",
"password": "somepass"
});
// Discover and build models from a given table
ds.discoverAndBuildModels('PERSON', {visited: {}, associations: true},
function (err, models) {
// Now we have a list of models keyed by the model name
// You only need the rest of this if wanted to inspect what came in...
// For example, you could find the first record from the table
// and verify info or something.
models.Person.findOne({}, function (err, person) {
if(err) {
// handle this if need be...
console.error(err);
return;
}
// Some code using `person`
});
});
Good luck!
I was supposing "discovery tool" was to find out pattern, cluster or whatever else thing into the data. But following
the recomendation of #jakarella I went with more depth.
It was even easier than that, because you can do everything via StrongLoop Arc (GUI). I always prefer cli
but to have a general look of it, sometimes is better to start with the GUI if you don't have too much idea about the subject.
Anyway,
first of all you would need to connect your datasource before (installing previously the driver).
After that, through StrongLoop Arc you can do "discover the models" choosing your tables (taking care of run Arc and restarting every time
you get a new model) and that's it, you get an API over your Datasource
(for testing go to the explorer).
I described before generally the main tasks but if anyone needs more detail pls let me know. Hope this helps to anyone else who is looking to do
something similar
thanks guys for the interest.
I'm currently working on a platform which is planned to coordinate the communication with customers in future. Users can be added to projects and have certain rights. Therefore users are assigned to different user roles (admin/manager/member/viewer). Admins can view all projects and are allowed to add other users to a project. If a user (e.g. role:member) is added to a project, he will have certain rights (depending on the role), if not, he is not allowed to access the project at all.
I'm using Cake's ACL Component and everything is working great, when i disregard if a user is added to a project or not. The only solution I can think of, is not to grant rights on the group-level, but on the user-level when an admin adds an user to the project.
Is there an easier way to solve this issue? Otherwise I'm afraid that the code would become totally confusing.
There is a another way (I don't really know if easier, depends on your point of view). The ACL component only helps you to create roles, but you need a role and project-access management, right?
What I do in this cases:
Create a Project_Permission table in your database (give it a better name, I'm lacking imagination). Depending on your project, create the associations: a user can be related to many projects and a project can have many users accesing it. If you are following the cake conventions (and your tables are named users and projects) and it doesn't interfere with what you already have, the table should be
PROJECTS_USERS
id
project_id
user_id
created and modified //if you want to
Create appropriate actions where the admin (or other type if users, that's up to you)
can add users to projects and save that many-to-many association in
the previously created table.
Since the authorization for the project does not come from the ACL component, you have to create an "authorization" function yourself. I recommend putting this in the beforeFilter() function of the AppController (if you don't have an AppController, you'll have to do it in every controller you want this to work). In this function, check if the logged user is in the existing table and has an association with the project. Something like:
function beforeFilter() {
//let's assume you have the project id somewhere, in a global variable like $this->_projectID
$user = $this->Session->read('Auth.User.id');
$project = $this->Project->find('first', array('conditions'=>array('id'=>$this->_projectID, 'User.id'=>$user)
if (count($project) > 0) {
//the user has permission to see the project
} else {
//he doesn't
}
}
It's difficult to give an actual code because I'm not sure of your model associations nor where do you want the code or if you have the variables needed for this available everywhere, but I hope you get the idea. After that it's just a matter of how you want to handle the restriction of access (normally a flash message and redirection is involved).
I hope this is clear enough :S