<commit_before>package foam.nanos.auth;

import foam.core.X;
import javax.security.auth.AuthPermission;
import javax.security.auth.login.LoginException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
/**
 * Created by marcroopchand on 2017-05-24.
 */

public class UserAndGroupAuthServiceTest extends CachedUserAndGroupAuthService {
  private int numUsers = 1000000;
  private ArrayList<X> xArray = new ArrayList<>();
  private Group adminGroup = new Group();
  private Group memberGroup = new Group();

  @Override
  public void start() {
    super.start();
    createGroupsAndPermissions();
    addTestUsers();
    testlogin();
    testCheck();
    testCheck();
    testChallengedLogin();
    testUpdatePassword();
  }

  /**
   * Setup two groups and two different permissions for each group
   *  Admin
   *    - Admin Permission 1
   *    - Admin Permission 2
   *  Member
   *    - Member Permission 1
   *    - Member Permission 2
   * */
  public void createGroupsAndPermissions() {
    /**
     * Admin group with some permissions
     * */
    adminGroup.setId("1");
    adminGroup.setDescription("Admin Users");

    foam.nanos.auth.Permission adminPermission1 = new foam.nanos.auth.Permission();
    adminPermission1.setId("1");
    adminPermission1.setDescription("Admin permissions 1");

    foam.nanos.auth.Permission adminPermission2 = new foam.nanos.auth.Permission();
    adminPermission2.setId("2");
    adminPermission2.setDescription("Admin permissions 2");

    Permission[] adminPermissions = {adminPermission1, adminPermission2};
    adminGroup.setPermissions(adminPermissions);
    groupDAO_.put(adminGroup);

    /**
     * Memeber group with some permissions
     * */
    memberGroup.setId("2");
    memberGroup.setDescription("Member Users");

    foam.nanos.auth.Permission memberPermission1 = new foam.nanos.auth.Permission();
    memberPermission1.setId("3");
    memberPermission1.setDescription("Member permisssions 1");

    foam.nanos.auth.Permission memberPermission2 = new foam.nanos.auth.Permission();
    memberPermission2.setId("4");
    memberPermission2.setDescription("Member permisssion 2");

    Permission[] memberPermissions = {memberPermission1, memberPermission2};
    memberGroup.setPermissions(memberPermissions);
    groupDAO_.put(memberGroup);
  }

