I have a story line as follows
Scenario:
Given user is on Login page
When user types login details with xxx as user xxx as passwd and submits
Then dashboard is shown
please advise, how to comment or not to make run for a line(example: 2 line should not undergo for test after 1 directly 3 line)
You want to temporarily disable a step in your scenario? Comment the line using the prefix "!-- ", such as
Given user is on Login page
!-- When user types login details with xxx as user xxx as passwd and submits
Then dashboard is shown
The space right after the !-- is mandatory. Thanks #flaz14
See documentation on JBehave: http://jbehave.org/reference/stable/grammar.html
I know this an old question, but I have found a solution for this, and I share for the community :
'!-- ' is the sign for cancellable step, means steps that need to be disabled.
In our project, we use a story Parser :
this.currentConf.useStoryParser(new TransformingStoryParser(this.currentConf.storyParser(), this.transformComment, this.transformCutter));
We needed to put documentation in user stories, so we made a difference between comments and cancellable steps :
!-- Then ... => Cancellable steps (native way)
!--| This is a a comment... => Comment
With the transformer, comments are stripped from the story before it is executed.
This is the same for '|--', a cancellable example. We have introduced '|--|', or a 'cutter' to prevent the rest of the story to be executed.
The classes (this.transformComment, this.transformCutter) :
public class ParserTransformingComment implements StoryTransformer {
public ParserTransformingComment() {
}
/**
* Suppression de commentaires
*/
private Rewriter vC = new Rewriter("(?ms)^((!--\\|[^\\r\\n]*)(?:\\r?\\n)?)") {
#Override
public String replacement() {
System.out.println("Ignoré : " + this.group(1));
return "";
}
};
#Override
public String transform(String pStoryAsText) {
return vC.rewrite(pStoryAsText);
}
}
public class ParserTransformingCutter implements StoryTransformer {
public ParserTransformingCutter() {
}
/**
* Gestion des 'cutter'.
*/
private Rewriter vS = new Rewriter("(?ms)^(\\|--\\|.*)") {
#Override
public String replacement() {
System.out.println(">>> Cette section va être ignorée : ");
System.out.println(StringUtils.lineStart("> ",this.group(1)));
System.out.println("-------------");
return "";
}
};
#Override
public String transform(String pStoryAsText) {
return vS.rewrite(pStoryAsText);
}
}
EDIT:
As of Jbehave 4.3, comments are handled in a better way, even without StoryTransformer :
!--BlahBlah -- ignored completely by Jbehave
!-- Then ... -- steps ignored (registered in the report)
!-- Blah blah -- comment (registered in the report)
Regards,
David C.
If you are using Eclipse IDE then you can use shortcut Ctrl + T to comment single / multiple story line.
Use this !-- When user types login details with xxx as user xxx as password and submits.
Note :For comment "!--" space is mandatory otherwise it will execute the step.
Related
I am setting up the logging for a project and was wondering, whether it is possible to send id to postges database. Later I would collect all logs with fluentd and use the efk(elastic search, fluentd, kibana) stack to look through the logs. That is why it would be very helpful if can set the id in the database logs.
You can have your connection set the application_name to something that includes the id you want, and then configure your logging to include the application_name field. Or you could include the id in an SQL comment, something like select /* I am number 6 */ whatever from whereever. But then the id will only be visible for log messages that include the sql. (The reason for putting the comment after the select keyword is that some clients will strip out leading comments so the serve never sees them)
Thank you #jjane,
for giving me such a great idea. After some googling I found a page describing how to intercept hibernate logs
then I made some more research on how to add the inspector to spring-boot and this is the solution I came up with:
#Component
public class SqlCommentStatementInspector
implements StatementInspector {
private static final Logger LOGGER = LoggerFactory
.getLogger(
SqlCommentStatementInspector.class
);
private static final Pattern SQL_COMMENT_PATTERN = Pattern
.compile(
"\\/\\*.*?\\*\\/\\s*"
);
#Override
public String inspect(String sql) {
LOGGER.info(
"Repo log, Correlation_id:"+ MDC.get(Slf4jMDCFilter.MDC_UUID_TOKEN_KEY),
sql
);
return String.format("/*Correlation_id: %s*/", MDC.get(Slf4jMDCFilter.MDC_UUID_TOKEN_KEY)) + SQL_COMMENT_PATTERN
.matcher(sql)
.replaceAll("");
}
}
and its configuration:
#Configuration
public class HibernateConfiguration implements HibernatePropertiesCustomizer {
#Autowired
private SqlCommentStatementInspector myInspector;
#Override
public void customize(Map<String, Object> hibernateProperties) {
hibernateProperties.put("hibernate.session_factory.statement_inspector", myInspector);
}
}
I need to display two different index pages to two different user groups. For example, a regular user should see one page, and a privileged user - another one. I see two ways of approaching this issue:
One index action with conditionals:
public function index()
{
// view for privileged users
if(request()->user()->hasRole('privileged')){
return view('index_privileged');
}
// view for regular users
if(request()->user()->hasRole('regular')){
return view('index_regular');
}
return redirect('/');
}
Multiple actions:
public function index_privileged()
{
return view('index_privileged');
}
public function index_regular()
{
return view('index_regular');
}
Which approach is more "restful-friendly" and generally better?
I'm a big fan of light controllers. This might be a little overboard for a simple problem but if something like this pops up again, you'd already have everything all setup.
With that said, it might be best to create a PrivilegedUser class and a RegularUser class and give them both an index method which returns their respective views. Code them both to an interface UserInterface and make sure they both implement that.
Here is what those looked like in my test.
class RegularUser implements UserInterface
{
public function index()
{
return view('index_regular');
}
}
class PrivilegedUser implements UserInterface
{
public function index()
{
return view('index_privileged');
}
}
interface UserInterface
{
public function index();
}
Then you can add a listener which should run for the event Illuminate\Auth\Events\Login. Laravel will fire this event for you automatically when someone logs in. This goes into the file EventServiceProvider.php.
protected $listen = [
'Illuminate\Auth\Events\Login' => [
'App\Listeners\AuthLoginListener',
],
];
Now you can run php artisan event:generate to generate the new listener. Here is what my listener looks like, it should work for you.
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Foundation\Application;
class AuthLoginListener
{
/**
* Create the event listener.
*
* #param Application $app
*/
public function __construct(Application $app)
{
$this->app = $app;
}
/**
* Handle the event.
*
* #param Login $event
* #return void
*/
public function handle(Login $event)
{
if ($event->user->hasRole('privileged')) {
$this->app->bind('App\Repositories\UserInterface', 'App\Repositories\PrivilegedUser');
} else if ($event->user->hasRole('regular')) {
$this->app->bind('App\Repositories\UserInterface', 'App\Repositories\RegularUser');
}
}
}
Essentially what this is doing is telling Laravel to load up a certain class based on the type of user that just logged in. The User instance is available through the Login object which was automatically passed in by Laravel.
Now that everything is setup, we barely have to do anything in our controller and if you need to do more things that are different depending on the user, just add them to the RegularUser or PrivilegedUser class. If you get more types of users, simply write a new class for them that implements the interface, add an additional else if to your AuthLoginListener and you should be good to go.
To use this, in your controller, you'd do something like the following...
// Have Laravel make our user class
$userRepository = App::make('App\Repositories\UserInterface');
return $userRepository->index()->with('someData', $data);
Or even better, inject it as a dependency.
use App\Repositories\UserInterface;
class YourController extends Controller
{
public function index(UserInterface $user)
{
return $user->index();
}
}
Edit:
I just realized I forgot the part where you wanted to return redirect('/'); if no condition was met. You could create a new class GuestUser (I know this sounds like an oxymoron) which implements UserInterface but instead of using the AuthLoginListener, I'd bind it in a service provider when Laravel boots. This way Laravel will always have something to return when it needs an implementation of UserInterface in the event it needs this class if no one is logged in.
Well, its more like a refactoring "issue" than a rest-friendly issue. Check this guideline and you can see that most of the things that makes an api friendly is concerned to the url.
But, lets answer what you are asking. The thing you wanna do is a refactoring method but it is not only the move method but something like the extract variable.
The second option would make the code more readable, either ways are right but the second is more developer friendly. It enhances the code readability from any developer. I would recommend using the second option.
Refactoring is never enough, but read something like this, it will help you a lot writing more readable codes.
I have implemented a CurrentUserPropertyBinder (see below) for a web application using FubuMVC.
public class CurrentUserPropertyBinder : IPropertyBinder
{
private readonly Database _database;
private readonly ISecurityContext _security;
public CurrentUserPropertyBinder(Database database, ISecurityContext security)
{
_database = database;
_security = security;
}
public bool Matches(PropertyInfo property)
{
return property.PropertyType == typeof(User)
&& property.Name == "CurrentUser";
}
public void Bind(PropertyInfo property, IBindingContext context)
{
var currentUser = //check database passing the username to get further user details using _security.CurrentIdentity.Name
property.SetValue(context.Object, currentUser, null);
}
}
When I login to my site, this works fine. The CurrentUserPropertyBinder has all the information it requires to perform the task (i.e. _security.CurrentIdentity.Name has the correct User details in it)
When I try and import a file using fineUploader (http://fineuploader.com/) which opens the standard fileDialog the _security.CurrentIdentity.Name is empty.
It doesn't seem to remember who the user was, I have no idea why. It works for all my other routes but then I import a file it will not remember the user.
Please help! Thanks in Advance
NOTE: We are using FubuMVC.Authentication to authenticate the users
I'm guessing your action for this is excluded from authentication; perhaps it's an AJAX-only endpoint/action. Without seeing what that action looks like, I think you can get away with a simple fix for this, if you've updated FubuMVC.Authentication in the past 3 months or so.
You need to enable pass-through authentication for this action. Out of the box, FubuMVC.Auth only wires up the IPrincipal for actions that require authentication. If you want access to that information from other actions, you have to enable the pass-through filter. Here are some quick ways to do that.
Adorn your endpoint/controller class, this specific action method, or the input model for this action with the [PassThroughAuthentication] attribute to opt-in to pass-through auth.
[PassThroughAuthentication]
public AjaxContinuation post_upload_file(UploadInputModel input) { ... }
or
[PassThroughAuthentication]
public class UploadInputModel { ... }
Alter the AuthenticationSettings to match the action call for pass-through in your FubuRegistry during bootstrap.
...
AlterSettings<AuthenticationSettings>(x => {
// Persistent cookie lasts 3 days ("remember me").
x.ExpireInMinutes = 4320;
// Many ways to filter here.
x.PassThroughChains.InputTypeIs<UploadInputModel>();
});
Check /_fubu/endpoints to ensure that the chain with your action call has the pass-through or authentication filter applied.
I have a flag on my users for 'active' and if set to zero or null, I will not allow login.
I have tried a couple of approaches and come up short.
If I do the logout route the flash message is not preserved, so the user sees nothing.
I looked into adding a validation on the login form so that it would throw a normal form error if the flag was not set to true, but in that folder (vendor/Bundles/FOS/UserBundle/Form/Type) I find nothing for login form, only registration and such, so I wouldn't know where to put it or where to inherit from in order to override.
I also tried as suggested here to manually log out, but that left me with a white screen of death...
Any suggestions how to easily accomplish this?
************** UPDATE ************
I realized that I probably want to go about it adding a validator on the login form. I currently have it coded into the controller of the first route a user gets sent to, but that won't provide much security if a user types a route before logging in, because on a successful login attempt, my default "landing page" after login will not be the route that the user is taken to, but he will be landing on the route of his choice...
***UPDATE AGAIN ****
So the service config file has this...
<service id="security.user_checker" class="%security.user_checker.class%" public="false" />
And that parameter is defined here...
<parameter key="security.user_checker.class">Symfony\Component\Security\Core\User\UserChecker</parameter>
So in order to modify the login logics I need to override
Symfony\Component\Security\Core\User\UserChecker
Now I have done that by overriding that parameter above in my own parameters.ini in the symfony app/config like this
security.user_checker.class = BizTV\UserBundle\Controller\UserChecker
.. and added this check to my userChecker overrider...
//Test for companylock...
if ( !$user->getCompany()->getActive() ) {
throw new LockedException('The company of this user is locked.', $user);
}
Here's the entire file:
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien#symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
//Override by Mattias
namespace BizTV\UserBundle\Controller;
//namespace Symfony\Component\Security\Core\User;
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
use Symfony\Component\Security\Core\Exception\LockedException;
use Symfony\Component\Security\Core\Exception\DisabledException;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserChecker as OriginalUserChecker;
/**
* UserChecker checks the user account flags.
*
* #author Fabien Potencier <fabien#symfony.com>
*/
class UserChecker extends OriginalUserChecker
{
/**
* {#inheritdoc}
*/
public function checkPreAuth(UserInterface $user)
{
//Test for companylock...
if ( !$user->getCompany()->getActive() ) {
throw new LockedException('The company of this user is locked.', $user);
}
if (!$user instanceof AdvancedUserInterface) {
return;
}
if (!$user->isCredentialsNonExpired()) {
throw new CredentialsExpiredException('User credentials have expired.', $user);
}
}
/**
* {#inheritdoc}
*/
public function checkPostAuth(UserInterface $user)
{
//Test for companylock...
if ( !$user->getCompany()->getActive() ) {
throw new LockedException('The company of this user is locked.', $user);
}
if (!$user instanceof AdvancedUserInterface) {
return;
}
if (!$user->isAccountNonLocked()) {
throw new LockedException('User account is locked.', $user);
}
if (!$user->isEnabled()) {
throw new DisabledException('User account is disabled.', $user);
}
if (!$user->isAccountNonExpired()) {
throw new AccountExpiredException('User account has expired.', $user);
}
}
}
* Update nb 3 ********
Now I only have left to make it actually check for the standard user lock which surprisingly it doesn't do out of the box. (Thanks nifr for getting me this far!)
My user entity starts off like this, and like Nifr said, I need to implement the AdvancedUserInterface, but this is probably not the way to do it since it still doesn't check for this lock... but it throws me no error message either (if I change them up and put implememts AdvancedUserInterface and then EXTENDs baseUser it throws an error so...)
<?php
// src/BizTV/UserBundle/Entity/User.php
namespace BizTV\UserBundle\Entity;
use BizTV\UserBundle\Validator\Constraints as BizTVAssert;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use BizTV\BackendBundle\Entity\company as company;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser implements AdvancedUserInterface
{
Not sure if that's how you do it when you both extend base user and try and implement AdvancedUserInterface, when done as above I still can't use the features it's supposed to add (but it throws me no error message either), but If I switch places of the EXTENDS and IMPLEMENTS like this (line 18)...
class User implements AdvancedUserInterface extends BaseUser
...I get this error:
Parse error: syntax error, unexpected T_EXTENDS, expecting '{' in /var/www/cloudsign/src/BizTV/UserBundle/Entity/User.php on line 18
FOSUserBundle / Symfony already has some kind of "active" flag integrated.
FOS\UserBundle\Model\User already provides the properties "locked" and "enabled" which are intended basically for this purpose. The difference between those two properties is the following ( quoting #stof's comment here)
From the Security component point of view, there is no real
difference: both are forbidden to log in. The difference is a
semantic one: disabled users are generally users that need to
activate their account (for instance, when you activate the need to
confirm the email in FOSUserBundle, the user is disabled on creation
and enabled on confirmation). On the other hand, locking a user is
generally an action done by the admin of the site to ban a user.
Using the same field in the database does not make sense as it would
allow banned user to have access again by simply going through the
confirmation process.
The check for locked/disabled users is being performed by a UserChecker ( symfony provides this one as #security.user_checker ) in FOSUserBundle's AuthenticationListener which implements Symfony\Component\Security\Core\User\UserCheckerInterface.
Now in order to redirect inactive user's to a different route you would:
Catch the Symfony\Component\Security\Core\Exception\DisabledException in the try/catch block in an extended AuthenticationListener
Redirect the user to a certain route if the caught exception is of type InactiveUserException
Optionally move the redirect to a newly created EventListener/-Subscriber which is being dispatched in the extended AuthenticationListener. This way you could later create additional Listeners i.e. for logging purposes and just subscribe them to the inactive-user login-attempt event.
I'm attempting to create a user login for Facebook and Windows LiveId using DotNetOpenAuth 4.1.0.12182
However the examples in the download make use of DotNetOpenAuth.ApplicationBlock and DotNetOpenAuth.ApplicationBlock.Facebook which don't exist in the current build.
Instead there is the DotNetOpenAuth.AspNet.Clients namespace which includes FacebookClient and WindowsLiveClient - however I can't find any example of how to use these.
Do any examples or documentation exist?
I have been able to get DNOA version 4.1.0.12182, .Net 3.5 and Facebook to work with each other by creating a FacebookAuthClient that is derived off of the DotNetOpenAuth.OAuth2.WebServerClient. One little gotcha that I have found is that if you are using cookie based sessions then you have to access the session before you use the OAuth functionality. From what I can tell this is because DNOA uses the Session ID as the state parameter and if session has never been accessed it can change between requests. This will cause a state parameter mismatch error when the response comes back from Facebook.
FacebookAuthClient:
public class FacebookAuthClient : DotNetOpenAuth.OAuth2.WebServerClient
{
private static readonly DotNetOpenAuth.OAuth2.AuthorizationServerDescription Description = new DotNetOpenAuth.OAuth2.AuthorizationServerDescription
{
TokenEndpoint = new Uri("https://graph.facebook.com/oauth/access_token"),
AuthorzationEndpoint = new Uri("https://graph.facebook.com/oauth/authorize")
};
public static readonly string [] ScopeNeeded = { "publish_stream" };
public FacebookAuthClient()
: base(Description)
{
}
}
Facebook.aspx.cs:
public partial class FacebookPage : System.Web.UI.Page
{
private FacebookAuthClient _client = new FacebookAuthClient
{
ClientIdentifier = ConfigurationManager.AppSettings["FBClientId"], //The FB app's Id
ClientCredentialApplicator = DotNetOpenAuth.OAuth2.ClientCredentialApplicator.PostParameter(ConfigurationManager.AppSettings["FBClientSecret"]) // The FB app's secret
}
protected void Page_Load(object sender, EventArgs e)
{
DotNetOpenAuth.OAuth2.IAuthorizationState auth = _client.ProcessUserAuthorization();
if (_auth == null)
{
// Kick off authorization request with the required scope info
client.RequestUserAuthorization(FacebookAuthClient.ScopeNeeded);
}
}
}
This is just a test app so there is no error handling but it seems to work.
Edit
I used the DotNetOpenAuth(unified) NuGet package for all of this.
Edit
Added missing .PostParameter call to the creating of the ClientCredentialApplicator.
You'll need to use ctp version 3.5 of DNOA. Version 4+ has been made to work with a later draft of OAuth 2 then Facebook uses.
You can find it on the owners GitHub:
https://github.com/AArnott/dotnetopenid