Search code examples
scalaplayframeworksilhouette

Removal of auth info fails due to bad implicit parameter


I'm using Silhouette to manage authentication in my Play application. Registration, login and authorization work fine. However, when trying to unregister (= delete) a user account, deletion of the corresponding auth info fails.

In particular, the following line throws an exception:

authInfoRepository.remove(LoginInfo(credentialsProvider.id, username))

(authInfoRepository is an injected AuthInfoRepository, which is configured to be a DelegableAuthInfoRepository)

Exception:

com.mohiva.play.silhouette.api.exceptions.ConfigurationException: Cannot remove auth info of type: class scala.runtime.Nothing$; Please configure the DAO for this type
at com.mohiva.play.silhouette.persistence.repositories.DelegableAuthInfoRepository.remove(DelegableAuthInfoRepository.scala:115)
[...]

Looking at the method in question, it expects an implicit parameter implicit tag: ClassTag[T]. That one somehow ends up being Nothing, which looks wrong in my eyes, but I don't fully understand what's going on, or what is expected to happen.

  • How should AuthInfoRepository#remove be properly called? Do I need to manually put a ClassTag object into the right context to avoid Nothing to be inferred?
  • Why is the implicit ClassTag parameter even relevant?

Solution

  • Why is the implicit ClassTag parameter even relevant?

    ClassTag is relevant because remove expects such implicit: https://github.com/mohiva/play-silhouette/blob/master/silhouette-persistence/src/main/scala/com/mohiva/play/silhouette/persistence/repositories/DelegableAuthInfoRepository.scala#L104-L118

    Do I need to manually put a ClassTag object into the right context to avoid Nothing to be inferred?

    I guess vice versa, you should specify T (without such specifying, T is now inferred to be Nothing) and proper implicit will be found.

    Try one of options:

    authInfoRepository.remove[CasInfo](LoginInfo(credentialsProvider.id, username))
    authInfoRepository.remove[OAuth1Info](LoginInfo(credentialsProvider.id, username))
    authInfoRepository.remove[OAuth2Info](LoginInfo(credentialsProvider.id, username))
    authInfoRepository.remove[OpenIDInfo](LoginInfo(credentialsProvider.id, username))
    authInfoRepository.remove[PasswordInfo](LoginInfo(credentialsProvider.id, username))