Coverage Report - controllers.Secure
 
Classes in this File Line Coverage Branch Coverage Complexity
Secure
0 %
0/52
0 %
0/28
2,267
Secure$Security
0 %
0/19
0 %
0/4
2,267
 
 1  
 package controllers;
 2  
 
 3  
 import java.lang.reflect.InvocationTargetException;
 4  
 import java.util.List;
 5  
 import play.Play;
 6  
 import play.mvc.*;
 7  
 import play.data.validation.*;
 8  
 import play.libs.*;
 9  
 import play.utils.*;
 10  
 
 11  0
 public class Secure extends Controller {
 12  
 
 13  
     @Before(unless={"login", "authenticate", "logout"})
 14  
     static void checkAccess() throws Throwable {
 15  
         // Authent
 16  0
         if(!session.contains("username")) {
 17  0
             flash.put("url", request.method == "GET" ? request.url : "/"); // seems a good default
 18  0
             login();
 19  
         }
 20  
         // Checks
 21  0
         Check check = getActionAnnotation(Check.class);
 22  0
         if(check != null) {
 23  0
             check(check);
 24  
         }
 25  0
         check = getControllerInheritedAnnotation(Check.class);
 26  0
         if(check != null) {
 27  0
             check(check);
 28  
         }
 29  0
     }
 30  
 
 31  
     private static void check(Check check) throws Throwable {
 32  0
         for(String profile : check.value()) {
 33  0
             boolean hasProfile = (Boolean)Security.invoke("check", profile);
 34  0
             if(!hasProfile) {
 35  0
                 Security.invoke("onCheckFailed", profile);
 36  
             }
 37  
         }
 38  0
     }
 39  
     
 40  
     // ~~~ Login
 41  
 
 42  
     public static void login() throws Throwable {
 43  0
         Http.Cookie remember = request.cookies.get("rememberme");
 44  0
         if(remember != null && remember.value.indexOf("-") > 0) {
 45  0
             String sign = remember.value.substring(0, remember.value.indexOf("-"));
 46  0
             String username = remember.value.substring(remember.value.indexOf("-") + 1);
 47  0
             if(Crypto.sign(username).equals(sign)) {
 48  0
                 session.put("username", username);
 49  0
                 redirectToOriginalURL();
 50  
             }
 51  
         }
 52  0
         flash.keep("url");
 53  0
         render();
 54  0
     }
 55  
 
 56  
     public static void authenticate(@Required String username, String password, boolean remember) throws Throwable {
 57  
         // Check tokens
 58  0
         Boolean allowed = false;
 59  
         try {
 60  
             // This is the deprecated method name
 61  0
             allowed = (Boolean)Security.invoke("authentify", username, password);
 62  0
         } catch (UnsupportedOperationException e ) {
 63  
             // This is the official method name
 64  0
             allowed = (Boolean)Security.invoke("authenticate", username, password);
 65  
         }
 66  0
         if(validation.hasErrors() || !allowed) {
 67  0
             flash.keep("url");
 68  0
             flash.error("secure.error");
 69  0
             params.flash();
 70  0
             login();
 71  
         }
 72  
         // Mark user as connected
 73  0
         session.put("username", username);
 74  
         // Remember if needed
 75  0
         if(remember) {
 76  0
             response.setCookie("rememberme", Crypto.sign(username) + "-" + username, "30d");
 77  
         }
 78  
         // Redirect to the original URL (or /)
 79  0
         redirectToOriginalURL();
 80  0
     }
 81  
 
 82  
     public static void logout() throws Throwable {
 83  0
         session.clear();
 84  0
         response.setCookie("rememberme", "", 0);
 85  0
         Security.invoke("onDisconnected");
 86  0
         flash.success("secure.logout");
 87  0
         login();
 88  0
     }
 89  
     
 90  
     // ~~~ Utils
 91  
     
 92  
     static void redirectToOriginalURL() throws Throwable {
 93  0
         Security.invoke("onAuthenticated");
 94  0
         String url = flash.get("url");
 95  0
         if(url == null) {
 96  0
             url = "/";
 97  
         }
 98  0
         redirect(url);
 99  0
     }
 100  
 
 101  0
     public static class Security extends Controller {
 102  
 
 103  
         /**
 104  
          * @Deprecated
 105  
          * 
 106  
          * @param username
 107  
          * @param password
 108  
          * @return
 109  
          */
 110  
         static boolean authentify(String username, String password) {
 111  0
             throw new UnsupportedOperationException();
 112  
         }
 113  
 
 114  
         /**
 115  
          * This method is called during the authentication process. This is where you check if
 116  
          * the user is allowed to log in into the system. This is the actual authentication process
 117  
          * against a third party system (most of the time a DB).
 118  
          *
 119  
          * @param username
 120  
          * @param password
 121  
          * @return true if the authentication process succeeded
 122  
          */
 123  
         static boolean authenticate(String username, String password) {
 124  0
             return true;
 125  
         }
 126  
 
 127  
         /**
 128  
          * This method checks that a profile is allowed to view this page/method. This method is called prior
 129  
          * to the method's controller annotated with the @Check method. 
 130  
          *
 131  
          * @param profile
 132  
          * @return true if you are allowed to execute this controller method.
 133  
          */
 134  
         static boolean check(String profile) {
 135  0
             return true;
 136  
         }
 137  
 
 138  
         /**
 139  
          * This method returns the current connected username
 140  
          * @return
 141  
          */
 142  
         static String connected() {
 143  0
             return session.get("username");
 144  
         }
 145  
 
 146  
         /**
 147  
          * Indicate if a user is currently connected
 148  
          * @return  true if the user is connected
 149  
          */
 150  
         static boolean isConnected() {
 151  0
             return session.contains("username");
 152  
         }
 153  
 
 154  
         /**
 155  
          * This method is called after a successful authentication.
 156  
          * You need to override this method if you with to perform specific actions (eg. Record the time the user signed in)
 157  
          */
 158  
         static void onAuthenticated() {
 159  0
         }
 160  
 
 161  
          /**
 162  
          * This method is called after a successful sign off.
 163  
          * You need to override this method if you with to perform specific actions (eg. Record the time the user signed off)
 164  
          */
 165  
         static void onDisconnected() {
 166  0
         }
 167  
 
 168  
         /**
 169  
          * This method is called if a check does not succeed. By default it shows the not allowed page (the controller forbidden method).
 170  
          * @param profile
 171  
          */
 172  
         static void onCheckFailed(String profile) {
 173  0
             forbidden();
 174  0
         }
 175  
 
 176  0
         private static Object invoke(String m, Object... args) throws Throwable {
 177  0
             Class security = null;
 178  0
             List<Class> classes = Play.classloader.getAssignableClasses(Security.class);
 179  0
             if(classes.size() == 0) {
 180  0
                 security = Security.class;
 181  
             } else {
 182  0
                 security = classes.get(0);
 183  
             }
 184  
             try {
 185  0
                 return Java.invokeStaticOrParent(security, m, args);
 186  0
             } catch(InvocationTargetException e) {
 187  0
                 throw e.getTargetException();
 188  
             }
 189  
         }
 190  
 
 191  
     }
 192  
 
 193  
 }