Skip to content

Commit

Permalink
Merge pull request #71 from myndocs/release/0.6.0
Browse files Browse the repository at this point in the history
Release/0.6.0
  • Loading branch information
adhesivee authored Sep 7, 2019
2 parents 3f39a51 + ec6f848 commit 09ac0bb
Show file tree
Hide file tree
Showing 48 changed files with 916 additions and 200 deletions.
5 changes: 5 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@ pipeline {
}
}
}
post {
always {
cleanWs()
}
}
}
70 changes: 41 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,37 @@ It encourages to adapt to existing implementations instead the other way around.
# Frameworks
## Setup
### Maven
First define the version to be used and set it as a property

```xml
<properties>
<myndocs.oauth.version>0.5.0</myndocs.oauth.version>
<myndocs.oauth.version>0.6.0</myndocs.oauth.version>
</properties>
```

Include the following repository in order to download the artifacts
```xml
<dependencies>
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-core</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>

<!-- In memory dependencies -->
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-client-inmemory</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-identity-inmemory</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-token-store-inmemory</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
</dependencies>

<repositories>
<repository>
<id>myndocs-oauth2</id>
Expand All @@ -25,32 +47,22 @@ Include the following repository in order to download the artifacts
</repositories>
```

For the frameworks examples we need at least the following dependencies:
```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-core</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>

<!-- In memory dependencies -->
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-client-inmemory</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-identity-inmemory</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-token-store-inmemory</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
### Gradle
```groovy
repositories {
maven { url 'https://dl.bintray.com/adhesivee/oauth2-server' }
}
dependencies {
compile "nl.myndocs:oauth2-server-core:$myndocs_oauth_version"
// In memory dependencies
compile "nl.myndocs:oauth2-server-client-inmemory:$myndocs_oauth_version"
compile "nl.myndocs:oauth2-server-identity-inmemory:$myndocs_oauth_version"
compile "nl.myndocs:oauth2-server-token-store-inmemory:$myndocs_oauth_version"
}
```


### Framework implementation
The following frameworks are supported:
- [Ktor](docs/ktor.md)
Expand Down
10 changes: 9 additions & 1 deletion docs/http4k.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# http4k

## Dependencies

### Maven
```xml
<dependency>
<groupId>nl.myndocs</groupId>
Expand All @@ -9,11 +11,17 @@
</dependency>
```

### Gradle
```groovy
compile "nl.myndocs:oauth2-server-http4k:$myndocs_oauth_version"
```


## Implementation
```kotlin
val app: HttpHandler = routes(
"/ping" bind GET to { _: Request -> Response(Status.OK).body("pong!") }
) `enable oauth2` {
).enableOauth2 {
identityService = InMemoryIdentity()
.identity {
username = "foo"
Expand Down
7 changes: 7 additions & 0 deletions docs/javalin.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Javalin

## Dependencies

### Maven
```xml
<dependency>
<groupId>nl.myndocs</groupId>
Expand All @@ -9,6 +11,11 @@
</dependency>
```

### Gradle
```groovy
compile "nl.myndocs:oauth2-server-javalin:$myndocs_oauth_version"
```

## Implementation
```kotlin
Javalin.create().apply {
Expand Down
6 changes: 6 additions & 0 deletions docs/ktor.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Dependencies

### Maven
```xml
<dependency>
<groupId>nl.myndocs</groupId>
Expand All @@ -10,6 +11,11 @@
</dependency>
```

### Gradle
```groovy
compile "nl.myndocs:oauth2-server-ktor:$myndocs_oauth_version"
```

## Implementation
```kotlin
embeddedServer(Netty, 8080) {
Expand Down
7 changes: 7 additions & 0 deletions docs/sparkjava.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Spark java

## Dependencies

### Maven
```xml
<dependency>
<groupId>nl.myndocs</groupId>
Expand All @@ -9,6 +11,11 @@
</dependency>
```

### Gradle
```groovy
compile "nl.myndocs:oauth2-server-sparkjava:$myndocs_oauth_version"
```

## Implementation
```kotlin
Oauth2Server.configureOauth2Server {
Expand Down
2 changes: 1 addition & 1 deletion oauth2-server-client-inmemory/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>kotlin-oauth2-server</artifactId>
<groupId>nl.myndocs</groupId>
<version>0.5.0</version>
<version>0.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
23 changes: 1 addition & 22 deletions oauth2-server-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,9 @@
<parent>
<artifactId>kotlin-oauth2-server</artifactId>
<groupId>nl.myndocs</groupId>
<version>0.5.0</version>
<version>0.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>oauth2-server-core</artifactId>

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.mockk</groupId>
<artifactId>mockk</artifactId>
<version>1.8.12.kotlin13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
74 changes: 39 additions & 35 deletions oauth2-server-core/src/main/java/nl/myndocs/oauth2/CallRouter.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package nl.myndocs.oauth2

import nl.myndocs.oauth2.authenticator.Authorizer
import nl.myndocs.oauth2.authenticator.Credentials
import nl.myndocs.oauth2.exception.*
import nl.myndocs.oauth2.grant.Granter
import nl.myndocs.oauth2.grant.GrantingCall
Expand All @@ -11,6 +11,8 @@ import nl.myndocs.oauth2.request.CallContext
import nl.myndocs.oauth2.request.RedirectAuthorizationCodeRequest
import nl.myndocs.oauth2.request.RedirectTokenRequest
import nl.myndocs.oauth2.request.headerCaseInsensitive
import nl.myndocs.oauth2.router.RedirectRouter
import nl.myndocs.oauth2.router.RedirectRouterResponse

class CallRouter(
val tokenEndpoint: String,
Expand All @@ -19,7 +21,7 @@ class CallRouter(
private val tokenInfoCallback: (TokenInfo) -> Map<String, Any?>,
private val granters: List<GrantingCall.() -> Granter>,
private val grantingCallFactory: (CallContext) -> GrantingCall
) {
) : RedirectRouter {
companion object {
const val METHOD_POST = "post"
const val METHOD_GET = "get"
Expand All @@ -29,16 +31,21 @@ class CallRouter(

}

fun route(
callContext: CallContext,
authorizer: Authorizer) {
fun route(callContext: CallContext) {
when (callContext.path) {
tokenEndpoint -> routeTokenEndpoint(callContext)
authorizeEndpoint -> routeAuthorizeEndpoint(callContext, authorizer)
tokenInfoEndpoint -> routeTokenInfoEndpoint(callContext)
}
}

override fun route(callContext: CallContext, credentials: Credentials?): RedirectRouterResponse {
return when (callContext.path) {
authorizeEndpoint -> routeAuthorizeEndpoint(callContext, credentials)
else -> throw NoRoutesFoundException("Route '${callContext.path}' not found")
}
}


private fun routeTokenEndpoint(callContext: CallContext) {
if (callContext.method.toLowerCase() != METHOD_POST) {
return
Expand Down Expand Up @@ -72,21 +79,18 @@ class CallRouter(

fun routeAuthorizationCodeRedirect(
callContext: CallContext,
authorizer: Authorizer
) {
credentials: Credentials?
): RedirectRouterResponse {
val queryParameters = callContext.queryParameters
val credentials = authorizer.extractCredentials()
try {
val redirect = grantingCallFactory(callContext).redirect(
RedirectAuthorizationCodeRequest(
queryParameters["client_id"],
queryParameters["redirect_uri"],
credentials?.username ?: "",
credentials?.password ?: "",
credentials?.username,
credentials?.password,
queryParameters["scope"]
),
authorizer.authenticator(),
authorizer.scopesVerifier()
)
)

var stateQueryParameter = ""
Expand All @@ -96,31 +100,31 @@ class CallRouter(
}

callContext.redirect(queryParameters["redirect_uri"] + "?code=${redirect.codeToken}$stateQueryParameter")

return RedirectRouterResponse(true)
} catch (unverifiedIdentityException: InvalidIdentityException) {
callContext.respondStatus(STATUS_UNAUTHORIZED)
authorizer.failedAuthentication()

return RedirectRouterResponse(false)
}
}


fun routeAccessTokenRedirect(
callContext: CallContext,
authorizer: Authorizer
) {
credentials: Credentials?
): RedirectRouterResponse {
val queryParameters = callContext.queryParameters
val credentials = authorizer.extractCredentials()

try {
val redirect = grantingCallFactory(callContext).redirect(
RedirectTokenRequest(
queryParameters["client_id"],
queryParameters["redirect_uri"],
credentials?.username ?: "",
credentials?.password ?: "",
credentials?.username,
credentials?.password,
queryParameters["scope"]
),
authorizer.authenticator(),
authorizer.scopesVerifier()
)
)

var stateQueryParameter = ""
Expand All @@ -134,33 +138,33 @@ class CallRouter(
"&token_type=bearer&expires_in=${redirect.expiresIn()}$stateQueryParameter"
)

return RedirectRouterResponse(true)
} catch (unverifiedIdentityException: InvalidIdentityException) {
authorizer.failedAuthentication()
callContext.respondStatus(STATUS_UNAUTHORIZED)

return RedirectRouterResponse(false)
}
}

private fun routeAuthorizeEndpoint(callContext: CallContext, authorizer: Authorizer) {
private fun routeAuthorizeEndpoint(callContext: CallContext, credentials: Credentials?): RedirectRouterResponse {
try {
if (callContext.method.toLowerCase() != METHOD_GET) {
return
if (!arrayOf(METHOD_GET, METHOD_POST).contains(callContext.method.toLowerCase())) {
return RedirectRouterResponse(false)
}

val allowedResponseTypes = setOf("code", "token")
val responseType = callContext.queryParameters["response_type"]
?: throw InvalidRequestException("'response_type' not given")

if (!allowedResponseTypes.contains(responseType)) {
throw InvalidGrantException("'grant_type' with value '$responseType' not allowed")
}

when (responseType) {
"code" -> routeAuthorizationCodeRedirect(callContext, authorizer)
"token" -> routeAccessTokenRedirect(callContext, authorizer)
return when (responseType) {
"code" -> routeAuthorizationCodeRedirect(callContext, credentials)
"token" -> routeAccessTokenRedirect(callContext, credentials)
else -> throw InvalidGrantException("'grant_type' with value '$responseType' not allowed")
}
} catch (oauthException: OauthException) {
callContext.respondStatus(STATUS_BAD_REQUEST)
callContext.respondJson(oauthException.toMap())

return RedirectRouterResponse(false)
}
}

Expand Down
Loading

0 comments on commit 09ac0bb

Please sign in to comment.