使用Securesocial注释保护的单元测试方法 [英] Unit-testing methods secured with Securesocial annotation

查看:87
本文介绍了使用Securesocial注释保护的单元测试方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为使用Play 2.1.4和Socialsecure的web应用程序进行一些功能测试。在使用securesocial之前,测试非常简单,但现在我遇到了麻烦,想知道如何对安全操作进行测试。

I'm trying to make some functional tests for my webapplication that is using Play 2.1.4 and Socialsecure. Before using securesocial the tests where pretty straight forward but now im having troubles figuering out how i can make tests on the secured actions.

@Test
public void createNewNote() {
    Result result;
    // Should return bad request if no data is given
    result = callAction(
            controllers.routes.ref.Notes.newNote(),
            fakeRequest().withFormUrlEncodedBody(
                    ImmutableMap.of("title", "", "text",
                            "")));
    assertThat(status(result)).isEqualTo(BAD_REQUEST);

    result = callAction(
            controllers.routes.ref.Notes.newNote(),
            fakeRequest().withFormUrlEncodedBody(
                    ImmutableMap.of("title", "My note title", "text",
                            "My note content")));

    // Should return redirect status if successful
    assertThat(status(result)).isEqualTo(SEE_OTHER);
    assertThat(redirectLocation(result)).isEqualTo("/notes");

    Note newNote = Note.find.where().eq("title", "My note title")
            .findUnique();

    // Should be saved to DB
    assertNotNull(newNote);
    assertEquals("My note title", newNote.title);
    assertEquals("My note content", newNote.text);
}

截至目前,我在测试yml文件中有一个用户:

As of right now i got a user in the test yml file:

- !!models.User
id: 1234567890
username: Pingu
provider: Twitter
firstName: Pingu
lastName: Pingusson
email: pingu@note.com
password: password

我的用户很直接......:

My user is pretty straight forward...:

@Table(
    uniqueConstraints=
        @UniqueConstraint(columnNames={"username"}))
@Entity
public class User extends Model {

    private static final long serialVersionUID = 1L;

@Id
public String id;

public String provider;

public String firstName;

public String lastName;

public String email;

public String password;

@MinLength(5)
@MaxLength(20)
public String username;

public static Finder<String, User> find = new Finder<String, User>(
        String.class, User.class);

public static User findById(String id) {
    return find.where().eq("id", id).findUnique();
}
public static User findByEmail(String email) {
    return find.where().eq("email", email).findUnique();
}
@Override
public String toString() {
    return this.id + " - " + this.firstName;
}

}

和UserService:

and the UserService:

