I am coding a Rest API with express and I have a middleware to check if a user is admin or not. However, I wonder how companies assign a new user as an admin? Do they edit the database record and change the role there?. I guess that one admin could make another user admin but how is the first admin created? Is there a way to do it in the frontend?
If it's a software platform (meaning one web address and database for all users of your app) then the first admin user is typically created by running commands on the server command line console to create the right record. Or perhaps by a setup script that is run once. This creates the first admin user, and then that user logs in and creates more admin users via the UI. This typically only ever needs to be done once in the entire lifetime of the project, so no need to have this be a user friendly process.
However, if it's a server you install your own instance of it's common to have a setup wizard, since each new install will need to go through this process, it's worth the effort to make something user friendly. You go to something like myapp.com/setup and then complete a few forms that sets up the first admin user and provides initial configuration and preferences. After this first admin user is setup this setup page would no longer be accessible, so that no other new admin users can be created that way.
Wordpress is a great example of the interactive setup. The end of this video has an example of what that looks like.
Usually when I'm in the midst of building my back-end I'll throw my own name into the user (model) via the users (routes) to test the puppy out.. i use Postman to inject my info into the endpoints points, then keep it there on the (mongo)db.. you could always use atlas to manual insert the user as well.
EDIT: my answer: use atlas to manually input a json file with the admin user of your clients (the company) choosing.
EDIT2: you've got me thinking... there could be an initialization state of the web-app where these things are declared; for example, say yo're creating an accounting management tool, in the first of a company initializing their new software you could request this information.
Related
I want to create an educational web app that, for specific reasons, I want someone to visit the website and immediately start using its functionality. It's not very high-stakes since it's educational, so security is not high-priority, but I'd like the app to be accessed by one user which they can later optionally sign in if needed.
E.g. if you use the app on your browser, you can continue using it there and your progress persists, without needing to log in, unless you need to transfer to a new device.
In my couchapp two databases are being used
1 Is for application data
2 Is "_users" database.
In my application In one form I'm trying to implement autocomplete where data source is a "view" created in "_users" database.
Now when I login with normal user id other than admin. While trying to access the view inside "_users" database I'm getting the error 403 which is :
{"error":"forbidden","reason":"Only admins can access design document actions for system databases."}
Is it possible for me to allow and limit the access for non admin users to that view only ? So I can get the list of users from _users database into my application.
I've never been able to do many tasks that require much custom with CouchDB by itself. I've always needed a script somewhere else that gives me the info that I need.
What works for me is this setup:
A gatekeeper Sinatra app that has admin access to my CouchDB
Using CouchDB's config to proxy to my Sinatra app. httpd_global_handlers _my_service {couch_httpd_proxy, handle_proxy_req, <<"http://127.0.0.1:9999">>}
The reason for the proxy is because any request that comes through to your gatekeeper will have the AuthSession token set. Inside your gatekeeper, you can GET localhost:5984/_session passing the AuthSession cookie along, it will tell you who is making the request, allowing you to look them up and see if they have access, or just give everyone access to whatever you like. Another reason for the proxy is to avoid any CORS nonsense since you're making the request to yourserver:5984/_my_service.
Update
A purely client-side/javascript solution means that it will be fundamentally insecure at some point, since well, everything is on the client-side. But perhaps your application, doesn't need to be that secure. That's up to you.
One workaround could be to make your application authenticate as a predefined admin, and then create more admin users that way. You could authenticate once when your application boots or on an as needed basis.
The "problem" is that CouchDB sees the _users database as fundamentally special, and doesn't give you the opportunity to change the credential requirements like other databases. Normally you would be able to use the _security document to give role based or user based access. But that's not possible with _users.
An alternative implementation might be to keep track of your own users and forgo the _users database altogether. In that case you could set your own cookies and have your own login and logout methods that don't depend on CouchDB's authentication scheme. You could query your own _view/users because it would be in your main database. Things wouldn't be locked down tight but they would work fine as long as no one was interested in hacking your system. :)
I'm currently working on a web application which deals with multiple users. Whilst it currently works, it relies on some real bad practises which I'll outline in a minute.
We're using MySQL as the database system, since we're updating our current application, we want to ensure everything is backwards compatible. Otherwise I'd look at MongoDB etc.
Our users are stored in a table aptly named login. This contains their username, email, hashed password etc and a field which contains a JSON encoded object of their preferences. There is no real reason for doing this over using a meta table.
So the bad practises:
We're storing the entire users login row, excluding their password (although this is an internal-only app) in a cookie. It's JSON encoded.
Once the user logs in we have a secure HTTP cookie, readable only via Node.js for their username and their password so that we can continue to keep the user logged in automatically.
We have a app.get('*') route which constantly ensures that the user has their three cookies and updates their acc cookie with new preferences. This means that every time the user switches page or accesses a new AJAX item (all under the same routes) they have an updated cookie.
Every time a user performs an action we do this to get their user id: JSON.parse(res.cookies.acc).agent_id yuck!
Now, each user is able to perform actions to certain elements on the page, this effects everyone as the application is internal and anybody can work on the data inside of it.
I know what I want to achieve and how it should be done in say PHP, but I can't figure out the most effective way in Node.js.
I've started creating a User module which would allow us to get the user who performed the action and neatly update their preferences etc. You can see this here bearing in mind that it's a WIP. The issue I'm having with the module is that it doesn't have access to the users cookies, since it's not "a part of" Express. Which explains the last bad practise.
What would be the best way to handle such a system and remain bad-practise free?
I doubt it meets all of your requirements but its worth checking out out Drywall; A website and user system for Node.js
Hopefully it (or parts of it) could be helpful to you.
http://jedireza.github.io/drywall/
I am trying to create a application using innoscript. I need to create/edit registry information values in HKLM. Hence I need admin privileges to install the application.
However, if a non admin user try to install the application, innoscript require admin user password, once they enter the admin user password, whenever I query the registry in installation script (say, HKCU), it retrieves information from the admin user. But I would like to get information from the currently logged in user. As a result, program installed under the admin user location instead of current logon user account.
Is there a way to get current logon user user and user app data location from innoscript, when the application is started with Run as administrator or prompted admin user.
Awaiting your update.
Thanks,
The installer is not supposed to read or modify any per-user state (including HKCU) during a per-machine installation (and there is no way to do so reliably). You should instead make the application itself do this on first run (by trying to read the appropriate location and assuming default values if they were not found).
Remember, an application is installed once, but can then be run by several different users. This behaviour is essential.
An easy workaround is to move your logic to an executable instead of Pascal script. Then you can call this executable in [Run] section,
http://www.jrsoftware.org/ishelp/index.php?topic=runsection
Remember to mark the Run item as runasoriginaluser.
CouchDB offers validation prior to allowing an object/row to be inserted into the database. This make sure that if you have a public facing couch application, you're database won't be filled with junk by just anyone.
User <-> CouchDB
However, I'm tring to figure out what that looks like comming from the standard application design process where you have a trusted middle layer that does much of the auth work. For example, most apps place Ruby or PHP between the database and user agent which allows the application to figure out information about the user agent before allowing something like a post to be saved to the database.
User -> Ruby -> MySQL
User <- Ruby <- MySQL
How do you trust the user to do administrative tasks when the user can't be trusted?
For example, how would you do something like "email verification" prior to inserting a user row using just couchDB? You can't let the user agent insert the row - because they would fill the system with spam accounts. On the other hand, there is no middle layer either that can insert the row after they click the link in the email.
How about this, I would assume that you would allow anyone to enter their email by creating a new record in a public table like email_verify. This is something that a public user agent could do as the table would not do anything in the application - it would just be a holding tank.
Then node.js could track the _changes feed and send an activation email while creating a new entry in a private table (like email_confirm) (node.js would serve as a trusted middle layer). If the user clicks that link and comes back then... [unknown] ... and node.js could finally create a record in the private user table (user).
At this point we could then rely on couchdb validation for the rest of the application since we got a confirmed user account created.
As more background lets imagine a discussion built on couchdb that anyone can register for. We don't want to allow just anyone to directly submit content without some kind of verification - yet the user agents all directly run the system. (Tables would be Thread, Comment, & User). How would this work?
I would think about adding roles to existing users in this issue.
Using couchdb's validation and changing _design/_auth can be a good idea to add email, email_verified and randomly generated email_verification_code in _users database when the user firsts registers.
To send mail, get confirmation, resend confirmation you can use external processes. (for an example usage of external process you can check couchdb-lucene).
And at last you can again do a quick check in _design/_auth in user update process if verification code matches and add verified_user role for that user.
This way all your requests would pass over couchdb, you would use external process only when you need to send mail and get confirmation.
Edit : Forgot to add (since it was pretty obvious), I would add verified_user role to database readers.
Couldn't you just make use of CouchDb's Validation ?
Users could be flagged. Upon registration, a User is added to the Users database. He gets his mail and then is flagged "valid:true" or something like this upon answering to that mail or clicking a link.
With validation users could not only be "logged in/out" but also access authorization can be implemented with more granular access rights. E.g.: Only mark threads solved if one is the author, admin, whatever...
Or does this seem impracticable?
After talking with some people on #couchdb IRC, it seems that they can't figure out out a way to do something administrative (like activation users that click on a email link) with out using a "backend" process like a node.js server which keeps track of the _changes feed.
I was hoping for a pure couchdb app - but it seems like couchdb still has a little ways to go.
Still, the good news is that you can hand off 80% of your applications logic/processing to your users. The other 20% will be 1) a node.js instance for things like sending emails or checking recaptcha and 2) record validation functions running in your couchdb, and 3) map/reduce (query) functions. These three things cannot be offloaded to something "untrusted" like a user-agent.