Adding new roles JHipster and MongoDb - mongodb

I'm creating application using JHipster and MongoDb and I'm trying to add new roles.
I added new constants to security/AuthoritiesConstants but in my collection jhi_authorities I'm not seeing changes.
Is anybody knows how to add my new role to this collection?

You must also add your new authorities to MongoDb, see InitialSetupMigration.java, either add them here or create a new migration.
See doc

Create new #ChangeLg and write method with #ChangeSet
Like this example
#ChangeLog(order = "002")
public class AddOthersAuthorities {
#ChangeSet(order = "01", author = "initiator", id = "03-addOthersAuthorities")
public void addAuthorities(DB db) {
DBCollection authorityCollection = db.getCollection("jhi_authority");
// Role for super administration
authorityCollection.insert(
BasicDBObjectBuilder.start()
.add("_id", "ROLE_SUPER_ADMIN")
.get());
// Role for company administration
authorityCollection.insert(
BasicDBObjectBuilder.start()
.add("_id", "ROLE_COMPANY_ADMIN")
.get());
// Role for branch administration
authorityCollection.insert(
BasicDBObjectBuilder.start()
.add("_id", "ROLE_BRANCH_ADMIN")
.get());
// Role for employee
authorityCollection.insert(
BasicDBObjectBuilder.start()
.add("_id", "ROLE_EMPLOYEE")
.get());
// Role for registred customer
authorityCollection.insert(
BasicDBObjectBuilder.start()
.add("_id", "ROLE_CUSTOMER")
.get());
// Role for non registred customer
authorityCollection.insert(
BasicDBObjectBuilder.start()
.add("_id", "ROLE_GUEST")
.get());
}
}

Related

AEM 6.3 Cannot create groups with service user

Hoping someone on here can help me out of a conundrum.
We are trying to remove all Admin sessions from our application, but are stuck with a few due to JCR Access Denied exceptions. Specifically, when we try to create AEM groups or users with a service user we get an Access Denied exception. Here is a piece of code written to isolate the problem:
private void testUserCreation2() {
String groupName = "TestingGroup1";
Session session = null;
ResourceResolver resourceResolver = null;
String createdGroupName = null;
try {
Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "userManagementService");
resourceResolver = resourceResolverFactory.getServiceResourceResolver(param);
session = resourceResolver.adaptTo(Session.class);
// Create UserManager Object
final UserManager userManager = AccessControlUtil.getUserManager(session);
// Create a Group
LOGGER.info("Attempting to create group: "+groupName+" with user "+session.getUserID());
if (userManager.getAuthorizable(groupName) == null) {
Group createdGroup = userManager.createGroup(new Principal() {
#Override
public String getName() {
return groupName;
}
}, "/home/groups/testing");
createdGroupName = createdGroup.getPath();
session.save();
LOGGER.info("Group successfully created: "+createdGroupName);
} else {
LOGGER.info("Group already exists");
}
} catch (Exception e) {
LOGGER.error("Error while attempting to create group.",e);
} finally {
if (session != null && session.isLive()) {
session.logout();
}
if (resourceResolver != null)
resourceResolver.close();
}
}
Notice that I'm using a subservice name titled userManagementService, which maps to a user titled fwi-admin-user. Since fwi-admin-user is a service user, I cannot add it to the administrators group (This seems to be a design limitation on AEM). However, I have confirmed that the user has full permissions to the entire repository via the useradmin UI.
Unfortunately, I still get the following error when I invoke this code:
2020-06-22 17:46:56.017 INFO
[za.co.someplace.forms.core.servlets.IntegrationTestServlet]
Attempting to create group: TestingGroup1 with user fwi-admin-user
2020-06-22 17:46:56.025 ERROR
[za.co.someplace.forms.core.servlets.IntegrationTestServlet] Error
while attempting to create group. javax.jcr.AccessDeniedException:
OakAccess0000: Access denied at
org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:231)
at
org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:212)
at
org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.newRepositoryException(SessionDelegate.java:670)
at
org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:496)
Is this an AEM bug, or am I doing something wrong here?
Thanks in advance
So it seems the bug is actually in the old useradmin interface. It was not allowing me to add my system user into the admninistrators group, but this is possible in the new touch UI admin interface.

MongoDB Program New Database Authentication Fails

