Is it possible to run a specific java method after all of the #Given statements have completed for a specific scenario? - jbehave

Currently I have a story written like:
Given I login as a user
And that user likes computers
And that user has a car
When that user goes to school
Then he will be happy
I want to be able to execute a java login method after I have collected all of the Given statement data to login.
Note: the last given statement changes between stories, and the user has different variables that could be assigned to that user.
Is it possible to do something like this?

One alternative is you to use tabular parameters this way:
Given an user logs into application with:
|Id|Taste|Belongings|
|Bob|computers|car|
and this step method:
#Given("an user logs into application with: $loginInfo")
public void theTraders(ExamplesTable loginInfo) {
callLoginProcedure(loginInfo);
}
you could see more details here.

Related

Get user's AD role without using Remote Server Administration Tools

I'm trying to write a powershell command that checks to see if a user is part of an AD Group, however, I don't want to use the RSAT modules, as this may end up being a logon script (and we don't want users having those modules installed). This did lead me to this question, Search AD with PowerShell without using AD module (RSAT), however, I can't figure out how to filter the results check it the value is in there.
For example, the below does return a list of users, in LDAP form, for the group IT, but how do I then check a specific user (with their Username, not display name) is in there?
([System.DirectoryServices.DirectorySearcher]"(&(objectCategory=group)(name=IT))").FindOne().Properties["Member"]
FindOne() despite what it says as well, returns multiple rows; in fact FindAll() and FindOne() both return the same results.
Should I be using a different command to search AD? Specifically I want to either check an AD group contains a user (the current user), or the inverse, check a user (the current user) is a member of a particular AD group.
You can do it that way if you really need to (and I can help you do it that way if you really need) but if you are going to be running this script under the credentials of the user you are interested in, then you can get all the groups from the user's login token. That already contains a recursive list of all security groups that the user is in. (It won't include groups where the 'Group type' is "Distribution")
The login token contains a list of SIDs, so the absolute fastest way is to compare using the SID of the group you are interested in, since it won't have to make any network request at all. That's especially convenient for laptop users who may not be online when they login - your script would still work.
$currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
if ($currentIdentity.Groups.Where({$_.Value -eq "S-1-1-0"}, "First")) { #Is in "Everyone"?
"Yes"
} else {
"No"
}
To find the SID of a group, use this:
(Get-ADGroup "GroupName").SID.Value
Then copy/paste that value into the script.
If you would prefer to use the name of the group in the script, then you can convert it to a WindowsPrincipal and use IsInRole. However, this will need to make a network request to find the group by its name.
$currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
$currentPrincipal = New-Object System.Security.Principal.WindowsPrincipal($currentIdentity)
if ($currentPrincipal.IsInRole("Everyone")) {
"Yes"
} else {
"No"
}

How to give personalised greeting in Watson Conversation?

