init: Initial commit

This commit is contained in:
Björn Benouarets
2026-01-20 06:53:05 +01:00
commit fc8238759a
31 changed files with 1384 additions and 0 deletions

123
app/bot/auth.go Normal file
View 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
}