Skip to content

Commit

Permalink
Add token for MSP requests (#5510)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/0/1209158877247466/f 

### Description
Retrieve token and inject it to malicious site protection requests
### Steps to test this PR
  • Loading branch information
CrisBarreiro authored Feb 4, 2025
1 parent 1a32a0d commit a779a24
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .github/workflows/build-ad-hoc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ jobs:
uses: gradle/actions/setup-gradle@v3

- name: Assemble APK
env:
MALICIOUS_SITE_PROTECTION_AUTH_TOKEN: ${{ secrets.MALICIOUS_SITE_PROTECTION_AUTH_TOKEN }}
run: ./gradlew assemble${{github.event.inputs.build-variant}} -Pforce-default-variant

- name: Move APK to new folder
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build-debug-apk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jobs:
uses: gradle/actions/setup-gradle@v3

- name: Assemble the project
env:
MALICIOUS_SITE_PROTECTION_AUTH_TOKEN: ${{ secrets.MALICIOUS_SITE_PROTECTION_AUTH_TOKEN }}
run: ./gradlew assembleInternalDebug -Pforce-default-variant

- name: Obtain debug apk
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build-fdroid-apk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
uses: gradle/actions/setup-gradle@v4

- name: Assemble F-Droid release apk
env:
MALICIOUS_SITE_PROTECTION_AUTH_TOKEN: ${{ secrets.MALICIOUS_SITE_PROTECTION_AUTH_TOKEN }}
run: ./gradlew assembleFdroidRelease

- name: Create Asana task when workflow failed on push to develop
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release_nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ jobs:
env:
NETP_DEBUG_SERVER_TOKEN: ${{ secrets.NETP_DEBUG_SERVER_TOKEN }}
if: steps.check_for_changes.outputs.has_changes == 'true'
env:
MALICIOUS_SITE_PROTECTION_AUTH_TOKEN: ${{ secrets.MALICIOUS_SITE_PROTECTION_AUTH_TOKEN }}
run: gradle bundleInternalRelease -PversionNameSuffix=-nightly -PuseUploadSigning -PlatestTag=${{ steps.get_latest_tag.outputs.latest_tag }} -Pbuild-date-time

- name: Generate nightly version name
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release_upload_play_store.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ jobs:
destination-path: $HOME/jenkins_static/com.duckduckgo.mobile.android/

- name: Assemble the bundle
env:
MALICIOUS_SITE_PROTECTION_AUTH_TOKEN: ${{ secrets.MALICIOUS_SITE_PROTECTION_AUTH_TOKEN }}
run: ./gradlew bundleRelease -PuseUploadSigning -Pbuild-date-time

- name: Capture App Bundle Path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,17 @@ plugins {

apply from: "$rootProject.projectDir/gradle/android-library.gradle"

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

dependencies {
implementation project(":malicious-site-protection-api")
implementation project(':browser-api')

anvil project(path: ':anvil-compiler')
implementation project(path: ':anvil-annotations')
Expand Down Expand Up @@ -63,6 +72,12 @@ dependencies {
coreLibraryDesugaring Android.tools.desugarJdkLibs
}

ext {
MALICIOUS_SITE_PROTECTION_AUTH_TOKEN =
localProperties.getProperty('MALICIOUS_SITE_PROTECTION_AUTH_TOKEN')
?: System.getenv('MALICIOUS_SITE_PROTECTION_AUTH_TOKEN')
}

android {
namespace "com.duckduckgo.malicioussiteprotection.impl"
anvil {
Expand All @@ -79,5 +94,7 @@ android {
compileOptions {
coreLibraryDesugaringEnabled = true
}
defaultConfig {
buildConfigField "String", "MALICIOUS_SITE_PROTECTION_AUTH_TOKEN", "\"${MALICIOUS_SITE_PROTECTION_AUTH_TOKEN}\""
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2025 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.duckduckgo.malicioussiteprotection.impl.data.network

import com.duckduckgo.app.global.api.ApiInterceptorPlugin
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.malicioussiteprotection.impl.BuildConfig
import com.squareup.anvil.annotations.ContributesMultibinding
import javax.inject.Inject
import logcat.logcat
import okhttp3.Interceptor
import okhttp3.Interceptor.Chain
import okhttp3.Response
import retrofit2.Invocation

@ContributesMultibinding(
scope = AppScope::class,
boundType = ApiInterceptorPlugin::class,
)
class MaliciousSiteProtectionRequestInterceptor @Inject constructor() : ApiInterceptorPlugin, Interceptor {
override fun getInterceptor(): Interceptor = this

override fun intercept(chain: Chain): Response {
val request = chain.request()

val authRequired = chain.request().tag(Invocation::class.java)
?.method()
?.isAnnotationPresent(AuthRequired::class.java) == true

return if (authRequired) {
val newRequest = chain.request().newBuilder()
newRequest.addHeader(
name = "X-Auth-Token",
value = BuildConfig.MALICIOUS_SITE_PROTECTION_AUTH_TOKEN,
)
chain.proceed(
newRequest.build().also { logcat { "headers: ${it.headers}" } },
)
} else {
chain.proceed(request)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,27 @@ private const val MALWARE = "malware"

@ContributesServiceApi(AppScope::class)
interface MaliciousSiteService {
@AuthRequired
@GET("$BASE_URL$HASH_PREFIX_PATH?$CATEGORY=$PHISHING")
suspend fun getPhishingHashPrefixes(@Query("revision") revision: Int): HashPrefixResponse

@AuthRequired
@GET("$BASE_URL$HASH_PREFIX_PATH?$CATEGORY=$MALWARE")
suspend fun getMalwareHashPrefixes(@Query("revision") revision: Int): HashPrefixResponse

@AuthRequired
@GET("$BASE_URL$FILTER_SET_PATH?$CATEGORY=$PHISHING")
suspend fun getPhishingFilterSet(@Query("revision") revision: Int): FilterSetResponse

@AuthRequired
@GET("$BASE_URL$FILTER_SET_PATH?$CATEGORY=$MALWARE")
suspend fun getMalwareFilterSet(@Query("revision") revision: Int): FilterSetResponse

@AuthRequired
@GET("$BASE_URL/matches")
suspend fun getMatches(@Query("hashPrefix") hashPrefix: String): MatchesResponse

@AuthRequired
@GET("$BASE_URL/revision")
suspend fun getRevision(): RevisionResponse
}
Expand Down Expand Up @@ -83,3 +89,10 @@ data class MatchResponse(
data class RevisionResponse(
val revision: Int,
)

/**
* This annotation is used in interceptors to be able to intercept the annotated service calls
*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class AuthRequired

0 comments on commit a779a24

Please sign in to comment.