公共类UserService扩展BaseUserService {

public class UserService extends BaseUserService {

public UserService(Application application) {
    super(application);
}

@Override
public void doDeleteExpiredTokens() {
    if (Logger.isDebugEnabled()) {
        Logger.debug("deleteExpiredTokens...");
    }
    List<LocalToken> list = LocalToken.find.where().lt("expireAt", new DateTime().toString()).findList();
    for(LocalToken localToken : list) {
        localToken.delete();
    }
}

@Override
public void doDeleteToken(String uuid) {
    if (Logger.isDebugEnabled()) {
        Logger.debug("deleteToken...");
        Logger.debug(String.format("uuid = %s", uuid));
    }
    LocalToken localToken = LocalToken.find.byId(uuid);
    if(localToken != null) {
        localToken.delete();
    }
}

@Override
//public Identity doFind(UserId userId) {
public Identity doFind(IdentityId identityId){
    if (Logger.isDebugEnabled()) {
        Logger.debug(String.format("finding by Id = %s", identityId.userId()));

    }

    User localUser = User.find.byId(identityId.userId());
    Logger.debug(String.format("localUser = " + localUser));
    if(localUser == null) return null;
    SocialUser socialUser = new SocialUser(new IdentityId(localUser.id, localUser.provider),    
        localUser.firstName, 
        localUser.lastName, 
        String.format("%s %s", localUser.firstName, localUser.lastName),
        Option.apply(localUser.email), 
        null, 
        new AuthenticationMethod("userPassword"),
        null, 
        null, 
        Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
    );  
    if (Logger.isDebugEnabled()) {
        Logger.debug(String.format("socialUser = %s", socialUser));
    }
    return socialUser;
}


@Override
public Identity doFindByEmailAndProvider(String email, String providerId) {
    List<User> list = User.find.where().eq("email", email).eq("provider", providerId).findList();
    if(list.size() != 1){
        Logger.debug("found a null in findByEmailAndProvider...");
        return null;
    }
    User localUser = list.get(0);
    SocialUser socialUser = 
            new SocialUser(new IdentityId(localUser.email, localUser.provider),
                    localUser.firstName, 
                    localUser.lastName, 
                    String.format("%s %s", localUser.firstName, localUser.lastName),
                    Option.apply(localUser.email), 
                    null, 
                    new AuthenticationMethod("userPassword"),
                    null, 
                    null, 
                    Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
               );  
    return socialUser;
}

@Override
public Token doFindToken(String token) {
    if (Logger.isDebugEnabled()) {
        Logger.debug("findToken...");
        Logger.debug(String.format("token = %s", token));
    }
    LocalToken localToken = LocalToken.find.byId(token);
    if(localToken == null) return null;
    Token result = new Token();
    result.uuid = localToken.uuid;
    result.creationTime = new DateTime(localToken.createdAt);
    result.email = localToken.email;
    result.expirationTime = new DateTime(localToken.expireAt);
    result.isSignUp = localToken.isSignUp;
    if (Logger.isDebugEnabled()) {
        Logger.debug(String.format("foundToken = %s", result));
    }
    return result;
}

@Override
public Identity doSave(Identity user) {
    if (Logger.isDebugEnabled()) {
        Logger.debug("save...!_!");
        Logger.debug(String.format("user = %s", user));
    }
    User localUser = null;
    localUser = User.find.byId(user.identityId().userId());
    Logger.debug("id = " + user.identityId().userId());
    Logger.debug("provider = " + user.identityId().providerId());
    Logger.debug("firstName = " + user.firstName());
    Logger.debug("lastName = " + user.lastName());
    Logger.debug(user.fullName() + "");
    Logger.debug("email = " + user.email());
    Logger.debug(user.email().getClass() + "");

    if (localUser == null) {
        Logger.debug("adding new...");
        localUser = new User();
        localUser.id = user.identityId().userId();
        localUser.provider = user.identityId().providerId();
        localUser.firstName = user.firstName();
        localUser.lastName = user.lastName();

        //Temporary solution for twitter which does not have email in OAuth answer
        if(!(user.email().toString()).equals("None")){
            localUser.email = user.email().get();
        }
        if(!(user.passwordInfo() + "").equals("None")){
            localUser.password = user.passwordInfo().get().password();
        }
        localUser.save();
    } else {
        Logger.debug("existing one...");
        localUser.id = user.identityId().userId();
        localUser.provider = user.identityId().providerId();
        localUser.firstName = user.firstName();
        localUser.lastName = user.lastName();

        //Temporary solution for twitter which does not have email in OAuth answer
        if(!(user.email().toString()).equals("None")){
            localUser.email = user.email().get();
        }
        if(!(user.passwordInfo() + "").equals("None")){
            localUser.password = user.passwordInfo().get().password();
        }
        localUser.update();
    }
    return user;
}

@Override
public void doSave(Token token) {
    LocalToken localToken = new LocalToken();
    localToken.uuid = token.uuid;
    localToken.email = token.email;
    try {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        localToken.createdAt = df.parse(token.creationTime.toString("yyyy-MM-dd HH:mm:ss"));
        localToken.expireAt = df.parse(token.expirationTime.toString("yyyy-MM-dd HH:mm:ss"));
    } catch (ParseException e) {
        Logger.error("UserService.doSave(): ", e);
    }
    localToken.isSignUp = token.isSignUp;
    localToken.save();
}

}

根据我的理解,我应该在某种程度上设置会话,以便用户通过在fakerequest上使用.withsession方法登录,也可以在服务器端设置一些值。

As of my understanding i should in someway set the session so the user is logged in by using the .withsession method on the fakerequest and maybe also set some value on the serverside.

尝试使用securesocial和play在网上搜索示例,但根本没有找到任何测试。

Tried searching the web for examples using securesocial and play but found no tests at all.

如何登录我的用户以便我可以预先测试?

How can i login in my user so i can preform the tests?

最好的问候
Rawa

Best regards Rawa

推荐答案

感谢David Weinbergs评论我在经过一些跟踪和错误之后能够解决这个问题。 (:

Thanks to David Weinbergs comment i was able to solve this after some trail and error. (:

我从这个回复中开始了我的LocalUser实现:
https://stackoverflow.com/a/18589402/1724097

I started out my LocalUser implementation from this reply: https://stackoverflow.com/a/18589402/1724097

这就是我解决它的方式:

This is how i solved it:

要进行单元测试,我使用test-data.yml文件在数据库中创建了一个本地用户:

To make unit tests i created a local user in the database, using the test-data.yml file:

- !!models.LocalUser
    id: 1234567890
    username: Username
    provider: userpass
    firstName: firstName
    lastName: lastName
    email: user@example.com
    #hash for "password"
    password: $2a$10$.VE.rwJFMblRv2HIqhZM5.CiqzYOhhJyLYrKpMmwXar6Vp58U7flW 

然后我创建了一个测试utils类来创建我的fakeCookie。

Then i made a test utils class that create my fakeCookie.

import models.LocalUser;
import play.Logger;
import securesocial.core.Authenticator;
import securesocial.core.IdentityId;
import securesocial.core.SocialUser;
import securesocial.core.PasswordInfo;
import scala.Some;
import securesocial.core.AuthenticationMethod;
import scala.Option;
import scala.util.Right;
import scala.util.Either;
import play.mvc.Http.Cookie;

public class Utils {


    public static Cookie fakeCookie(String user){

        LocalUser localUser = LocalUser.findByEmail(user);
        Logger.debug("Username: " + localUser.username +" - ID: " + localUser.id);

        SocialUser socialUser = new SocialUser(new IdentityId(localUser.id, localUser.provider),    
            localUser.firstName, 
            localUser.lastName, 
            String.format("%s %s", localUser.firstName, localUser.lastName),
            Option.apply(localUser.email), 
            null, 
            new AuthenticationMethod("userPassword"),
            null, 
            null, 
            Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
        );  

        Either either = Authenticator.create(socialUser);
        Authenticator auth = (Authenticator) either.right().get();
        play.api.mvc.Cookie scalaCookie = auth.toCookie();


        //debug loggig
        Logger.debug("Cookie data:");
        Logger.debug("Name: " + "Value: " + auth.cookieName() + " | Class: " + auth.cookieName().getClass() + " | Should be type: " + "java.lang.String");
        Logger.debug("Value: " + "Value: " + scalaCookie.value() + " | Class: " + scalaCookie.value().getClass() + " | Should be type: " + "java.lang.String");
        Logger.debug("MaxAge: " + "Value: " + scalaCookie.maxAge() + " | Class: " + scalaCookie.maxAge().getClass() + " | Should be type: " + "int");
        Logger.debug("Path: " + "Value: " + scalaCookie.path() + " | Class: " + scalaCookie.path().getClass() + " | Should be type: " + "java.lang.String");
        Logger.debug("Domain: " + "Value: " + scalaCookie.domain() + " | Class: " + auth.cookieDomain().getClass() + " | Should be type: " + "java.lang.String");
        Logger.debug("Secure: " + "Value: " + auth.cookieSecure() + " | Class: " + "Boolean" + " | Should be type: " + "boolean");
        Logger.debug("HttpOnly: " + "Value: " + auth.cookieHttpOnly() + " | Class: " + "Boolean" + " | Should be type: " + "boolean");

        // secureSocial doesnt seem to set a maxAge or Domain so i set them myself.
        Cookie fakeCookie = new Cookie(auth.cookieName(), scalaCookie.value(), 120, scalaCookie.path(), "None", auth.cookieSecure(), auth.cookieHttpOnly());
        return fakeCookie;
    }
}

然后我只是在fakeRequest中使用我的cookie所以我登录后:

And then i simply use my cookie to in the fakeRequest so im logged in:

Cookie cookie = Utils.fakeCookie("user@example.com");

Result result = callAction(
        controllers.routes.ref.yourSampleClass.yourSecuredFucntion(),
        fakeRequest().withFormUrlEncodedBody(
                ImmutableMap.of("Value", "Some input value")).withCookies(cookie));

// Should return redirect status if successful
assertThat(status(result)).isEqualTo(SEE_OTHER);
assertThat(redirectLocation(result)).isEqualTo("/yourWantedResult");

希望这有助于其他人!

这篇关于使用Securesocial注释保护的单元测试方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