Grant roles to mongo users via rails - ruby

I am trying to assign roles to mongo users through rails controller.
I know that we can assign roles to users as mentioned here, but there we need to update the whole user. So is there any way to run a query similar to grantRole directly through the rails controller?

db.grantRolesToUser is a shell helper. You can find out how it is implemented by typing its name in the shell but not invoking it:
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.grantRolesToUser
function(username, roles, writeConcern) {
var cmdObj = {
grantRolesToUser: username,
roles: roles,
writeConcern: writeConcern ? writeConcern : _defaultWriteConcern
};
var res = this.runCommand(cmdObj);
if (!res.ok) {
throw _getErrorWithCode(res, res.errmsg);
}
}
You can see that it uses runCommand.
The Ruby mechanism for running arbitrary commands is documented here.
You would then do something like:
client.database.command(grantRolesToUser: username, roles: ['foo'])
To get the client instance, use Foo.collection.client where Foo is a Mongoid model class.

Related

Parse Android: update ParseObject containing an array of ParseUsers throws UserCannotBeAlteredWithoutSessionError

im working on an Android App.
I have a custom class which has relations with TWO ParseUsers and other fields. As suggested by the docs, I used an array (with key "usersArray") to store the pointers for the two ParseUsers, because I want to be able to use "include" to include the users when i query my custom class. I can create a new object and save it successfully.
//My custom parse class:
CustomObject customObject = new CustomObject();
ArrayList<ParseUser> users = new ArrayList<ParseUser>();
users.add(ParseUser.getCurrentUser());
users.add(anotherUser);
customObject.put("usersArray", users);
//I also store other variable which i would like to update later
customObject.put("otherVariable",false);
customObject.saveInBackground();
Also, i can query successfully with:
ParseQuery<CustomObject> query = CustomObject.getQuery();
query.whereEqualTo("usersArray", ParseUser.getCurrentUser());
query.whereEqualTo("usersArray", anotherUser);
query.include("usersArray");
query.findInBackground( .... );
My problem is when trying to UPDATE one of those CustomObject.
So after retrieving the CustomObject with the previous query, if I try to change the value of the "otherVariable" to true and save the object, I am getting a UserCannotBeAlteredWithoutSessionError or java.lang.IllegalArgumentException: Cannot save a ParseUser that is not authenticated exceptions.
CustomObject customObject = customObject.get(0); //From the query
customObject.put("otherVariable", true);
customObject.saveInBackground(); // EXCEPTION
I can see this is somehow related to the fact im trying to update an object which contains a pointer to a ParseUser. But im NOT modifying the user, i just want to update one of the fields of the CustomObject.
¿There is any way to solve this problem?
Maybe late but Parse users have ACL of public read and private write so you should do users.isAuthenticated() to check if its true or false.
If false then login with the user and retry. Note: you cannot edit info on two users at the same time without logging out and relogging in.
Another thing you can do is use Roles and define an admin role by using ACL which can write over all users.

How to access Users in Mongo db console

I'm using Mongoid for Ruby. I have queried in my Mongo database before, but forget how it works with Mongo. I have a user model like so:
class User
include Mongoid::Document
field :email, type String
field :crypted_password, type String
...
end
How would I grab all the users or a specific user in my console? Thanks to anyone who can help
use *database
This returns a specific user:
db.getUser("*user")
This returns all users
db.getUsers()
If your class is called User then the underlying MongoDB collection will be users. So you'd say things like:
> db.users.find() // All users
> db.users.find({ field: value }) // Users that match certain conditions
> db.users.findOne({ _id: ObjectId('...') }) // Find one user with a specific id
...
See the find and findOne documentation for further details.

How to Persist data using session variable in mvc3 razor view?

