Skip to content

Commit

Permalink
store api key in OSM (#990)
Browse files Browse the repository at this point in the history
* add apiKeyToOSM method

* run formatter
  • Loading branch information
jschwarz2030 authored Oct 30, 2022
1 parent 3f27b6c commit 46120e4
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
40 changes: 38 additions & 2 deletions app/controllers/AuthController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ import org.maproulette.framework.service.UserService
import org.maproulette.models.dal.DALManager
import org.maproulette.session.SessionManager
import org.maproulette.permissions.Permission
import org.maproulette.utils.Crypto
import play.api.libs.json.{JsString, Json}
import play.api.libs.oauth.{OAuthCalculator}
import play.api.mvc._
import play.shaded.oauth.oauth.signpost.exception.OAuthNotAuthorizedException
import play.api.libs.ws.WSClient
import org.slf4j.LoggerFactory

import scala.collection.mutable.ArrayBuffer
import scala.concurrent.Promise
import scala.util.{Failure, Success}
import scala.concurrent.Future

/**
* All the authentication actions go in this class
Expand All @@ -34,6 +39,8 @@ class AuthController @Inject() (
userService: UserService,
dalManager: DALManager,
permission: Permission,
wsClient: WSClient,
crypto: Crypto,
val config: Config
) extends AbstractController(components)
with StatusMessages {
Expand All @@ -58,6 +65,9 @@ class AuthController @Inject() (
user,
Redirect(redirect, SEE_OTHER).withHeaders(("Cache-Control", "no-cache"))
)

Future(storeAPIKeyInOSM(user))

case Failure(e) => p failure e
}
case None =>
Expand Down Expand Up @@ -166,6 +176,29 @@ class AuthController @Inject() (
}
}

def storeAPIKeyInOSM = (user: User) => {
if (!config.getOSMServer.isEmpty && !config.getOSMPreferences.isEmpty) {
val logger = LoggerFactory.getLogger(this.getClass)
val decryptedAPIKey = User.withDecryptedAPIKey(user)(crypto).apiKey.getOrElse("")

wsClient
.url(s"${config.getOSMServer}${config.getOSMPreferences}")
.withHttpHeaders(ACCEPT -> JSON)
.sign(OAuthCalculator(config.getOSMOauth.consumerKey, user.osmProfile.requestToken))
.put(decryptedAPIKey) onComplete {
case Success(response) =>
val status = response.status
if (status != 200) {
logger.info(
"API key unsuccessfully stored in OSM preferences for user id {}. Status code {}",
user.id,
status
)
}
}
}
}

/**
* Generates a new API key for the user. A user can then use the API key to make API calls directly against
* the server. Only the current API key for the user will work on any authenticated API calls, any previous
Expand All @@ -190,8 +223,11 @@ class AuthController @Inject() (
this.userService.generateAPIKey(newAPIUser, user) match {
case Some(updated) =>
updated.apiKey match {
case Some(api) => Ok(api)
case None => NoContent
case Some(api) => {
Future(storeAPIKeyInOSM(user))
Ok(api)
}
case None => NoContent
}
case None => NoContent
}
Expand Down
3 changes: 3 additions & 0 deletions app/org/maproulette/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ class Config @Inject() (implicit val configuration: Configuration) {
this.config.getOptional[Boolean](Config.KEY_PROXY_SSL).getOrElse(false);
lazy val allowMatchOSM = changeSetEnabled || osmMatcherEnabled || osmMatcherManualOnly
lazy val getOSMServer: String = this.config.getOptional[String](Config.KEY_OSM_SERVER).get
lazy val getOSMPreferences: String =
this.config.getOptional[String](Config.KEY_OSM_PREFERENCES).get
lazy val getOSMOauth: OSMOAuth = {
val osmServer = this.getOSMServer
OSMOAuth(
Expand Down Expand Up @@ -337,6 +339,7 @@ object Config {

val GROUP_OSM = "osm"
val KEY_OSM_SERVER = s"$GROUP_OSM.server"
val KEY_OSM_PREFERENCES = s"$GROUP_OSM.preferences"
val KEY_OSM_USER_DETAILS_URL = s"$GROUP_OSM.userDetails"
val KEY_OSM_REQUEST_TOKEN_URL = s"$GROUP_OSM.requestTokenURL"
val KEY_OSM_ACCESS_TOKEN_URL = s"$GROUP_OSM.accessTokenURL"
Expand Down
5 changes: 5 additions & 0 deletions conf/dev.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ osm {

server="https://master.apis.dev.openstreetmap.org"

# needed if system intends to store MR API keys in osm user preferences.
# replace maproulette_apikey_v2 with a unique parameter
# see https://wiki.openstreetmap.org/wiki/API_v0.6#Preferences_of_the_logged-in_user
preferences="/api/0.6/user/preferences/maproulette_apikey_v2"

# The Consumer and Secret keys as provided by your OAuth app

consumerKey="CHANGE_ME"
Expand Down

0 comments on commit 46120e4

Please sign in to comment.