This commit is contained in:
Erik C. Thauvin 2019-09-24 21:15:16 -07:00
parent 32fd9c3c57
commit 6f47f40bd1
5 changed files with 124 additions and 115 deletions

View file

@ -6,7 +6,7 @@ import java.util.Date
import kotlin.system.exitProcess import kotlin.system.exitProcess
fun main() { fun main() {
val akismet = Akismet("YOUR_API_KEY", "http://yourblogdomainname.com/blog/") val akismet = Akismet(apiKey = "YOUR_API_KEY", blog = "http://yourblogdomainname.com/blog/")
val comment = AkismetComment(userIp = "127.0.0.1", userAgent = "curl/7.29.0") val comment = AkismetComment(userIp = "127.0.0.1", userAgent = "curl/7.29.0")
with(comment) { with(comment) {

View file

@ -5,10 +5,12 @@ import net.thauvin.erik.akismet.AkismetComment
import java.io.IOException import java.io.IOException
import java.util.Date import java.util.Date
import javax.servlet.ServletException import javax.servlet.ServletException
import javax.servlet.annotation.WebServlet
import javax.servlet.http.HttpServlet import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse import javax.servlet.http.HttpServletResponse
@WebServlet(description = "Akismet Servlet", displayName = "Akismet", urlPatterns = ["/comment/*"])
class AkismetServlet : HttpServlet() { class AkismetServlet : HttpServlet() {
private val akismet = Akismet("YOUR_API_KEY", "http://yourblogdomainname.com/blog/") private val akismet = Akismet("YOUR_API_KEY", "http://yourblogdomainname.com/blog/")
@ -17,7 +19,7 @@ class AkismetServlet : HttpServlet() {
val id = request.getParameter("id") val id = request.getParameter("id")
akismet.appUserAgent = request.servletContext.serverInfo akismet.appUserAgent = request.servletContext.serverInfo
val comment = AkismetComment(request) val comment = AkismetComment(request)
with(comment) { with(comment) {
permalink = "${akismet.blog}/comment/$id" permalink = "${akismet.blog}/comment/$id"

View file

@ -208,7 +208,7 @@ open class Akismet(apiKey: String) {
require( require(
(apiKey.isNotBlank() && (apiKey.isNotBlank() &&
apiKey.length == 12 && apiKey.length == 12 &&
apiKey.matches(Regex("[A-Za-z0-9]+"))) apiKey.matches(Regex("[A-Za-z0-9\\-]+")))
) { ) {
"An Akismet API key must be specified." "An Akismet API key must be specified."
} }

View file

@ -193,7 +193,7 @@ open class AkismetComment(val userIp: String, val userAgent: String) {
* @see [serverEnv] * @see [serverEnv]
*/ */
constructor(request: HttpServletRequest) : this( constructor(request: HttpServletRequest) : this(
request.remoteAddr.ifNull(), request.remoteAddr,
request.getHeader("User-Agent").ifNull() request.getHeader("User-Agent").ifNull()
) { ) {
referrer = request.getHeader("referer").ifNull() referrer = request.getHeader("referer").ifNull()
@ -266,17 +266,13 @@ open class AkismetComment(val userIp: String, val userAgent: String) {
} }
} }
private fun buildServerEnv(request: HttpServletRequest): HashMap<String, String> { private fun buildServerEnv(request: HttpServletRequest): Map<String, String> {
val params = HashMap<String, String>() val params = HashMap<String, String>()
if (request.remoteAddr != null) params["REMOTE_ADDR"] = request.remoteAddr
params["REMOTE_ADDR"] = request.remoteAddr params["REQUEST_URI"] = request.requestURI
if (request.requestURI != null)
params["REQUEST_URI"] = request.requestURI
val names = request.headerNames for (name in request.headerNames) {
while (names.hasMoreElements()) {
val name = names.nextElement()
if (!name.equals("cookie", true)) { if (!name.equals("cookie", true)) {
params["HTTP_${name.toUpperCase().replace('-', '_')}"] = request.getHeader(name).ifNull() params["HTTP_${name.toUpperCase().replace('-', '_')}"] = request.getHeader(name).ifNull()
} }

View file

@ -95,35 +95,39 @@ class AkismetTest {
level = Level.FINE level = Level.FINE
} }
comment.referrer = referer with(comment) {
comment.permalink = "http://yourblogdomainname.com/blog/post=1" referrer = referer
comment.type = AkismetComment.TYPE_COMMENT permalink = "http://yourblogdomainname.com/blog/post=1"
comment.author = "admin" type = AkismetComment.TYPE_COMMENT
comment.authorEmail = "test@test.com" author = "admin"
comment.authorUrl = "http://www.CheckOutMyCoolSite.com" authorEmail = "test@test.com"
comment.content = "It means a lot that you would take the time to review our software. Thanks again." authorUrl = "http://www.CheckOutMyCoolSite.com"
comment.dateGmt = Akismet.dateToGmt(date) content = "It means a lot that you would take the time to review our software. Thanks again."
comment.postModifiedGmt = comment.dateGmt dateGmt = Akismet.dateToGmt(date)
comment.blogLang = "en" postModifiedGmt = dateGmt
comment.blogCharset = "UTF-8" blogLang = "en"
comment.userRole = AkismetComment.ADMIN_ROLE blogCharset = "UTF-8"
comment.isTest = true userRole = AkismetComment.ADMIN_ROLE
isTest = true
}
akismet.logger.info(comment.toString()) akismet.logger.info(comment.toString())
mockComment.permalink = comment.permalink with(mockComment) {
mockComment.type = comment.type permalink = comment.permalink
mockComment.authorEmail = comment.authorEmail type = comment.type
mockComment.author = comment.author authorEmail = comment.authorEmail
mockComment.authorUrl = comment.authorUrl author = comment.author
mockComment.content = comment.content authorUrl = comment.authorUrl
mockComment.dateGmt = comment.dateGmt content = comment.content
mockComment.postModifiedGmt = comment.dateGmt dateGmt = comment.dateGmt
mockComment.blogLang = comment.blogLang postModifiedGmt = comment.dateGmt
mockComment.blogCharset = comment.blogCharset blogLang = comment.blogLang
mockComment.userRole = comment.userRole blogCharset = comment.blogCharset
mockComment.recheckReason = "edit" userRole = comment.userRole
mockComment.isTest = true recheckReason = "edit"
isTest = true
}
akismet.logger.info(mockComment.toString()) akismet.logger.info(mockComment.toString())
} }
@ -158,28 +162,29 @@ class AkismetTest {
@Test @Test
fun verifyKeyTest() { fun verifyKeyTest() {
assertFalse(akismet.isVerifiedKey, "isVerifiedKey -> false") with(akismet) {
assertFalse(isVerifiedKey, "isVerifiedKey -> false")
assertTrue(akismet.verifyKey(), "verifyKey()") assertTrue(verifyKey(), "verifyKey()")
assertEquals(akismet.response, "valid", "response -> valid") assertEquals(response, "valid", "response -> valid")
assertTrue(akismet.isVerifiedKey, "isVerifiedKey -> true") assertTrue(isVerifiedKey, "isVerifiedKey -> true")
akismet.reset() reset()
assertTrue( assertTrue(!isVerifiedKey && response.isEmpty() && httpStatusCode == 0, " reset")
!akismet.isVerifiedKey && akismet.response.isEmpty() && akismet.httpStatusCode == 0, }
" reset"
)
assertFalse(Akismet("123456789012").verifyKey(), "verifyKey() --> false") assertFalse(Akismet("123456789012").verifyKey(), "verifyKey() --> false")
} }
@Test @Test
fun checkMockComment() { fun checkMockComment() {
assertEquals(mockComment.userIp, comment.userIp, "userIp") with(mockComment) {
assertEquals(mockComment.userAgent, comment.userAgent, "userAgent") assertEquals(userIp, comment.userIp, "userIp")
assertEquals(mockComment.referrer, comment.referrer, "referrer") assertEquals(userAgent, comment.userAgent, "userAgent")
assertTrue(mockComment.serverEnv.containsKey("HTTP_ACCEPT_ENCODING"), "HTTP_ACCEPT_ENCODING") assertEquals(referrer, comment.referrer, "referrer")
assertTrue(mockComment.serverEnv.containsKey("REQUEST_URI"), "REQUEST_URI") assertTrue(serverEnv.containsKey("HTTP_ACCEPT_ENCODING"), "HTTP_ACCEPT_ENCODING")
assertTrue(serverEnv.containsKey("REQUEST_URI"), "REQUEST_URI")
}
} }
@Test @Test
@ -189,84 +194,87 @@ class AkismetTest {
} }
val empty = AkismetComment("", "") val empty = AkismetComment("", "")
assertFalse(empty.isTest, "isTest") with(empty) {
assertEquals(empty.permalink, "", "permalink") assertFalse(isTest, "isTest")
assertEquals(empty.type, "", "type") assertEquals(permalink, "", "permalink")
assertEquals(empty.authorEmail, "", "authorEmail") assertEquals(type, "", "type")
assertEquals(empty.author, "", "author") assertEquals(authorEmail, "", "authorEmail")
assertEquals(empty.authorUrl, "", "authorUrl") assertEquals(author, "", "author")
assertEquals(empty.content, "", "content") assertEquals(authorUrl, "", "authorUrl")
assertEquals(empty.dateGmt, "", "dateGmt") assertEquals(content, "", "content")
assertEquals(empty.postModifiedGmt, "", "postModifiedGmt") assertEquals(dateGmt, "", "dateGmt")
assertEquals(empty.blogLang, "", "blogLang") assertEquals(postModifiedGmt, "", "postModifiedGmt")
assertEquals(empty.blogCharset, "", "blogCharset") assertEquals(blogLang, "", "blogLang")
assertEquals(empty.userRole, "", "userRole") assertEquals(blogCharset, "", "blogCharset")
assertEquals(empty.recheckReason, "", "recheckReason") assertEquals(userRole, "", "userRole")
assertEquals(empty.serverEnv.size, 0, "serverEnv") assertEquals(recheckReason, "", "recheckReason")
assertEquals(serverEnv.size, 0, "serverEnv")
}
} }
@Test @Test
fun emptyResponseTest() { fun emptyResponseTest() {
assertTrue( with(akismet) {
akismet.executeMethod( assertTrue(
"https://postman-echo.com/status/200".toHttpUrlOrNull(), emptyFormBody, true executeMethod(
"https://postman-echo.com/status/200".toHttpUrlOrNull(), emptyFormBody, true
)
) )
) val expected = "{\"status\":200}"
val expected = "{\"status\":200}" assertEquals(response, expected, expected)
assertEquals(akismet.response, expected, expected) assertTrue(errorMessage.contains(expected), "errorMessage contains $expected")
assertTrue(akismet.errorMessage.contains(expected), "errorMessage contains $expected")
akismet.reset() reset()
assertTrue(httpStatusCode == 0 && errorMessage.isEmpty(), "reset")
assertTrue( }
akismet.httpStatusCode == 0 && akismet.errorMessage.isEmpty(),
"reset"
)
} }
@Test @Test
fun proTipResponseTest() { fun proTipResponseTest() {
assertFalse( with(akismet) {
akismet.executeMethod( assertFalse(
"https://postman-echo.com/response-headers?x-akismet-pro-tip=discard".toHttpUrlOrNull(), executeMethod(
emptyFormBody "https://postman-echo.com/response-headers?x-akismet-pro-tip=discard".toHttpUrlOrNull(),
emptyFormBody
)
) )
) assertEquals(proTip, "discard")
assertEquals(akismet.proTip, "discard") assertTrue(isDiscard, "isDiscard")
assertTrue(akismet.isDiscard, "isDiscard")
akismet.reset() reset()
assertTrue(!akismet.isDiscard && akismet.response.isEmpty() && akismet.httpStatusCode == 0) assertTrue(!isDiscard && response.isEmpty() && httpStatusCode == 0)
}
} }
@Test @Test
fun checkCommentTest() { fun checkCommentTest() {
assertFalse(akismet.checkComment(comment), "check_comment(admin) -> false") with(akismet) {
assertEquals(akismet.response, "false", "response -> false") assertFalse(checkComment(comment), "check_comment(admin) -> false")
comment.userRole = "" assertEquals(response, "false", "response -> false")
assertTrue(akismet.checkComment(comment), "check_comment -> true") comment.userRole = ""
assertEquals(akismet.response, "true", "response -> true") assertTrue(checkComment(comment), "check_comment -> true")
assertEquals(response, "true", "response -> true")
assertFalse(akismet.checkComment(mockComment), "check_comment(request) -> false") assertFalse(checkComment(mockComment), "check_comment(request) -> false")
mockComment.userRole = "" mockComment.userRole = ""
assertTrue(akismet.checkComment(mockComment), "check_comment(request) -> true") assertTrue(checkComment(mockComment), "check_comment(request) -> true")
assertEquals(akismet.httpStatusCode, 200, "status code") assertEquals(httpStatusCode, 200, "status code")
}
} }
@Test @Test
fun executeMethodTest() { fun executeMethodTest() {
akismet.executeMethod( with(akismet) {
"https://$apiKey.rest.akismet.com/1.1/comment-check".toHttpUrlOrNull(), executeMethod(
FormBody.Builder().apply { add("is_test", "1") }.build() "https://$apiKey.rest.akismet.com/1.1/comment-check".toHttpUrlOrNull(),
) FormBody.Builder().apply { add("is_test", "1") }.build()
assertTrue(akismet.debugHelp.isNotEmpty(), "debugHelp not empty") )
assertTrue(debugHelp.isNotEmpty(), "debugHelp not empty")
akismet.reset() reset()
assertTrue( assertTrue(httpStatusCode == 0 && debugHelp.isEmpty() && response.isEmpty(), "reset")
akismet.httpStatusCode == 0 && akismet.debugHelp.isEmpty() && akismet.response.isEmpty(), }
"reset"
)
} }
@Test @Test
@ -332,14 +340,17 @@ class AkismetTest {
private fun getMockRequest(): HttpServletRequest { private fun getMockRequest(): HttpServletRequest {
val request = Mockito.mock(HttpServletRequest::class.java) val request = Mockito.mock(HttpServletRequest::class.java)
Mockito.`when`(request.remoteAddr).thenReturn(comment.userIp) with(request) {
Mockito.`when`(request.requestURI).thenReturn("/blog/post=1") Mockito.`when`(remoteAddr).thenReturn(comment.userIp)
Mockito.`when`(request.getHeader("User-Agent")).thenReturn(comment.userAgent) Mockito.`when`(requestURI).thenReturn("/blog/post=1")
Mockito.`when`(request.getHeader("referer")).thenReturn(referer) Mockito.`when`(getHeader("User-Agent")).thenReturn(comment.userAgent)
Mockito.`when`(request.getHeader("Cookie")).thenReturn("name=value; name2=value2; name3=value3") Mockito.`when`(getHeader("referer")).thenReturn(referer)
Mockito.`when`(request.getHeader("Accept-Encoding")).thenReturn("gzip") Mockito.`when`(getHeader("Cookie")).thenReturn("name=value; name2=value2; name3=value3")
Mockito.`when`(request.headerNames) Mockito.`when`(getHeader("Accept-Encoding")).thenReturn("gzip")
.thenReturn(Collections.enumeration(listOf("User-Agent", "referer", "Cookie", "Accept-Encoding", "Null"))) Mockito.`when`(headerNames).thenReturn(
Collections.enumeration(listOf("User-Agent", "referer", "Cookie", "Accept-Encoding", "Null"))
)
}
return request return request
} }
} }