  public void addTestUsers() {
    System.out.println("Registering 1 million Users");
    long startTime = System.nanoTime();

    for (int i = 0; i < numUsers; i++) {
      User user = new User();
      user.setId("" + i);
      user.setEmail("marc" + i + "@<EMAIL>.<EMAIL>");
      user.setFirstName("Marc" + i);
      user.setLastName("R" + i);
      user.setPassword("<PASSWORD>);

      /**
       * Just set 3 users as admin for now, everyone
       * else will be members
       * */
      if (i == 5 || i == 15 || i == 20) {
        user.setGroup(adminGroup);
      }
      else {
        user.setGroup(memberGroup);
      }

      userDAO_.put(user);
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testlogin() {
    System.out.println("Login 1 million Users");
    long startTime = System.nanoTime();

    for (int i = 0; i < numUsers; i++) {
      try {
        xArray.add(login("" + i, "marc" + i));
      }
      catch (LoginException e) {
        e.printStackTrace();
      }
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testCheck() {
    System.out.println("Permissions Check for 1 million users");
    long startTime = System.nanoTime();

    /**
     * Go through all logged in users and check if a user has the permission above
     * */
    for (int i = 0; i < xArray.size(); i++) {
      AuthPermission authAdminpermission = new AuthPermission(adminGroup.getPermissions()[0].getId());
      check(xArray.get(i), authAdminpermission);
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testChallengedLogin() {
    System.out.println("Challenge Login 1 million Users");
    long startTime = System.nanoTime();

    for (int i = 0; i < numUsers; i++) {
      try {
        challengedLogin("" + i, generateChallenge("" + i));
      }
      catch (LoginException e) {
        e.printStackTrace();
      }
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testChallengedLoginWithExpiredChallenge() {
    try {
      String challenge = generateChallenge("0");
      TimeUnit.SECONDS.sleep(6);

      challengedLogin("0", challenge);
    }
    catch (LoginException e) {
      e.printStackTrace();
    }
    catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public void testUpdatePassword() {
    System.out.println("Update Password for 1 million Users");
    long startTime = System.nanoTime();

    for (int i = 0; i < numUsers; i++) {
      try {
        X x = login("" + i, "marc" + i);
        updatePassword(x, "marc" + i, "<PASSWORD>");
      }
      catch (LoginException e) {
        e.printStackTrace();
      }
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testLogout() {
    try {
      X x = login("0", "marc0");
      logout(x);
    }<commit_msg>Made creation of groups and permissions more modular, also randomly assinged a user to a graup with a random permission<commit_after>package foam.nanos.auth;

import foam.core.X;
import foam.dao.ListSink;
import javax.security.auth.AuthPermission;
import javax.security.auth.login.LoginException;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
 * Created by marcroopchand on 2017-05-24.
 */

public class UserAndGroupAuthServiceTest extends CachedUserAndGroupAuthService {
  private int numUsers = 1000000;
  private int numGroups = 10;
  private int numPermissions = 100;
  private ArrayList<X> xArray = new ArrayList<>();

  @Override
  public void start() {
    super.start();
    createGroupsAndPermissions();
    addTestUsers();
    testlogin();
    testCheck();
    testChallengedLogin();
    testUpdatePassword();
  }

  public void createGroupsAndPermissions() {
    System.out.println("Creating " + numGroups + " groups with " + numPermissions + " permissions each");
    long startTime = System.nanoTime();

    for ( int i = 0; i < numGroups; i++ ) {
      Group group = new Group();
      group.setId("" + i);
      group.setDescription("Group " + i + " users");

      Permission[] permissions = new Permission[numPermissions];
      for ( int j = 0; j < numPermissions; j++ ) {
        foam.nanos.auth.Permission permission = new foam.nanos.auth.Permission();
        permission.setId("" + j);
        permission.setDescription("Group" + i + " permissions-" + j);
        permissions[j] = permission;
      }

      group.setPermissions(permissions);
      groupDAO_.put(group);
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void addTestUsers() {
    System.out.println("Registering " + numUsers + " Users");
    long startTime = System.nanoTime();

    ListSink sink = (ListSink) groupDAO_.select(new ListSink(), null, null, null, null);

    for ( int i = 0; i < numUsers; i++ ) {
      User user = new User();
      user.setId("" + i);
      user.setEmail("marc" + i + "@nanopay.net");
      user.setFirstName("Marc" + i);
      user.setLastName("R" + i);
      user.setPassword("<PASSWORD>);

      /**
       * Generate a random number to put a user in a group
       * */
      int randomGroup = ThreadLocalRandom.current().nextInt(0, sink.getData().size());
      Group group = (Group) sink.getData().get(randomGroup);

      user.setGroup(group);
      userDAO_.put(user);
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testlogin() {
    System.out.println("Login " + numUsers + " Users");
    long startTime = System.nanoTime();

    for ( int i = 0; i < numUsers; i++ ) {
      try {
        xArray.add(login("" + i, "marc" + i));
      }
      catch ( LoginException e ) {
        e.printStackTrace();
      }
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testCheck() {
    System.out.println("Permissions Check for " + numUsers + " users");
    long startTime = System.nanoTime();

    ListSink sink = (ListSink) groupDAO_.select(new ListSink(), null, null, null, null);

    ArrayList<Integer> groups = new ArrayList<>();
    ArrayList<Integer> permissions = new ArrayList<>();

    for ( int i = 0; i < xArray.size(); i++ ) {
      int randomGroup = ThreadLocalRandom.current().nextInt(0, sink.getData().size());
      groups.add(randomGroup);
      Group group = (Group) sink.getData().get(randomGroup);

      int randomPermission = ThreadLocalRandom.current().nextInt(0, group.getPermissions().length);
      permissions.add(randomPermission);
      Permission permission = group.getPermissions()[randomPermission];

      AuthPermission authAdminpermission = new AuthPermission(permission.getId());
      check(xArray.get(i), authAdminpermission);
    }
    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");


    System.out.println("Cached Permissions Check for " + numUsers + " users");
    startTime = System.nanoTime();

    for ( int i = 0; i < xArray.size(); i++ ) {
      Group group = (Group) sink.getData().get(groups.get(i));
      Permission permission = group.getPermissions()[permissions.get(i)];

      AuthPermission authAdminpermission = new AuthPermission(permission.getId());
      check(xArray.get(i), authAdminpermission);
    }

    endTime = System.nanoTime();
    durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testChallengedLogin() {
    System.out.println("Challenge Login " + numUsers + " Users");
    long startTime = System.nanoTime();

    for ( int i = 0; i < numUsers; i++ ) {
      try {
        challengedLogin("" + i, generateChallenge("" + i));
      }
      catch (LoginException e) {
        e.printStackTrace();
      }
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testChallengedLoginWithExpiredChallenge() {
    try {
      String challenge = generateChallenge("0");
      TimeUnit.SECONDS.sleep(6);

      challengedLogin("0", challenge);
    }
    catch (LoginException e) {
      e.printStackTrace();
    }
    catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public void testUpdatePassword() {
    System.out.println("Update Password for " + numUsers + " Users");
    long startTime = System.nanoTime();

    for ( int i = 0; i < numUsers; i++ ) {
      try {
        X x = login("" + i, "marc" + i);
        updatePassword(x, "marc" + i, "<PASSWORD>");
      }
      catch (LoginException e) {
        e.printStackTrace();
      }
    }

    long endTime = System.nanoTime();
    long durationInMilliseconds = (endTime - startTime) / 1000000;
    System.out.println("Duration: " + durationInMilliseconds + "ms \n");
  }

  public void testLogout() {
    try {
      X x = login("0", "marc0");
      logout(x);
    }
{'fraction_non_alphanumeric': 0.13521400778210116, 'fraction_numerical': 0.015158884565499351, 'mean_word_length': 3.022497554613629, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3519236', 'n_tokens_mistral': 3854, 'n_tokens_neox': 3658, 'n_words': 875}