init: Initial commit
This commit is contained in:
123
app/bot/auth.go
Normal file
123
app/bot/auth.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.secnex.io/secnex/masterlog"
|
||||
)
|
||||
|
||||
var AUTH *Auth
|
||||
|
||||
type Token struct {
|
||||
Data map[string]interface{}
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
|
||||
type Auth struct {
|
||||
TenantId string
|
||||
AppId string
|
||||
AppSecret string
|
||||
token *Token
|
||||
}
|
||||
|
||||
func NewAuth(tenantId, appId, appSecret string) *Auth {
|
||||
auth := &Auth{
|
||||
TenantId: tenantId,
|
||||
AppId: appId,
|
||||
AppSecret: appSecret,
|
||||
}
|
||||
AUTH = auth
|
||||
return auth
|
||||
}
|
||||
|
||||
func (a *Auth) getRequestUrl() string {
|
||||
return fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/v2.0/token", a.TenantId)
|
||||
}
|
||||
|
||||
func (a *Auth) requestToken() (*Token, error) {
|
||||
if a.TenantId == "" {
|
||||
return nil, fmt.Errorf("tenant ID is required but not set")
|
||||
}
|
||||
if a.AppId == "" {
|
||||
return nil, fmt.Errorf("app ID is required but not set")
|
||||
}
|
||||
if a.AppSecret == "" {
|
||||
return nil, fmt.Errorf("app secret is required but not set")
|
||||
}
|
||||
|
||||
requestUrl := a.getRequestUrl()
|
||||
masterlog.Debug("Requesting token", map[string]interface{}{
|
||||
"url": requestUrl,
|
||||
"tenantId": a.TenantId,
|
||||
"appId": a.AppId,
|
||||
})
|
||||
|
||||
body := url.Values{
|
||||
"grant_type": []string{"client_credentials"},
|
||||
"client_id": []string{a.AppId},
|
||||
"client_secret": []string{a.AppSecret},
|
||||
"scope": []string{"https://api.botframework.com/.default"},
|
||||
}
|
||||
req, err := http.NewRequest("POST", requestUrl, strings.NewReader(body.Encode()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bodyBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
masterlog.Error("Token request failed", map[string]interface{}{
|
||||
"statusCode": resp.StatusCode,
|
||||
})
|
||||
return nil, fmt.Errorf("token request failed with status %d: %s", resp.StatusCode, string(bodyBytes))
|
||||
}
|
||||
|
||||
masterlog.Debug("Token request successful", map[string]interface{}{
|
||||
"statusCode": resp.StatusCode,
|
||||
})
|
||||
|
||||
if len(bodyBytes) == 0 {
|
||||
return nil, fmt.Errorf("empty response body from token endpoint")
|
||||
}
|
||||
|
||||
var token Token
|
||||
err = json.Unmarshal(bodyBytes, &token)
|
||||
if err != nil {
|
||||
masterlog.Error("Failed to unmarshal token response", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, fmt.Errorf("failed to unmarshal token response: %w", err)
|
||||
}
|
||||
token.ExpiresAt = time.Now().Add(time.Duration(token.ExpiresIn) * time.Second)
|
||||
masterlog.Debug("Requested token", map[string]interface{}{"accessToken": token.AccessToken, "expiresIn": token.ExpiresIn, "expiresAt": token.ExpiresAt})
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
func (a *Auth) GetToken() (string, error) {
|
||||
if a.token == nil || a.token.ExpiresAt.Before(time.Now()) {
|
||||
token, err := a.requestToken()
|
||||
if err != nil {
|
||||
masterlog.Error("Failed to refresh token", map[string]interface{}{"error": err.Error()})
|
||||
return "", err
|
||||
}
|
||||
a.token = token
|
||||
masterlog.Debug("Refreshed token", map[string]interface{}{"token": a.token.AccessToken})
|
||||
}
|
||||
return a.token.AccessToken, nil
|
||||
}
|
||||
Reference in New Issue
Block a user