Skip to content

Commit 8907ae4

Browse files
Merge pull request #65 from OpenFuturePlatform/SA-41_Deploy-Open-Key-Open-API
Sa 41 deploy open key open api
2 parents 5e25260 + 0fd73f6 commit 8907ae4

13 files changed

Lines changed: 156 additions & 17 deletions

File tree

.github/workflows/open-api-ci-cd.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,9 @@ jobs:
209209
-e "OPEN_TOKEN_ADDRESS=${{ secrets.OPEN_TOKEN_ADDRESS_PROD }}" \
210210
-e "EVENT_SUBSCRIPTION=true" \
211211
-e "WIDGET_HOST=${{ secrets.WIDGET_HOST_PROD }}" \
212-
-e "OPEN_STATE_URL=${{ secrets.OPEN_STATE_URLPROD }}" \
212+
-e "OPEN_STATE_URL=${{ secrets.OPEN_STATE_URL_PROD }}" \
213213
-e "STATE_API_URL=${{ secrets.STATE_API_URL_PROD }}" \
214+
-e "OPEN_KEY_URL=${{ secrets.OPEN_KEY_URL_PROD }}" \
214215
${{ env.DEPLOY_IMAGE_NAME }}:${{ env.DEPLOY_IMAGE_TAG }}
215216
"
216217

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ dependencies {
5959
// Utils
6060
implementation('commons-io:commons-io:2.8.0')
6161
implementation 'org.apache.commons:commons-lang3:3.6'
62+
implementation group: 'commons-net', name: 'commons-net', version: '3.6'
63+
6264

6365
// Test
6466
testImplementation('org.springframework.boot:spring-boot-starter-test')

frontend/src/components/GatewayApplicationRemove.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import {t} from "../utils/messageTexts";
33
import React from "react";
44

55
export const GatewayApplicationRemove = ({ onSubmit }) => (
6-
<EntityRemove onSubmit={onSubmit} header="Delete Gateway">
6+
<EntityRemove onSubmit={onSubmit} header="Delete Application">
77
<div>
8-
{t('sure to delete Gateway')}
8+
{t('sure to delete Application')}
99
</div>
1010
</EntityRemove>
11-
);
11+
);