I have a remote tenant database application using MongoDB with authentication enabled. During run-time, I have to programmatically create a new tenant database, create a new tenant database user, create a new collection, and write to the new database with user metadata. My problem is that I am not setting up the tenant user authorization correctly. I am able to create the new tenant database and a database user with role credentials "readWrite". I also can correctly write the document to the "users" collection. If I use my admin credentials, I can access the Tenant database and examine the users document with no issue. However, if I try to later access the database with the newly created database user credentials I get an incorrect user credentials exception. Below is my code that creates the new tenant database,
MongoCredential adminCredentials = MongoCredential
.createCredential(adminuid, admindb, adminpw.toCharArray());
ServerAddress adminSA = new ServerAddress(mongoConnectionUri, mongoPort);
// Create the Mongo Password Vault Client & Document Template
MongoClient adminclient = new MongoClient(adminSA, Arrays.asList(adminCredtials)):
MongoClient adminclient MongoClient(adminSA,Arrays.asList(adminCredentials));
DB tenant = adminclient.getDB(tenantdb);
// Create pwvdb user
DBObject pwvdbrole = new BasicDBObject();
pwvdbrole.put("role", pwvrole);
pwvdbrole.put("db", pwvdb);
ArrayList<DBObject> pwvdbroles = new ArrayList<DBObject>();
pwvdbroles.add(pwvdbrole);
DBObject pwvaultcmd = new BasicDBObject();
pwvaultcmd.put("createUser", pwvuid);
pwvaultcmd.put("pwd", pwvpw);
pwvaultcmd.put("roles", pwvdbroles);
CommandResult result = tenant.command(pwvaultcmd);
if (result.ok()) {
System.out.println("Tenant Credentials: OK");
} else {
System.out.println("Tenant Credentials Error: " +
result.getErrorMessage());
}
// Create users Collection
DBCollection tenantCollection =
tenant.getCollection(tenantcollection);
// Create user default credentials & update user collection
BasicDBObject userdocument = new BasicDBObject();
userdocument.put("firstname", userfirstname);
userdocument.put("lastname", userlastname);
userdocument.put("email", useremail);
userdocument.put("username", username);
userdocument.put("password", pwencoder.encode(userpassword));
userdocument.put("role", Integer.parseInt(userrole));
// Create admin web portal users uid/pw
tenantCollection.insert(userdocument);
pwvclient.close();
Because the client is remote, I use my admin userid, pw, and db for the credentials. However, the MongoDB tenant client is setup using the new tenant database name. This is probably where I am going wrong but I don't know how to remotely access the database with a user I have not created yet. These databases are created at run time and I do not know the name of the tenant user when the application starts.
there are two different places for user permissions to be created, which can be confusing. Both can be done dynamically in your code.
User roles in tenant DB
The easiest option is for you to create the user you want in the tenant DB. You should use the runCommand call with the document structure for the createUser command documented here. You would create this user in the tenant DB. The role should be readWrite or any others documented.
Then later you would authenticate for the user and password for that same DB.
You can also centralize all of your user management in the Admin DB with each createUser call enumerating the roles for each DB/role pair you want. Let me know if you need that explanation. It works basically the same way to create users there and authenticate against that DB also. Then you switch to the DB you want to access on the same MongoClient.
I could not post 2 other helpful links because of strange limitation on posting more than 2 links if I am not an active enough poster (10 reputation).
Here is what I did to get it to work. The two key things I want to point out is the adminops and testops MongoDB templates. Notice that in adminops I used my MongoDB admin credentials but pointed to the testdb. In testops I used my new testdb credentials and point to testdb as well. My error was with adminops. I used the admindb which was incorrect. Also getting the roleobj and cmd was a little tricky but I eventially figured it out.
package com.belcan;
import java.util.ArrayList;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
#SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class PreConfigTestApplication implements CommandLineRunner {
public static void main(String[] args) {
// Fire off Spring Boot & Embedded Linux
SpringApplication.run(PreConfigTestApplication.class, args);
}
#Override
public void run(String...args) throws Exception {
String testdb = "testdb";
String testuid = "skm";
String testpw = "password";
// Set up credentials
MongoCredential admincredentials = MongoCredential
.createCredential(adminuid, admindb, adminpw.toCharArray());
ServerAddress adminsa = new ServerAddress(mongoConnectionUri, mongoPort);
// Create the Mongo Client & Document Template
MongoClient adminclient = new MongoClient(adminsa,Arrays.asList(admincredentials));
MongoOperations adminops = new MongoTemplate(adminclient, testdb);
// First create new user
DBObject roleobj = new BasicDBObject();
roleobj.put("role", "readWrite");
roleobj.put("db", "testdb");
ArrayList<DBObject> array = new ArrayList<DBObject>();
array.add(roleobj);
DBObject cmd = new BasicDBObject();
cmd.put("createUser", testuid);
cmd.put("pwd", testpw);
cmd.put("roles", array);
// Create new User
CommandResult result = (CommandResult) adminops.executeCommand(cmd);
// check to see if command is ok
if (result.ok()) {
System.out.println("createUser Command: OK");
} else {
System.out.println("createUser Error:" + result.getErrorMessage());
}
// switch to testdb
MongoOperations testops = new MongoTemplate(adminclient, testdb);
// Create the user object
User user = new User();
user.setFirstname("mickey");
user.setLastname("mouse");
user.setEmail("mmouse#gmail.com");
user.setUsername("mmouse");
user.setPassword("mmouse1");
user.setRole("USER");
user.setStatus("ACTIVE");
// Now save it
testops.save(user, "users");
// Close Database Connection
adminclient.close();
//
// Now see if we can open the file with the new uid/pw
//
// Set up credentials
MongoCredential testcredentials = MongoCredential
.createCredential(testuid, testdb, testpw.toCharArray());
ServerAddress testsa = new ServerAddress(mongoConnectionUri, mongoPort);
// Create the Mongo Client & Document Template
MongoClient testclient = new MongoClient(testsa,Arrays.asList(testcredentials));
MongoOperations myops = new MongoTemplate(testclient, testdb);
User myuser = new User();
myuser.setFirstname("Daffy");
myuser.setLastname("Duck");
myuser.setEmail("dduck#gmail.com");
myuser.setUsername("dduck");
myuser.setPassword("dduck1");
myuser.setRole("USER");
myuser.setStatus("ACTIVE");
// Now save it
myops.save(myuser,"users");
// Lets print it out
System.out.println("Print Results");
ArrayList<User> userout = (ArrayList<User>) myops.findAll(User.class, "users");
for (int i = 0; i < userout.size(); i++) {
System.out.println(userout.get(i));
}
System.out.println("\n\nAll Done....");
// Close the database
testclient.close();
}
// MongoDB Connection URI
#Value("${spring.data.mongodb.uri}")
private String mongoConnectionUri;
// MongoDB Connection Port
#Value("${spring.data.mongodb.port}")
private int mongoPort;
// MongoDB userid
#Value("${mongo.server.admin.db}")
private String admindb;
// MongoDB admin password
#Value("${mongo.server.admin.pw}")
private String adminpw;
// MongoDB admin userid
#Value("${mongo.server.admin.uid}")
private String adminuid;
}

