2019-04-25 04:52:08 +07:00
package duo
import (
"encoding/json"
"net/url"
2020-04-05 19:37:21 +07:00
duoapi "github.com/duosecurity/duo_api_golang"
2020-03-01 07:51:11 +07:00
2021-08-11 08:04:35 +07:00
"github.com/authelia/authelia/v4/internal/middlewares"
2019-04-25 04:52:08 +07:00
)
2020-05-02 12:06:39 +07:00
// NewDuoAPI create duo API instance.
2019-04-25 04:52:08 +07:00
func NewDuoAPI ( duoAPI * duoapi . DuoApi ) * APIImpl {
api := new ( APIImpl )
api . DuoApi = duoAPI
2020-05-06 02:35:32 +07:00
2019-04-25 04:52:08 +07:00
return api
}
2020-05-02 12:06:39 +07:00
// Call call to the DuoAPI.
2021-12-01 10:32:58 +07:00
func ( d * APIImpl ) Call ( ctx * middlewares . AutheliaCtx , values url . Values , method string , path string ) ( * Response , error ) {
2020-05-06 02:35:32 +07:00
var response Response
2019-04-25 04:52:08 +07:00
2021-12-01 10:32:58 +07:00
_ , responseBytes , err := d . DuoApi . SignedCall ( method , path , values )
2019-04-25 04:52:08 +07:00
if err != nil {
return nil , err
}
2021-12-01 10:32:58 +07: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 07:51:11 +07:00
2019-04-25 04:52:08 +07:00
err = json . Unmarshal ( responseBytes , & response )
if err != nil {
return nil , err
}
2020-05-06 02:35:32 +07:00
2021-12-01 10:32:58 +07: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-25 04:52:08 +07:00
return & response , nil
}
2021-12-01 10:32:58 +07: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
}