How can I get the current user in jHipster? - jhipster

Per other answers here my code below should be correct, but I am getting nothing from SecurityUtils. I need to assign a user to a new record in an application. Am I missing something here?
This other response also returns a null user.
User user = userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin().get()).get();
entity.setUser(user);
entityRepository.save(entity);

Related

Get highest role of a member with mentions

How can I get the highest role name of a mentioned member? I tried something like this but it doesn't work. Thanks! :) btw this is a ban command and I need this bc my bot is crashing when someone is trying to ban a user with a higher rank than bot.
if(message.member.hasPermission('BAN_MEMBERS')){
const user = message.mentions.users.first()
console.log(user.roles.highest.name)
if(!user) return console.log("test1")
if(!args[2]) return console.log("test2")
const ddays = args[1]
What you could do is:
Getting a user's highest role:
Get the UserId from the Mention inside of the Message
Get the Cache from the RoleManager of the Guild in which the Message was sent in
(I don't know if the roles in RoleCache are sorted by position, so sort if needed)
Iterate through the roles in RoleCache and check if the UserId is contained inside a specific role
Get the position of the role
Getting the bot's highest role:
Repeat steps 2-5 for your bot (or integrate them within the previous iteration of the RoleCache)
Then compare both numbers and find out if the bot's "role number" is higher than the one of the user's.

How to back to start wait new input-text in Dialogflow by using fulfillment?

Hi all,
I have question about control flow in Dialogflow. Is it possible to control Dialogflow in fullfillment?
Below are my Dialogflow Process.
I created 'Intent1' -> wait for user input about 'Document Type' such as 'Document No.1' or 'Document No.2', etc ...
I created 'Intent2' -> It is follow-up intent of 'Intent1'. It get user input (Training Phrases) such as 'Document No.1' or 'Document No.2' or etc. This 'Intent2' has created parameters for get 'Document Type' such as 'No.1' or 'No.2' from user input.
I created fulfillment 'Inline' for 'Intent2' too. After user input 'No.1' or 'No.2' or etc. I check the parameter value with my Firebase Realtime Database. And then return result message to user for waiting next user input by using ...
agent.add("...some phrase...");
I want to know, is it possible to control Dialogflow in fullfillment?
Such as, if I check 'No.3' does not in by Database, may I send message
"It is not in database" and force process back to 'Intent1'.
But if 'No.1' is in my Database, may I send message "Please input time
to get it?" to user and wait user input at 'Intent3' (follow-up intent
of 'Intent2').
I try to search guide for solving but not found.
Thank in advance
Using Firebase to retrieve data
When using firebase to retrieve data for your dialogflow agent, try not to have any ' business logic' in your databases. Instead, query the database, get the results in your application code (for this example Inline fulfillment), and have your logic there (i.e. did the results come back null or non-null, depending on if it exists in the database). Now, let's get back to your problem at stake.
Implementing a solution
First, you should have code that looks like this to set up the connection between Dialogflow and Firebase.
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: 'ws://project_name.firebaseio.com/'
});
If you have issues with respect to using firebase-admin, you will need greater permission and check out this out.
Next, when your user says a Document Type to the agent, you query the database based on what you extracted from the user. This extraction is stored in a variable you named when you created parameters in the console. You can name this variable anything; I am going to call this extracted parameter userType. The inline fulfillment code is as follows:
function getDoc(agent){
// userType is what the user responded to you
const response = agent.parameters.userType;
return admin.database().ref('data').once('value').then((snapshot) => {
const type = snapshot.child(response).val();// response is variable so no quotes
if(type!== null){
agent.add(`You chose Document type ${type}`);
}
else{
// type == null indicating the type doesn't exist in the database
agent.add('You gave an invalid type');
}
});
}
If the Document Type the user said to agent exists in your database, then the variable above I called type will be some value (not null). If it is null, then what the user asked for is not in the database, and you can prompt a message to user as a follow up such as, "Your input is invalid."
In your example, if the user asked for No. 3 then response would refer to No. 3 and the type would be null. indicative of the fact No. 3 is not is your database.
Resources:
Video by Axle Web Technologies about the workflow and syntax of connecting Dialogflow to Firebase (highly recommended)
Accessing parameters from inside a fulfillment, by GCP Quickstart
Get data using Firebase, from the Firebase Documentation

Permission denied to query class in the Parse Server with JS SDK

