How to assign role to newly created user - coffeescript

I am using meteor-roles packages and statically it creates the user admin#example.com, normal#example.com,.....
NOw I have a signup pages where the user can sign up.Initially I create the account by following code in client side, i am using coffeescritp:
Accounts.createUser
email: email
password: password
By doing these I can create the new user. Now how do I assign the role to that newly created user. I have roles- admin, normal, manage-users.
When doing these
id = Meteor.userId()
roles = "admin"
Roles.addUsersToRoles id, roles
I get the error "Exception while delivering result of invoking 'createUser' Error {} Error: Missing 'users' param
How can I assign the role dynamically.
Thank you in advance.!!!

You can only use Meteor.userId() if the user ID you are assigning the role(s) too is the current user. You would need to call Meteor.userLoginWith*() before trying to use Roles.addUsersToRoles(Meteor.userId(), roles).
I would suggest creating the user, assigning the roles, and then logging them in. If you log the user in prior to assigning an appropriate role, role-specific routes, allow functions, and publish functions may not behave properly.
I would suggest creating the user:
var userId = Accounts.createUser({
username: 'username',
email: 'email#email.com',
password: 'passwordString',
profile: {}
});
And then adding the user to the appropriate role:
var roles = ['admin', 'roleName'];
Roles.addUsersToRoles(userId, roles);
Then finally logging them in, after the role(s) has been assigned.

Related

Keycloak ignores realmRoles when adding a user by rest api