While Defining the Dialog in the Watson Conversation I'm not able to greet user with his/her name or I'm not able to detect contact number sent by the user and rephrase it to the user. Is it possible to do it in the Watson Conversation Api or not.
Although Mitch's response is correct, here is an example of doing a personalised response.
1. Set your conversation_start node text to "Hello <? context.username ?>".
2. In your code you would do something like this (Python).
import json
from watson_developer_cloud import ConversationV1
conversation = ConversationV1(
username='SERVICE_USERNAME',
password='SERVICE_PASSWORD',
version='2016-07-11')
workspace_id = 'WORKSPACE_ID_CONVERSATION'
response = conversation.message(workspace_id=workspace_id, context= {'username':'Simon'})
print json.dumps(response)
3. When you run this, it should output the following, with the "text" part being what the user sees.
{
"entities":[],
"intents":[],
"output":{
"log_messages":[],
"nodes_visited":["node_1_1472298724972],
"text":["Hello Simon"]
},
"context":{
"username":"Simon",
"conversation_id":"9dc1501b-ac53-4b51-a299-37f5314ebf89",
"system":{
"dialog_turn_counter":1,
"dialog_stack":["root"],
"dialog_request_counter":1
}
},
"input":{}
}
One thing to be aware is that, the context object is used to maintain the state of the conversation. So if you plan to use just REST API's then you need to merge your context variables into the preceding context object before sending it. You do only need to do this at points where you do know the conversation needs that context.
Do you already have access to this information? You can send these values through as context, and refer to them using $context_variable
The same goes for collecting information from a user. You can capture things using regular expressions via your application, or using some Spring Expressions, you can see the text.matches here:
https://www.ibm.com/watson/developercloud/doc/conversation/dialog_reference.shtml
You would store this as context, and then refer to it using $context_variable again.
Information like names and phone numbers is quite open ended, so can be difficult to capture without using an open entity extraction engine, which we are researching best ways to incorporate this.
To get the user's input, use:
"context": {"yourVariable": "<?input.text?>"}
And to show:
"output": {"text": "You entered this $yourVariable"}

Logging with Email and Password , Not with Username Yii 2

How I can manage to login with email address,not with the standart (username + password).I enter the website with my Users in my DataBase , but is there a way to change that to be with email address instead of that user name , because when I use Gii , I got a lot of errors , even I try to fix those errors
First, try to locate your SiteController or any other Controller you use for the index route. It should have an action function that corresponds to the login route; it is usually with signature public function actionLogin().
You should see the initialized model (usually, the LoginForm model). The model should have a function for login logic which is checked to determine user authenticity. You should find that this function invokes another login function which requires the User object as first argument/parameter. The function is usually the $this->getUser() function.
Looking into this will point to you a call to the actual data model that fetches user by whatever criteria/property you specify; this can be email or anything else that might not even need be unique but generally, you want to use a unique data property like username and email. This function relies on the User data model. It, by Gii default, calls the function User::findByUsername(search_property)
Yii2 provides a default User model that implements the Identity interface; that's where you want to make the adjustment you need. It should have the required static function findByUsername() or something similar. You would find that Yii2 default searches within static data to find user, you should link that to you (User) data model which I assume you generated using Gii.
My Gii sequence usually looks like such:
List item
Generate the yii2-basic/yii2-advanced using composer
Create Database (I have a user table in there) and set proper db credentials in config/db.php
Rename the default model/User.php to model/OldUser.php
Create Data Models using Gii
Make the newly generated User Model implement IdentityInterface to allow Yii2 freely-given session management by adding implements yii\web\IdentityInterface to the class declaration.
Implement all the required methods of the IdentityInterface. You can check in `model/OldUser.php' for guidance.
Create static functions to findUserByEmail($email) or findUserByUsername($username)
Mine usually look like this
I hope this helps.
I made it just change everywhere where must be email,instead of username,because of Yii default username loggin , thank u for the advices

How to get the current user using jsonwebtoken in Sails.js?

I've been working with Sails since couple of weeks ago, I came from Rails and I don't have any experience working with Node.js.
Now I'm trying to make a robust token authentication using jsonwebtoken.
https://github.com/auth0/node-jsonwebtoken
I followed this guide http://thesabbir.com/how-to-use-json-web-token-authentication-with-sails-js/ and everything worked fine.
I'm able to make a sign up, sign in and then use the token correctly for different actions.
Now, there are some actions where I'd like to use the login user,
something like devise current_user helper.
For example, when creating a comment, this comment should belongs to the current user.
Using Sabbir Ahmed guide, in the line 33 from the isAuthorized.js policy the token gets decrypted so I can get the current user id from there.
So, my question is, what should be the best way to get the current user and be able to use it later in some controller?
For example I tried something like:
# isAuthorized.js line 34, after getting decrypted token
User.findOne({id: token.id}).exec(function findOneCB(err, found){
currentUser = found;
});
But, on this way, because this is an async action I can't use this currentUser in a controller.
I want to store the current user in order to be able to use it later in some controller without repeated the same code in each controller, something like a helper or maybe a service.
The trick is where you place the next(). Since you are making an async call, the control should only be transferred to next policy/ controller once the database action is competed.
You should modify the policy to:
User.findOne({id: token.id}).exec(function findOneCB(err, found){
if(err) next(err);
req.currentUser = found;
next();
});
And you should be able to access the user details in controllers that use isAuthorized policy via req.currentUser
If by
For example, when creating a comment, this comment should belongs to the current user.
what you mean is certain attributes like username, and country etc, rather than querying the database after verification, what you can choose to do is to send these additional attributes to jwToken.issue in api/controllers/UsersController.js
eg.
jwToken.issue({
id: user.id,
username: user.name,
country: user.country
})
How that helps is, you can keep api/policies/isAuthorized.js as is, and in all the controllers that you use in the future, you can access the payload values from as
token.username or token.country
Instead of having to query the database again, thereby saving you valuable response time.
Beware however, of the data you choose to send in the token (you could also send {user:user} if you want to) however, as the secret key or hashing is not required to decrypt the payload as you can figure # jwt.io , you might want to exercise restraint.

Testing stateful Mojolicious apps

I want to test hiding and unhiding of an entry. I conduct the following tests in Mojolicious t/basic.t:
my $t = Test::Mojo->new('AdminApi');
$t->get_ok('/publications/hide/1');
$t->get_ok('/read/publications/meta')->content_unlike(qr/Paper with id 1:/i);
$t->get_ok('/read/publications/meta/1')->content_like(qr/Cannot find entry id: 1/i);
$t->get_ok('/publications/unhide/1');
$t->get_ok('/read/publications/meta')->content_like(qr/Paper with id 1: <a href/i);
$t->get_ok('/read/publications/meta/1')->content_unlike(qr/Cannot find entry id: 1/i);
My problem is that the two lines '/publications/hide/1' and '/publications/unhide/1' do not hide and unhide the entry. The state of the entry remains untouched.
If I repeat the steps manually in the browser everything works well. For the obvious reasons I want to have it automated with the tests. How to do this?
EDIT: The calls '/publications/hide/1' and '/publications/unhide/1' change the state of the database - just a simple UPDATE query. The change applies to the whole application - for all users. But one needs to be logged in as a user to hide/unhide. Question: how do I emulate a logged user during the test?
Contents generated by '/read/publications/meta' and '/read/publications/meta/1' can be read without login.
Bitbucket Repo
File with test code: basic.t
As you have already said, you need to be logged in to perform the hide and unhide action.
my $t = Test::Mojo->new('AdminApi');
You are creating a new UserAgent here. The Test::Mojo class inherits from Mojo::UserAgent. It has a cookie_jar and thus keeps a session alive. You need that to perform this action:
$t->get_ok('/publications/hide/1');
But right now you are not logged in. What you need to do is log in the user. Looking at the code in your repository, you actually assert that you are not logged in.
$t->get_ok('/')->status_is(200)->content_like(qr/Please login or register/i);
Before you perform the hide, you need to log in the user. After digging a bit in your code I found the action and the template to do that, so I know what the request needs to look like.
$t->post_ok(
'/do_login' => { Accept => '*/*' },
form => { user => 'admin', pass => 'hunter2' }
);
Now your $t UserAgent should be logged in and you can do the hide. Note that get_ok only checks if there was no transport error. So in fact it would make sense to now check if in fact you are now logged in.
You could do that by introspecting the session in the application, by checking the logfile (you are writing "Login success" there) or by checking the page for some string that says that the user is logged in. In templates/display/start.html.ep there is a text that welcomes the logged-in user, so you can use that.
$t->post_ok(
'/do_login' => { Accept => '*/*' },
form => { user => 'admin', pass => 'hunter2' }
)->text_like(qr/Nice to see you here admin/i);
Because text_like uses the text-nodes, the <em> around the username is not relevant in the test.
Right, now we know you are logged in. Time to switch the thing on and off.
$t->get_ok('/publications/hide/1');
Because there is no obvious error thrown for that as far as I can tell, I don't see how to test the success of that. Status code is one way, but there might be something in the content as well that you could test.
To verify the state of the application, you would now call the publication.
$t->get_ok('/read/publications/meta')->content_unlike(qr/Paper with id 1:/i);
$t->get_ok('/read/publications/meta/1')->content_like(qr/Cannot find entry id: 1/i);
Right. But remember, our $t is still logged in. Maybe the logged-in user is allowed to see hidden stuff as well as unhidden stuff. Maybe they are not.
It's probably safer to make a second UserAgent that's not logged in, and check with that one as well.
# check with an unauthorized user
my $t_not_logged_in = Test::Mojo->new('AdminApi');
$t_not_logged_in
->get_ok('/read/publications/meta')
->content_unlike(qr/Paper with id 1:/i);
$t_not_logged_in
->get_ok('/read/publications/meta/1')
->content_like(qr/Cannot find entry id: 1/i);
Now basically you repeat the same thing by unhiding your content and testing again. Rinse and repeat.
Keep in mind that unless you are using an explicit testing database (which you seem not to do), you cannot be sure that there even is an entry 1. Or what the name of that is. You should use fixtures for the tests. You could, for example, create a fresh instance of the DB using sqlite and work with that.