I created a class in my Parse Server, using the Parse Dashboard, and then I changed the Class Level Permissions to allow only one user to perform read and write operations in the documents of this class:
The user that is supposed to have access to this class was also created manually through the Parse Dashboard and it looks like this:
However, when I try to query documents from this class, using this user in specific, I keep getting the error message "Permission denied for action find on class Person". This is how my code to login and query the class looks like:
const Person = Parse.Object.extend('Person')
Parse.Object.registerSubclass('Person', Person)
Parse.User.logIn('username', 'password').then(user => {
console.log('E-mail: ' + user.getEmail())
console.log('Created: ' + user.createdAt)
console.log('Current: ' + user.isCurrent())
console.log('Authenticated: ' + user.authenticated())
const query = new Parse.Query(Person)
query.equalTo('name', 'John')
return query.find()
})
I included a bunch of console.log's to check what information about the user is being printed and I confirm that the login seems to complete successfully because the fields email and createdAt match the information that I see in the Parse Dashboard. However, the field authenticated and current both return false, but I don't know why. I was expecting them to return true.
This is the only place in the application that I try to login the Parse Server and perform an operation that is restricted to only one user. Any idea why I'm getting this "Permission denied for action find on class Person" error?
I guess that this is related to security. Generally Parse will not allow a user to get data about any other user, unless you do some actions - e.g. - allow it from the dashboard. But anyway I guess that you have to do it one by one.

Kentico 10 - How do I update the username of an existing user?

Using a kentico 10 website with claims based authentication. We have the facility to update their email address in the external system. So what I want to do is update the user's email address and username by looking up based on the external userid from our sso platform.
var existingUser = UserInfoProvider.GetUsers().Where("ExternalGuid", QueryOperator.Equals, userId).FirstOrDefault();
if (existingUser.IsInSite(SiteContext.CurrentSiteName))
UserInfoProvider.RemoveUserFromSite(existingUser.UserName, SiteContext.CurrentSiteName);
loggingInUser = UserInfoProvider.GetUserInfo(existingUser.UserID);
loggingInUser.UserName = e.UserName;
UserInfoProvider.SetUserInfo(loggingInUser);
I'm getting the error:
The user with code name 'ac.aa#test.com' already exists.
This is happening on that SetUserInfo line. So I'm thinking there must be another way to update the username properly.
You need to do a few things:
Check if the user exists already:
UserInfo ui = UserInfoProvider.GetUserInfo(newUserName);
if (ui != null)
{
// user exists with new username so don't continue
}
Check if the username can be used as a username (no spaces, special characters, etc):
if (!ValidationHelper.IsUserName(newUserName))
{
// username cannot be used as a username
}
Check if the username is reserved or not:
if (UserInfoProvider.NameIsReserved(siteName, newUserName))
{
// reserved username so cannot use it
}
I'm willing to bet the username is reserved or not valid which is why it is not saving. The assignment you have done should work without issue.
It also looks like you're performing this update in a global handler so this could cause problems with a few things. So you may have to perform that username update later on or simply write a record to a custom table and then update it from there based on the event of creating those records in the custom table.
So I'd debug through your code and verify it is working properly by removing it from the global event handler, if it works, then it's an issue with having too many things happen at one time.
Try using SetValue(string columnName, value) method, I just tested this one and it worked fine:
UserInfo updateUser = UserInfoProvider.GetUserInfo("NewUser");
if (updateUser != null)
{
// Updates the user's properties
updateUser.SetValue("UserName", "NewUserName");
// Saves the changes to the database
UserInfoProvider.SetUserInfo(updateUser);
}
For some properties/columns, which are acting like "read only", you need to use the SetValue method like it was a custom field (API examples)

How to protect properties for different roles using loopback

I was just wondering how you would restrict property access to the $owner role only. For instance in my case I have a Joke which has an Author. The Author has User as base. I would like other "Authers" / Users to see who created the Joke, but they should not be able to see the Authers email, only if the Author is the $owner of the Joke itself it should be OK to show their email, just for the sake of this case.
Looking at the built-in User model you can see that they use the hidden feature to hide the password, but using that for their email will also hide their email for the $owner, which is not what I wanted
Let me know if something is not clear.
Thanks in advance
Register beforeRemote hook and check if current user is the $owner.
Joke.boforeRemote('findById', function(context, joke, next) {
// 1. find current user by id, using context.req.accessToken.userId
// 2. check if he is owner or not, by Role.isOwner
// 3. remove email from returned joke instance if user is not $owner
})
Note: it can be a bit complicated to cover all endpoints that return Jokes. But is there another way to do it?
To modify the output/results, you can use the afterRemote hook, as per the docs. The output/results are stored in ctx.result.
'findById' hooks into your GET requests when the call is like GET http://myModel/id. Use 'find' if you are not including the id in your request e.g. GET http://myModel. Just notice that in case of 'find', the returned instance(s) (joke(s)) is usually not just one so it is in an array of objects.
Joke.afterRemote('findById', function(ctx, joke, next) {
//your code
});
Get the id of current logged-in user: var currentUser = context.req.accessToken.userId
Compare the user id of the current logged-in user with that of the joke owner. If both are not the same (i.e. if (!(currentUser == joke.userId))), then:
before calling next(), remove the email attribute from returned joke instance. Because sometimes some ways don't work, here are a few:
delete ctx.result.email;
ctx.result.email = '';
loop through the attributes and transferring them to a new var, except the email, then save that new var the result: ctx.result = newVar;
You can create your own role resolver. See https://github.com/strongloop/loopback-example-access-control/blob/master/server/boot/role-resolver.js for an example. Just add your own logic once you determine the user.

Resources