I am working in MVC3 Application with Razor. In my Account controller after validating the user, i am getting the user ClientID from Database. Here i want to persist ClientID in Session variable. which was using across the all controller and Razor view.
I have no idea as to what is the best way to implement this.OR How to persist data in the session variable. And how to use persisted data in the session variable in across the controller.
Thanks for your help..
I usually write a Session wrapper that allows me easy access to it in the future:
public class SessionData
{
const string ClientId_KEY = "ClientId";
public static int ClientId
{
get { return HttpContext.Current.Session[ClientId_KEY] != null ? (int)HttpContext.Current.Session[ClientId_KEY] : 0; }
set { HttpContext.Current.Session[ClientId_KEY] = value; }
}
}
After that you can access it from anywhere like this:
int clientId = SessionData.ClientId;
If you want you can use whole objects in Session like this.
Or you can set it like so: SessionData.ClientId = clientId;
If you are using ASP.NET Forms Authentication, the user name is already stored in a cookie. You can access it from the Controller via
Controller.User.Identity.Name
It's possible to store the user ID as the user name. When you call something like
FormsAuthentication.RedirectFromLoginPage
Give it the ID instead of a name. The ID can then be found using the method above and no extra session data is necessary. If you want to store something in the session, just call
Session["UserID"] = value;
From your controller.

Something weird about express session store

If I store an object in session like this:
user.name = "Kelvin"; // user is an object pass by "mongoose" findOne's callback.
req.session.user = user;
console.log(req.session.user.name); // Kelvin
and after that, I access "user" in other routes of express:
app.get("/somepath", function(req, resp) {
console.log(req.session.user.name); // undefined
});
I want to know why req.session.user.name is undefined besides the function I set it?
After looking into mongoose source code I can say that this is because how mongoose models and session works. When you call req.session.user = user then req.session.user points to the object but actually the data needs to be stored somewhere (like memory or Redis).
In order to do that Express calls JSON.stringify(sess) and string is stored in memory. Here's where mongoose enters. Models are constructed in such a way, that when you stringify them only attributes predefined in Schema are included. So when you set req.session.user = user Express stringifies user (you loose name attribute) and saves the data. When you call req.session.user in another route Express parses stringified data and you obtain object without name attribute.
Now how to fix this? There are several ways.
Add name attribute to the Schema;
Define new literal object for user:
var newuser = { id: user.id, name : "Kelvin", pwd: user.pwd, etc. };
req.session.user = newuser;
Store name in another field: req.session.name = "Kelvin"; (the best solution imho)
By the way: You shouldn't hold the user object in session. What if some other user like administrator makes changes to the user object? You won't see them at all. I advice holding only the id of the user in session and make custom middleware to load user from DB and store it in request object.

Can I filter the Users returned by GetAllUsers based on a role they are in

I am trying to create an administration interface where users and roles (among other things) can be administered. I have a list of users who can be edited, deleted or viewed. I have this code in the action:
var model = Membership.GetAllUsers()
.Cast<MembershipUser>()
.Select(x => new UserModel
{
UserName = x.UserName,
Email = x.Email,
UserRoles = Roles.GetRolesForUser(x.UserName)
});
return View(model);
This is all fine except that I don't want admins to be able to edit each other. So I need to filter out all users in the "super admin" role. I can certainly figure this out by stepping through each role for each user to see if they are a member. I am wondering if there is a nice sucinct way to do this by filtering the result set in the Select statement, or using Except or Where
I would normally think about the sql I want generated then try write the linq, filtering by roles should be fairly easy with a simple where statement.
However it appears you're trying to abstract each part of the query into smaller bits, this may make it easier to write but can have a devastating effect on performance. For example, I wouldn't be suprised if the GetRolesForUser method you are calling causing an extra database query per user that is returned by GetAllUsers, using the Include method is a much nicer way to get all roles at the same time.
var model = context.Users
.Include(user => user.UserRoles)
.Where(user => !user.UserRoles.Any(role => role == superAdmin)
.Select(user => new UserModel() { UserName = user.UserName, Email = user.Email, UserRoles = user.UserRoles});

Resources