check in hint service which provides a list of hints for the current lesson

This commit is contained in:
lawson89 2014-06-20 14:41:15 -04:00
parent c71931f43c
commit a90817f332
4 changed files with 834 additions and 876 deletions

View File

@ -1,4 +1,3 @@
package org.owasp.webgoat.lessons;
import java.io.BufferedReader;
@ -30,42 +29,41 @@ import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext;
import org.owasp.webgoat.session.WebgoatProperties;
import org.owasp.webgoat.util.WebGoatI18N;
/***************************************************************************************************
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository for free software
* projects.
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public abstract class AbstractLesson extends Screen implements Comparable<Object>
{
public abstract class AbstractLesson extends Screen implements Comparable<Object> {
/**
* Description of the Field
@ -101,7 +99,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
private String sourceFileName;
private Map<String,String> lessonPlanFileName = new HashMap<String,String>();
private Map<String, String> lessonPlanFileName = new HashMap<String, String>();
private String lessonSolutionFileName;
@ -114,29 +112,24 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
/**
* Constructor for the Lesson object
*/
public AbstractLesson()
{
public AbstractLesson() {
id = new Integer(++count);
}
public String getName()
{
public String getName() {
String className = getClass().getName();
return className.substring(className.lastIndexOf('.') + 1);
}
public void setRanking(Integer ranking)
{
public void setRanking(Integer ranking) {
this.ranking = ranking;
}
public void setHidden(boolean hidden)
{
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public void update(WebgoatProperties properties)
{
public void update(WebgoatProperties properties) {
String className = getClass().getName();
className = className.substring(className.lastIndexOf(".") + 1);
setRanking(new Integer(properties.getIntProperty("lesson." + className + ".ranking", getDefaultRanking()
@ -153,8 +146,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
// " + getRanking() + ", hidden:" + hidden +")");
}
public boolean isCompleted(WebSession s)
{
public boolean isCompleted(WebSession s) {
return getLessonTracker(s, this).getCompleted();
}
@ -168,24 +160,20 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
/**
* Description of the Method
*
* @param obj
* Description of the Parameter
* @param obj Description of the Parameter
* @return Description of the Return Value
*/
public int compareTo(Object obj)
{
public int compareTo(Object obj) {
return this.getRanking().compareTo(((AbstractLesson) obj).getRanking());
}
/**
* Description of the Method
*
* @param obj
* Description of the Parameter
* @param obj Description of the Parameter
* @return Description of the Return Value
*/
public boolean equals(Object obj)
{
public boolean equals(Object obj) {
return this.getScreenId() == ((AbstractLesson) obj).getScreenId();
}
@ -194,8 +182,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return The category value
*/
public Category getCategory()
{
public Category getCategory() {
return category;
}
@ -208,57 +195,45 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
/**
* Gets the fileMethod attribute of the Lesson class
*
* @param reader
* Description of the Parameter
* @param methodName
* Description of the Parameter
* @param numbers
* Description of the Parameter
* @param reader Description of the Parameter
* @param methodName Description of the Parameter
* @param numbers Description of the Parameter
* @return The fileMethod value
*/
public static String getFileMethod(BufferedReader reader, String methodName, boolean numbers)
{
public static String getFileMethod(BufferedReader reader, String methodName, boolean numbers) {
int count = 0;
StringBuffer sb = new StringBuffer();
boolean echo = false;
boolean startCount = false;
int parenCount = 0;
try
{
try {
String line;
while ((line = reader.readLine()) != null)
{
while ((line = reader.readLine()) != null) {
if ((line.indexOf(methodName) != -1)
&& ((line.indexOf("public") != -1) || (line.indexOf("protected") != -1) || (line
.indexOf("private") != -1)))
{
.indexOf("private") != -1))) {
echo = true;
startCount = true;
}
if (echo && startCount)
{
if (numbers)
{
if (echo && startCount) {
if (numbers) {
sb.append(pad(++count) + " ");
}
sb.append(line + "\n");
}
if (echo && (line.indexOf("{") != -1))
{
if (echo && (line.indexOf("{") != -1)) {
parenCount++;
}
if (echo && (line.indexOf("}") != -1))
{
if (echo && (line.indexOf("}") != -1)) {
parenCount--;
if (parenCount == 0)
{
if (parenCount == 0) {
startCount = false;
echo = false;
}
@ -266,8 +241,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
}
reader.close();
} catch (Exception e)
{
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
@ -276,51 +250,41 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
}
/**
* Reads text from a file into an ElementContainer. Each line in the file is represented in the
* ElementContainer by a StringElement. Each StringElement is appended with a new-line
* character.
* Reads text from a file into an ElementContainer. Each line in the file is
* represented in the ElementContainer by a StringElement. Each
* StringElement is appended with a new-line character.
*
* @param reader
* Description of the Parameter
* @param numbers
* Description of the Parameter
* @param reader Description of the Parameter
* @param numbers Description of the Parameter
* @return Description of the Return Value
*/
public static String readFromFile(BufferedReader reader, boolean numbers)
{
public static String readFromFile(BufferedReader reader, boolean numbers) {
return (getFileText(reader, numbers));
}
/**
* Gets the fileText attribute of the Screen class
*
* @param reader
* Description of the Parameter
* @param numbers
* Description of the Parameter
* @param reader Description of the Parameter
* @param numbers Description of the Parameter
* @return The fileText value
*/
public static String getFileText(BufferedReader reader, boolean numbers)
{
public static String getFileText(BufferedReader reader, boolean numbers) {
int count = 0;
StringBuffer sb = new StringBuffer();
try
{
try {
String line;
while ((line = reader.readLine()) != null)
{
if (numbers)
{
while ((line = reader.readLine()) != null) {
if (numbers) {
sb.append(pad(++count) + " ");
}
sb.append(line + System.getProperty("line.separator"));
}
reader.close();
} catch (Exception e)
{
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
@ -333,37 +297,39 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return The ranking value
*/
public boolean isEnterprise()
{
public boolean isEnterprise() {
return false;
}
/**
* Gets the hintCount attribute of the Lesson object
*
* @param s
* The user's WebSession
* @param s The user's WebSession
*
* @return The hintCount value
*/
public int getHintCount(WebSession s)
{
public int getHintCount(WebSession s) {
return getHints(s).size();
}
protected abstract List<String> getHints(WebSession s);
// @TODO we need to restrict access at the service layer
// rather than passing session object around
public List<String> getHintsPublic(WebSession s){
List<String> hints = getHints(s);
return hints;
}
/**
* Fill in a minor hint that will help people who basically get it, but are stuck on somthing
* silly.
* Fill in a minor hint that will help people who basically get it, but are
* stuck on somthing silly.
*
* @param s
* The users WebSession
* @param s The users WebSession
*
* @return The hint1 value
*/
public String getHint(WebSession s, int hintNumber)
{
public String getHint(WebSession s, int hintNumber) {
return "Hint: " + getHints(s).get(hintNumber);
}
@ -379,8 +345,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return The lessonPlan value
*/
protected String getLessonName()
{
protected String getLessonName() {
int index = this.getClass().getName().indexOf("lessons.");
return this.getClass().getName().substring(index + "lessons.".length());
}
@ -395,33 +360,29 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
/**
* Gets the content of lessonPlanURL
*
* @param s
* The user's WebSession
* @param s The user's WebSession
*
* @return The HTML content of the current lesson plan
*/
public String getLessonPlan(WebSession s)
{
public String getLessonPlan(WebSession s) {
StringBuffer src = new StringBuffer();
String lang = s.getCurrrentLanguage();
try
{
try {
// System.out.println("Loading lesson plan file: " +
// getLessonPlanFileName());
String filename = getLessonPlanFileName(lang);
if(filename==null){
if (filename == null) {
filename = getLessonPlanFileName(getDefaultLanguage());
}
src.append(readFromFile(new BufferedReader(new FileReader(s.getWebResource(filename))), false));
} catch (Exception e)
{
} catch (Exception e) {
// s.setMessage( "Could not find lesson plan for " +
// getLessonName());
src = new StringBuffer("Could not find lesson plan for: " + getLessonName()+" and language "+lang);
src = new StringBuffer("Could not find lesson plan for: " + getLessonName() + " and language " + lang);
}
return src.toString();
@ -432,14 +393,10 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return The ranking value
*/
public Integer getRanking()
{
if (ranking != null)
{
public Integer getRanking() {
if (ranking != null) {
return ranking;
}
else
{
} else {
return getDefaultRanking();
}
}
@ -449,8 +406,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return The hidden value
*/
public boolean getHidden()
{
public boolean getHidden() {
return this.hidden;
}
@ -459,8 +415,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return The role value
*/
public String getRole()
{
public String getRole() {
// FIXME: Each lesson should have a role assigned to it. Each
// user/student
// should also have a role(s) assigned. The user would only be allowed
@ -478,13 +433,11 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return The uniqueID value
*/
public int getScreenId()
{
public int getScreenId() {
return id.intValue();
}
public String getHtml_DELETE_ME(WebSession s)
{
public String getHtml_DELETE_ME(WebSession s) {
String html = null;
// FIXME: This doesn't work for the labs since they do not implement
@ -499,13 +452,11 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
return html;
}
public String getSource(WebSession s)
{
public String getSource(WebSession s) {
String source = null;
String src = null;
try
{
try {
// System.out.println("Loading source file: " +
// getSourceFileName());
src = convertMetacharsJavaCode(readFromFile(new BufferedReader(new FileReader(s
@ -516,8 +467,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
// that performs the convertMetacharsJavaCode() transform plus
// optionally adds a styled
// line number. Wouldn't color syntax be great too?
} catch (Exception e)
{
} catch (Exception e) {
s.setMessage("Could not find source file");
src = ("Could not find the source file or source file does not exist.<br/>"
+ "Send this message to: <a href=\"mailto:" + s.getWebgoatContext().getFeedbackAddress()
@ -541,16 +491,13 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
return source;
}
public String getSolution(WebSession s)
{
public String getSolution(WebSession s) {
String src = null;
try
{
try {
// System.out.println("Solution: " + getLessonSolutionFileName());
src = readFromFile(new BufferedReader(new FileReader(s.getWebResource(getLessonSolutionFileName()))), false);
} catch (Exception e)
{
} catch (Exception e) {
s.setMessage("Could not find the solution file");
src = ("Could not find the solution file or solution file does not exist.<br/>"
+ "Send this message to: <a href=\"mailto:" + s.getWebgoatContext().getFeedbackAddress()
@ -562,15 +509,18 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
return src;
}
/**
* <p>Returns the default "path" portion of a lesson's URL.</p>
* <p>
* Returns the default "path" portion of a lesson's URL.</p>
*
* <p>Legacy webgoat lesson links are of the form "attack?Screen=Xmenu=Ystage=Z".
* This method returns the path portion of the url, i.e., "attack" in the string above.</p>
* <p>
* Legacy webgoat lesson links are of the form
* "attack?Screen=Xmenu=Ystage=Z". This method returns the path portion of
* the url, i.e., "attack" in the string above.</p>
*
* <p>Newer, Spring-Controller-based classes will override this method
* to return "*.do"-styled paths.</p>
* <p>
* Newer, Spring-Controller-based classes will override this method to
* return "*.do"-styled paths.</p>
*/
protected String getPath() {
return "attack";
@ -581,8 +531,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return
*/
public String getLink()
{
public String getLink() {
StringBuffer link = new StringBuffer();
// mvc update:
@ -602,8 +551,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return
*/
public String getPage(WebSession s)
{
public String getPage(WebSession s) {
return null;
}
@ -612,8 +560,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*
* @return
*/
public String getTemplatePage(WebSession s)
{
public String getTemplatePage(WebSession s) {
return null;
}
@ -628,8 +575,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
* @param functionId
* @return
*/
public boolean isAuthorized(WebSession s, int employeeId, String functionId)
{
public boolean isAuthorized(WebSession s, int employeeId, String functionId) {
return false;
}
@ -640,50 +586,41 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
* @param functionId
* @return
*/
public boolean isAuthorized(WebSession s, String role, String functionId)
{
public boolean isAuthorized(WebSession s, String role, String functionId) {
boolean authorized = false;
try
{
try {
String query = "SELECT * FROM auth WHERE role = '" + role + "' and functionid = '" + functionId + "'";
try
{
try {
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
authorized = answer_results.first();
} catch (SQLException sqle)
{
} catch (SQLException sqle) {
s.setMessage("Error authorizing");
sqle.printStackTrace();
}
} catch (Exception e)
{
} catch (Exception e) {
s.setMessage("Error authorizing");
e.printStackTrace();
}
return authorized;
}
public int getUserId(WebSession s) throws ParameterNotFoundException
{
public int getUserId(WebSession s) throws ParameterNotFoundException {
return -1;
}
public String getUserName(WebSession s) throws ParameterNotFoundException
{
public String getUserName(WebSession s) throws ParameterNotFoundException {
return null;
}
/**
* Description of the Method
*
* @param windowName
* Description of the Parameter
* @param windowName Description of the Parameter
* @return Description of the Return Value
*/
public static String makeWindowScript(String windowName)
{
public static String makeWindowScript(String windowName) {
// FIXME: make this string static
StringBuffer script = new StringBuffer();
script.append("<script language=\"JavaScript\">\n");
@ -720,32 +657,27 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
}
/**
* Simply reads a url into an Element for display. CAUTION: you might want to tinker with any
* non-https links (href)
* Simply reads a url into an Element for display. CAUTION: you might want
* to tinker with any non-https links (href)
*
* @param url
* Description of the Parameter
* @param url Description of the Parameter
* @return Description of the Return Value
*/
public static Element readFromURL(String url)
{
public static Element readFromURL(String url) {
ElementContainer ec = new ElementContainer();
try
{
try {
URL u = new URL(url);
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(huc.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
{
while ((line = reader.readLine()) != null) {
ec.addElement(new StringElement(line));
}
reader.close();
} catch (Exception e)
{
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
@ -756,16 +688,12 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
/**
* Description of the Method
*
* @param reader
* Description of the Parameter
* @param numbers
* Description of the Parameter
* @param methodName
* Description of the Parameter
* @param reader Description of the Parameter
* @param numbers Description of the Parameter
* @param methodName Description of the Parameter
* @return Description of the Return Value
*/
public static Element readMethodFromFile(BufferedReader reader, String methodName, boolean numbers)
{
public static Element readMethodFromFile(BufferedReader reader, String methodName, boolean numbers) {
PRE pre = new PRE().addElement(getFileMethod(reader, methodName, numbers));
return (pre);
@ -774,11 +702,9 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param s Description of the Parameter
*/
public void handleRequest(WebSession s)
{
public void handleRequest(WebSession s) {
// call createContent first so messages will go somewhere
Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType("");
@ -788,74 +714,64 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
setContent(form);
}
public String getFormAction()
{
public String getFormAction() {
return getLink();
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param s Description of the Parameter
* @return Description of the Return Value
*/
public String toString()
{
public String toString() {
return getTitle();
}
public String getDefaultLanguage(){
public String getDefaultLanguage() {
return this.defaultLanguage;
}
public String getLessonPlanFileName(String lang)
{
public String getLessonPlanFileName(String lang) {
String ret = lessonPlanFileName.get(lang);
if(ret==null) ret = lessonPlanFileName.get(getDefaultLanguage());
if (ret == null) {
ret = lessonPlanFileName.get(getDefaultLanguage());
}
return ret;
}
public void setLessonPlanFileName(String lang, String lessonPlanFileName)
{
this.lessonPlanFileName.put(lang,lessonPlanFileName);
public void setLessonPlanFileName(String lang, String lessonPlanFileName) {
this.lessonPlanFileName.put(lang, lessonPlanFileName);
this.availableLanguages.add(lang);
}
public List<String> getAvailableLanguages(){
public List<String> getAvailableLanguages() {
return this.availableLanguages;
}
public String getLessonSolutionFileName()
{
public String getLessonSolutionFileName() {
return lessonSolutionFileName;
}
public void setLessonSolutionFileName(String lessonSolutionFileName)
{
public void setLessonSolutionFileName(String lessonSolutionFileName) {
this.lessonSolutionFileName = lessonSolutionFileName;
}
public String getSourceFileName()
{
public String getSourceFileName() {
return sourceFileName;
}
public void setSourceFileName(String sourceFileName)
{
public void setSourceFileName(String sourceFileName) {
// System.out.println("Setting source file of lesson " + this + " to: "
// + sourceFileName);
this.sourceFileName = sourceFileName;
}
public WebgoatContext getWebgoatContext()
{
public WebgoatContext getWebgoatContext() {
return webgoatContext;
}
public void setWebgoatContext(WebgoatContext webgoatContext)
{
public void setWebgoatContext(WebgoatContext webgoatContext) {
this.webgoatContext = webgoatContext;
}
}

View File

@ -5,7 +5,13 @@
*/
package org.owasp.webgoat.service;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.model.Hint;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@ -17,13 +23,40 @@ import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HintService extends BaseService {
/**
* Returns hints for current lesson
*
* @param session
* @return
*/
@RequestMapping(value = "/hint.do", produces = "application/json")
public @ResponseBody
Hint showHint() {
Hint h = new Hint();
h.setHint("This is a test hint");
h.setLesson("Some lesson");
h.setNumber(1);
return h;
List<Hint> showHint(HttpSession session) {
List<Hint> listHints = new ArrayList<Hint>();
WebSession ws;
Object o = session.getAttribute(WebSession.SESSION);
if (o == null || !(o instanceof WebSession)) {
return null;
}
ws = (WebSession) o;
AbstractLesson l = ws.getCurrentLesson();
if (l == null) {
return listHints;
}
List<String> hints;
hints = l.getHintsPublic(ws);
if (hints == null) {
return listHints;
}
int idx = 0;
for (String h : hints) {
Hint hint = new Hint();
hint.setHint(h);
hint.setLesson(l.getName());
hint.setNumber(idx);
listHints.add(hint);
idx++;
}
return listHints;
}
}

View File

@ -269,6 +269,15 @@ public class Course {
return getLessons(category, roles);
}
public AbstractLesson getLesson(int lessonId) {
for (AbstractLesson l : lessons) {
if (l.getScreenId() == lessonId) {
return l;
}
}
return null;
}
/**
* Load all of the filenames into a temporary cache
*