Cleaning an Access Team Record in CRM

I have to clean/to empty an access team record based on an Access team template.
How can I remove all users in the access team record in one shot? or Getting the list of users and then call RemoveUserFromRecordTeamRequest() for each user?
Here is the solution:
internal void CleanAccessTeam(IVisibilityService service, Guid recordId)
{
QueryExpression query = new QueryExpression(CrmTeam.EntityLogicalName);
FilterExpression filter = new FilterExpression();
filter.Conditions.Add(new ConditionExpression(CrmTeam.Lookups.RegardingObjectId, ConditionOperator.Equal, recordId));
query.Criteria.AddFilter(filter);
var teams = service.RetrieveMultipleRecord(query);
if (teams.Entities.Count > 0)
{
service.Delete(CrmTeam.EntityLogicalName, teams.Entities[0].Id);
}
}

How to get OObjectDatabaseTx from ConnectionPool?

According OrientDB official doc, I should create Connection Pool with Object API with following code.
// OPEN THE DATABASE
OObjectDatabaseTx db= OObjectDatabasePool.global().acquire("remote:localhost/petshop", "admin", "admin");
However, I found that OObjectDatabasePool class has been deprecated and suggested to use com.orientechnologies.orient.core.db.OPartitionedDatabasePool instead.
But in that way, how can I get OObjectDatabaseTx object? That is because OPartitionedDatabasePool.acquire() can only return ODatabaseDocumentTx object.
Hope there are someone knows how to resolve it.
Thanks
With this code you can get "object to connect to" and then make queries etc.
GET DOCUMENT DB
String remote = "remote:localhost/";
String nameDB = "domain";
String url = remote + nameDB;
OPartitionedDatabasePool pool = new OPartitionedDatabasePool(url, "admin", "admin");
ODatabaseDocumentTx db = pool.acquire();
//use example
List<ODocument> resultset = db.query(new OSQLSynchQuery<Object>("select from ORole"));
for(ODocument doc:resultset) {
System.out.println(doc);
}
db.close();
GET OBJECT DB
String remote = "remote:localhost/";
String nameDB = "TestPartitioned2";
String url = remote + nameDB;
OServerAdmin serverAdmin = new OServerAdmin(url).connect("root", "root");
serverAdmin.createDatabase(nameDB, "object", "plocal");
System.out.println(" Database '"+nameDB +"' created!..");
OPartitionedDatabasePool pool = new OPartitionedDatabasePool(url, "admin", "admin");
//object
OObjectDatabaseTx db = new OObjectDatabaseTx(pool.acquire());
db.getEntityManager().registerEntityClass(Person.class);
Person personA = db.newInstance(Person.class);
personA.setName("tennantA");
db.save(personA);
db.close();

ServiceStack: How to deal with user registration

I'm trying to understand how to create a SignIn/SignUp service with ServiceStack and my database of choice is MongoDB:
public class AppHost : AppHostBase
{
public AppHost() : base("My Web Services", typeof(WelcomeService).Assembly) {}
public override void Configure(Container container)
{
Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {
new BasicAuthProvider()
}));
Plugins.Add(new RegistrationFeature());
var connectionString = ConfigurationManager.ConnectionStrings["mongodb"].ConnectionString;
var mongoClient = new MongoClient(connectionString);
var server = mongoClient.GetServer();
var db = server.GetDatabase("auth");
container.Register<ICacheClient>(new MemoryCacheClient());
container.Register<IUserAuthRepository>(new MongoDBAuthRepository(db, true));
}
The code above works correctly... it connects to the MongoDB server and creates the user table in the auth database. So far so good... What I'm trying to understand is how the built-in registration service works. If you look at my code, I enabled the RegistrationFeature but when I try to invoke it with http://localhost/register I always get a NotImplementedException. Does this mean I have to implement it from scratch? Is there any additional package to install? How do I actually invoke the default registration feature?