2019-04-24 21:52:08 +00:00
package duo
import (
"encoding/json"
"net/url"
2020-04-05 12:37:21 +00:00
duoapi "github.com/duosecurity/duo_api_golang"
2020-03-01 00:51:11 +00:00
2021-08-11 01:04:35 +00:00
"github.com/authelia/authelia/v4/internal/middlewares"
2019-04-24 21:52:08 +00:00
)
2020-05-02 05:06:39 +00:00
// NewDuoAPI create duo API instance.
2019-04-24 21:52:08 +00:00
func NewDuoAPI ( duoAPI * duoapi . DuoApi ) * APIImpl {
api := new ( APIImpl )
api . DuoApi = duoAPI
2020-05-05 19:35:32 +00:00
2019-04-24 21:52:08 +00:00
return api
}
2020-05-02 05:06:39 +00:00
// Call call to the DuoAPI.
2021-12-01 03:32:58 +00:00
func ( d * APIImpl ) Call ( ctx * middlewares . AutheliaCtx , values url . Values , method string , path string ) ( * Response , error ) {
2020-05-05 19:35:32 +00:00
var response Response
2019-04-24 21:52:08 +00:00
2021-12-01 03:32:58 +00:00
_ , responseBytes , err := d . DuoApi . SignedCall ( method , path , values )
2019-04-24 21:52:08 +00:00
if err != nil {
return nil , err
}
2021-12-01 03:32:58 +00:00
ctx . Logger . Tracef ( "Duo endpoint: %s response raw data for %s from IP %s: %s" , path , ctx . GetSession ( ) . Username , ctx . RemoteIP ( ) . String ( ) , string ( responseBytes ) )
2020-03-01 00:51:11 +00:00
2019-04-24 21:52:08 +00:00
err = json . Unmarshal ( responseBytes , & response )
if err != nil {
return nil , err
}
2020-05-05 19:35:32 +00:00
2021-12-01 03:32:58 +00:00
if response . Stat == "FAIL" {
ctx . Logger . Warnf (
"Duo Push Auth failed to process the auth request for %s from %s: %s (%s), error code %d." ,
ctx . GetSession ( ) . Username , ctx . RemoteIP ( ) . String ( ) ,
response . Message , response . MessageDetail , response . Code )
}
2019-04-24 21:52:08 +00:00
return & response , nil
}
2021-12-01 03:32:58 +00:00
// PreAuthCall call to the DuoAPI.
func ( d * APIImpl ) PreAuthCall ( ctx * middlewares . AutheliaCtx , values url . Values ) ( * PreAuthResponse , error ) {
var preAuthResponse PreAuthResponse
response , err := d . Call ( ctx , values , "POST" , "/auth/v2/preauth" )
if err != nil {
return nil , err
}
err = json . Unmarshal ( response . Response , & preAuthResponse )
if err != nil {
return nil , err
}
return & preAuthResponse , nil
}
// AuthCall call to the DuoAPI.
func ( d * APIImpl ) AuthCall ( ctx * middlewares . AutheliaCtx , values url . Values ) ( * AuthResponse , error ) {
var authResponse AuthResponse
response , err := d . Call ( ctx , values , "POST" , "/auth/v2/auth" )
if err != nil {
return nil , err
}
err = json . Unmarshal ( response . Response , & authResponse )
if err != nil {
return nil , err
}
return & authResponse , nil
}