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

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

问题描述

我正在尝试对使用 Play 2.1.4 和 Socialsecure 的网络应用程序进行一些功能测试.在使用 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 扩展 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?

最好的问候拉瓦

推荐答案

感谢 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

我是这样解决的:

为了进行单元测试,我在数据库中创建了一个本地用户,使用 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");

希望这对其他人有帮助!

Hope this helps others!

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

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