src/main/kotlin/io/openfuture/api/config/SecurityConfig.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ class SecurityConfig(
4141
.antMatchers("/static/**").permitAll()
4242
.antMatchers("**.js").permitAll()
4343
.antMatchers("/widget/**").permitAll()
44+
.antMatchers("/**").access("hasIpAddress('127.0.0.1') or hasIpAddress('0:0:0:0:0:0:0:1') or hasIpAddress('${properties.cidr}')")
4445
.anyRequest().authenticated()
4546

4647
.and()
4748

4849
.addFilterAfter(AuthorizationFilter(properties, keyService), OAuth2LoginAuthenticationFilter::class.java)
49-
.addFilterAfter(ApiAuthorizationFilter(mapper), AuthorizationFilter::class.java)
50+
.addFilterAfter(ApiAuthorizationFilter(mapper,properties), AuthorizationFilter::class.java)
5051
.addFilterAfter(PublicApiAuthorizationFilter(applicationService, mapper, properties), AuthorizationFilter::class.java)
5152
.sessionManagement().sessionCreationPolicy(STATELESS)
5253

src/main/kotlin/io/openfuture/api/config/filter/ApiAuthorizationFilter.kt

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package io.openfuture.api.config.filter
22

33
import com.fasterxml.jackson.databind.ObjectMapper
4+
import io.openfuture.api.config.propety.AuthorizationProperties
45
import io.openfuture.api.domain.exception.ExceptionResponse
56
import org.springframework.http.HttpStatus.UNAUTHORIZED
67
import org.springframework.security.core.context.SecurityContextHolder
8+
import org.springframework.security.web.util.matcher.IpAddressMatcher
79
import javax.servlet.*
810
import javax.servlet.http.HttpServletRequest
911
import javax.servlet.http.HttpServletResponse
1012

11-
class ApiAuthorizationFilter(private val mapper: ObjectMapper): Filter {
13+
class ApiAuthorizationFilter(
14+
private val mapper: ObjectMapper,
15+
private val properties: AuthorizationProperties
16+
): Filter {
17+
18+
private val ipV4LoopBack = "127.0.0.1"
19+
private val ipV6LoopBack = "0:0:0:0:0:0:0:1"
1220

1321
override fun init(filterConfig: FilterConfig?) {
1422
// Do nothing
@@ -18,7 +26,7 @@ class ApiAuthorizationFilter(private val mapper: ObjectMapper): Filter {
1826
request as HttpServletRequest
1927
response as HttpServletResponse
2028

21-
if (request.requestURI.startsWith("/api") && null == SecurityContextHolder.getContext().authentication) {
29+
if (request.requestURI.startsWith("/api") && null == SecurityContextHolder.getContext().authentication && !isAllowed(request)) {
2230
val exceptionResponse = ExceptionResponse(UNAUTHORIZED.value(), "Open token is invalid or disabled")
2331
response.status = exceptionResponse.status
2432
response.writer.write(mapper.writeValueAsString(exceptionResponse))
@@ -32,4 +40,22 @@ class ApiAuthorizationFilter(private val mapper: ObjectMapper): Filter {
3240
// Do nothing
3341
}
3442

43+
fun isAllowed(request: HttpServletRequest): Boolean {
44+
45+
val ip = request.remoteAddr
46+
if (properties.allowLocalHost && (ipV4LoopBack == ip || ipV6LoopBack == ip)) {
47+
return true
48+
}
49+
50+
if (properties.cidr != null) {
51+
val matcher = IpAddressMatcher(properties.cidr)
52+
53+
if (matcher.matches(request.getHeader("X-Forwarded-For"))) {
54+
return true
55+
}
56+
}
57+
58+
return false
59+
}
60+
3561
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package io.openfuture.api.config.filter
2+
3+
import io.openfuture.api.config.propety.AuthorizationProperties
4+
import io.openfuture.api.util.getIpRange
5+
import org.springframework.security.web.util.matcher.IpAddressMatcher
6+
import java.io.IOException
7+
import javax.servlet.*
8+
import javax.servlet.http.HttpServletRequest
9+
import javax.servlet.http.HttpServletResponse
10+
11+
12+
class IpAddressFilter(
13+
private val properties: AuthorizationProperties
14+
) : Filter {
15+
16+
private val IPV4_LOOPBACK = "127.0.0.1"
17+
private val IPV6_LOOPBACK = "0:0:0:0:0:0:0:1"
18+
private var ipList = arrayListOf<String>()
19+
var allowLocalhost = true
20+
21+
override fun init(filterConfig: FilterConfig?) {
22+
ipList = getIpRange(properties.cidr!!)
23+
ipList.stream().map { ip -> print(ip) }
24+
}
25+
26+
override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
27+
request as HttpServletRequest
28+
response as HttpServletResponse
29+
30+
println("REMOTE ADDRESS ${request.getHeader("X-Forwarded-For")}")
31+
32+
33+
if (!isAllowed(request)) {
34+
println("DENIED")
35+
deny(response)
36+
return
37+
}
38+
chain.doFilter(request, response)
39+
}
40+
41+
@Throws(IOException::class)
42+
fun deny(res: HttpServletResponse) {
43+
res.sendError(HttpServletResponse.SC_NOT_FOUND)
44+
}
45+
46+
override fun destroy() {
47+
48+
}
49+
50+
fun isAllowed(request: HttpServletRequest): Boolean {
51+
52+
val ip = request.remoteAddr
53+
if (allowLocalhost && (IPV4_LOOPBACK == ip || IPV6_LOOPBACK == ip)) {
54+
return true
55+
}
56+
/*var uri = request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE) as String
57+
if (!StringUtils.isEmpty(uri)) {
58+
uri = request.requestURI
59+
if (request.contextPath != "/" && uri.startsWith(request.contextPath)) {
60+
uri = uri.substring(request.contextPath.length)
61+
}
62+
}*/
63+
64+
val matcher = IpAddressMatcher("192.168.1.0/24")
65+
66+
if (!matcher.matches(request.getHeader("X-Forwarded-For"))) {
67+
return true
68+
}
69+
70+
return false
71+
}
72+
}

src/main/kotlin/io/openfuture/api/config/filter/PublicApiAuthorizationFilter.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ import org.springframework.http.HttpStatus.UNAUTHORIZED
66
import io.openfuture.api.domain.exception.ExceptionResponse
77
import io.openfuture.api.domain.key.WalletApiCreateRequest
88
import io.openfuture.api.service.ApplicationService
9-
import io.openfuture.api.util.CustomHttpRequestWrapper
10-
import io.openfuture.api.util.KeyGeneratorUtils
11-
import io.openfuture.api.util.currentEpochs
12-
import io.openfuture.api.util.differenceEpochs
9+
import io.openfuture.api.util.*
1310
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
1411
import org.springframework.security.core.authority.SimpleGrantedAuthority
1512
import org.springframework.security.core.context.SecurityContextHolder
@@ -36,7 +33,7 @@ class PublicApiAuthorizationFilter(
3633

3734
val accessKey = request.getHeader("X-API-KEY")
3835
val signature = request.getHeader("X-API-SIGNATURE")
39-
val expirePeriod = 10L;
36+
val expirePeriod = properties.expireApi!!
4037

4138
val requestWrapper = CustomHttpRequestWrapper(request)
4239
val walletApiCreateRequest = mapper.readValue(requestWrapper.bodyInStringFormat, WalletApiCreateRequest::class.java)
@@ -59,7 +56,7 @@ class PublicApiAuthorizationFilter(
5956
val token = UsernamePasswordAuthenticationToken(application.user, null, listOf(SimpleGrantedAuthority("ROLE_APPLICATION")))
6057
SecurityContextHolder.getContext().authentication = token
6158

62-
chain.doFilter(requestWrapper, response);
59+
chain.doFilter(requestWrapper, response)
6360
return
6461
}
6562

src/main/kotlin/io/openfuture/api/config/propety/AuthorizationProperties.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ import javax.validation.constraints.NotEmpty
1010
@Component
1111
class AuthorizationProperties(
1212
@field:NotEmpty var cookieName: String? = null,
13-
var expireApi: Long? = 10
13+
var expireApi: Long? = 10,
14+
var cidr: String? = null,
15+
var allowLocalHost: Boolean = false
1416
)

src/main/kotlin/io/openfuture/api/controller/api/ApplicationApiController.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ApplicationApiController(
3737
}
3838

3939
@GetMapping("/{id}")
40-
fun get(@CurrentUser user: User, @PathVariable id: Long): ApplicationDto {
40+
fun get(@PathVariable id: Long): ApplicationDto {
4141
val application = service.getById(id)
4242
return ApplicationDto(application)
4343
}

src/main/kotlin/io/openfuture/api/service/DefaultApplicationWalletService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class DefaultApplicationWalletService(
2222
val keyWalletDto = keyApi.generateKey(CreateKeyRequest(request.applicationId, user.id.toString(), request.blockchainType))
2323

2424
// Save webhook on state
25-
request.webHook.let { stateApi.createWallet(keyWalletDto.address, it, Blockchain.Ethereum) }
25+
//request.webHook.let { stateApi.createWallet(keyWalletDto.address, it, Blockchain.Ethereum) }
2626

2727
return keyWalletDto
2828
}
@@ -35,6 +35,6 @@ class DefaultApplicationWalletService(
3535
// Delete from Open Key
3636
keyApi.deleteAllKeysByApplicationAddress(applicationId, address)
3737
// Delete from Open State
38-
stateApi.deleteWallet(address, Blockchain.Ethereum)
38+
//stateApi.deleteWallet(address, Blockchain.Ethereum)
3939
}
4040
}

0 commit comments

Comments
 (0)