When I am creating a new user by using Keycloak rest API, the application ignores the realmRoles property not assigning the role to the new user.
Here is an exemple
POST: https://localhost:8543/auth/admin/realms/quarkus/users
Body:
{
"username":"alexandre",
"enabled":true,
"emailVerified":true,
"firstName":"Alexandre",
"lastName":"Oliveira",
"email":"alexandreqogmailcom",
"credentials":[
{
"type":"password",
"value":"123456",
"temporary":false
}
],
"realmRoles":[
"user_esc"
],
"access":{
"mapRoles":true
}
Is there a way to resolve this problem or a work around ?
PS: I am using the keycloak version 12.0.1
If you are expecting that with the endpoint:
POST: https://localhost:8543/auth/admin/realms/quarkus/users
it will also create the realm roles, that will not happen, it will not create the Realm roles. To create the Realm roles you either use the Admin Console or you use the endpoint:
POST https://localhost:8543/auth/admin/realms/quarkus/roles
with the payload
{"name":"<ROLE_NAME>","description":"<DESCRIPTION>"}
if it is a non Composite Realm Role.
To assign the Realm Role to the user, after having create the user, call the endpoint:
POST: https://localhost:8543/auth/admin/realms/quarkus/users/<USER_ID>/role-mappings/realm
with the payload
[{"id":"<Role ID>","name":"<Role Name>"}]
The role ID you can get it from:
GET: https://localhost:8543/auth/admin/realms/quarkus/roles/<ROLE_NAME>
and the user ID from :
GET: https://localhost:8543/auth/admin/realms/quarkus/users/?username=<USERNAME>
I have upload the following bash scripts to automatize this process.

Why doesn't Accounts.createUser create a user in MongoDB?

I'm using accounts-password package to manage my user accounts. I tried 2 ways to create account using Accounts.createUser() function.
1st way: Calling Accounts.createUser() from the client
register.js:
Template.register.events({
"submit form"(event){
event.preventDefault();
const email = event.target.email.value;
const password = event.target.password.value;
Accounts.createUser({
email: email,
password: password
});
}
});
2nd way: Calling Accounts.createUser() from the server method and calling that method from the client. Got the hint after going through: Meteor: Accounts.createUser() doesn't create user
register.js:
Template.register.events({
"submit form"(event){
event.preventDefault();
const email = event.target.email.value;
const password = event.target.password.value;
Meteor.call('createNewUser', email, password);
}
});
methods.js:(on server)
Meteor.methods({
'createNewUser'(email, password){
Accounts.createUser({
email: email,
password: password
});
}
});
In both the cases, no new collection is created in MongoDB. Neither is any old collection updated. My connection strings are proper. Why is this happening?
However, when I use the following on the server, a document is created:
Accounts.users = new Mongo.Collection("profiles", {
_preventAutopublish: true, _driver: dbConn
});
Meteor.users = Accounts.users;
I don't know why a new collection has to be created for this to work. Isn't accounts-password package supposed to create a collection by itself?
if you are just keen on getting a basic version up and running try adding the default {{>loginButtons}} to your html. This will also make sure the javascript is executed as it should be. Building the js manually only makes sense if you need more customizability.
Have you added the accounts-base package? Accounts.createUser comes from this package. (docs)
In the linked example you gave, the OP had set forbidClientAccountCreation: true in the Accounts.config(). That prevents the Accounts.createUser function from working on the client (which is useful in applications where users need an invitation to register). That is why the answers recommended to create the user account server side and isn't applicable to your application.
As a side note, in your second example you are passing an unencrypted password from the client to the server which is considered dangerous.
You can encrypt it before sending it to the server method like so:
const password = Accounts._hashPassword( event.target.password.value );
_driver: dbConn
That line is really concerning. Are you trying to manage your own database connection?
There's nothing wrong with the code you wrote, it's not your problem. Accounts.createUser is the correct method to call.
If you need to use a different database than the one initialized by default by running the meteor command from terminal, look at the documentation on using MONGO_URL.

MembershipReboot with IdentityServer v3

I am having trouble extracting UserAccount properties from MembershipReboot in conjunction with Thinktecture IdentityServer. I have both up and running using the Sample repo here: https://github.com/identityserver/IdentityServer3.MembershipReboot
When I request the "openid profile" scope in an Implicit Grant Flow, I am missing a lot of the user account fields such as "given_name, middle_name", etc from the id_token and response from the userinfo endpoint. I understand this is because they need to be assigned in the GetClaimsFromAccount function.
I can see the requestedClaims come into the GetProfileDataAsync() function in the MembershipRebootUserService class and if I hover over the instance of TAccount in GetClaimsFromAccount I can see the Firstname, Lastname, etc properties appearing in the CustomUser dynamic proxy but I can't for the life of me work out how to access them and copy them into the claims collection?
More Info:
I suspect the issue is with this line:
claims.AddRange(userAccountService.MapClaims(account));
It looks like this should be converting the user account properties into claims but I dont get any back.
The way I understand it works is you add an option to your Scope object to return all of the claims for a user. IncludeAllClaimsForUser is the key property.
e.g.
new Scope
{
Enabled = true,
Name = "roles",
Type = ScopeType.Identity,
IncludeAllClaimsForUser = true,
Claims = new List<ScopeClaim>
{
new ScopeClaim("role")
}
}
My request includes the role property as well. This pulled back all the claims for the user from MR for me. My example is with Implicit flow btw.

Bootstrap a grails app with dummy data when spring security facebook is involved

I've created a grails app that uses spring security to allow a user to authenticate via facebook, and I can successfully print out the facebook username onto one of the views, so thus far I don't have any issues.
My problem lies when trying to bootstrap my application with some sample data for my given facebook user, so I don't have to enter it every time the application starts up.
This is how I'm trying to bootstrap my own facebook account, I have the following in Bootstrap.groovy :
def adminRole = new AppRole(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new AppRole(authority: 'ROLE_USER').save(flush: true)
def testUser = new AppUser(username: 'facebook_563645402', enabled: true,
password: 'my-hashed-pw-here',
surveys: [jamies])
testUser.save(flush: true)
AppUserAppRole.create testUser, adminRole, true
For the record, I've added a hasMany for the surveys field mentioned above onto AppUser.
When I fire up the app and try to connect, I get the following error :
URI
/web/j_spring_security_facebook_check
Class
grails.validation.ValidationException
Message
Validation Error(s) occurred during save(): - Field error in object 'web.AppUser' on field 'username': rejected value [facebook_563645402]; codes [web.AppUser.username.unique.error.web.AppUser.username,web.AppUser.username.unique.error.username,web.AppUser.username.unique.error.java.lang.String,web.AppUser.username.unique.error,appUser.username.unique.error.web.AppUser.username,appUser.username.unique.error.username,appUser.username.unique.error.java.lang.String,appUser.username.unique.error,web.AppUser.username.unique.web.AppUser.username,web.AppUser.username.unique.username,web.AppUser.username.unique.java.lang.String,web.AppUser.username.unique,appUser.username.unique.web.AppUser.username,appUser.username.unique.username,appUser.username.unique.java.lang.String,appUser.username.unique,unique.web.AppUser.username,unique.username,unique.java.lang.String,unique]; arguments [username,class web.AppUser,facebook_563645402]; default message [Property [{0}] of class [{1}] with value [{2}] must be unique]
Which appears to complain about the username not being unique.
If by trying to bootstrap some data breaks the unique constraints on the facebook username, how can I possibly ever pre define any data for a user?
A quick Googling brings up a few suggestions (link1, Grails spring security bootstrap, but so far they haven't helped, any ideas?
EDIT:
Delving deeper into the error that grails reports, I can see that the root of the above error is located in DefaultFacebookAuthDao, line 135, which mentions the following :
AppUserDomainClazz.withTransaction {
appUser.save(flush: true, failOnError: true)
}
So, by authenticating, spring security attempts to save a user domain object...
EDIT 2 :
This is my Bootstrap.groovy
def testUser = new AppUser(username: 'facebook_563645402', enabled: true,
password: 'my-hashed-pw', surveys: [new Survey(1)])
testUser.save()
def fbUser = new FacebookUser(uid: 563645402)
fbUser.save(flush: true)
Both FacebookUser and AppUser were generated via the spring security facebook quickstart, with the only change being to add static hasMany = [surveys: Survey] to AppUser.
It looks like the data has already been predefined, otherwise there wouldn't be a unique constraint violation. Just check for the existence of the data and only create it if needed:
def adminRole = AppRole.findOrSaveByAuthority('ROLE_ADMIN')
def userRole = AppRole.findOrSaveByAuthority('ROLE_USER')
String username = 'facebook_563645402'
if (!AppUser.findByUsername(username)) {
def testUser = new AppUser(username: username, enabled: true,
password: 'my-hashed-pw-here')
testUser.addToSurveys(jamies)
testUser.save()
AppUserAppRole.create testUser, adminRole, true
}
Spring Security Facebook tries to create a new user with same username (facebook_563645402). Because it cannot find it by uid.
As I see from you code, you just create an user, with filled username, but it's not a facebook user, and uid field isn't filled. So, the plugin cannot find any facebook user and tries to create a new one, using 'facebook_563645402' username by default.
There two ways: or change username for user created in Bootstrap (if it's not a facebook user), or create a Facebook User also (will be used for authentication).

grails spring-security create user

Im having some problems creating new user from one of my controllers. I'm trying to add a new user to my MongoDB user collection like this. Authorities is defined as a Set of Role in the domain.
Role role = new Role(authority:"ROLE_USER")
User user = new User(username:params.username,email:params.email,password:params.password,enabled:params.enabled,
accountExpired:params.accountExpired,accountLocked:params.accountLocked,passwordExpired:params.passwordExpired,
authorities:[role])
if (user.validate()) {
user.save(flush:true)
} else {
user.errors.allErrors.each { println it }
}
The exact same code is able to create a user successfully from the bootstrap, but when i'm trying to do the same thing from a simple controller i'm getting this error:
2012-09-24 10:43:27,450 [http-8080-3] ERROR binding.GrailsDataBinder - Unable to auto-create type interface java.util.Set, class java.lang.InstantiationException thrown in constructor
a:662)
Looks like the problem is with data binding. You have to create User with authorities first and then add role using UserRole domain. Something like:
Role role = Role.findByAuthority("ROLE_USER")
User user = new User(username:params.username,email:params.email,password:params.password,enabled:params.enabled, accountExpired:params.accountExpired,accountLocked:params.accountLocked,passwordExpired:params.passwordExpired)
new UserRole(user: user, role: role).save(flush: flush, insert: true)
user.save(flush:true)
For more information how to create user with spring security, you may want to look at Spring Security UI