initial microsoft auth

This commit is contained in:
Samuel Walker 2024-10-30 16:41:03 -06:00
parent 3720f1e524
commit 806f6e2dbf
2 changed files with 183 additions and 1 deletions

View File

@ -2,7 +2,11 @@ package main
import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
@ -17,6 +21,7 @@ type App struct {
Java JavaManager
Instance InstanceManager
Modpacks ModpackManager
Auth authenticationResp
}
@ -64,7 +69,31 @@ func (a *App) CheckPrerequisites() {
a.Java.InstallJavaVer(21)
a.Status("Java 21 Installed")
}
dir, _ := os.UserConfigDir()
authenticated := false
if _, err := os.Stat(filepath.Join(dir, "FCLauncher", "authentication.json")); err == nil {
f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "authentication.json"), os.O_RDONLY, 0755)
defer f.Close()
data, _ := io.ReadAll(f)
json.Unmarshal(data, &a.Auth)
a.Auth, err = TokenRefresh(*a, a.Auth)
if err == nil {
authenticated = true
}
}
if !authenticated {
var err error
a.Auth, err = AuthCode(*a)
if err != nil {
fmt.Printf("Authentication Error: %s\n", err)
return
}
}
os.MkdirAll(filepath.Join(dir, "FCLauncher"), 0755)
f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "authentication.json"), os.O_CREATE|os.O_RDWR, 0755)
defer f.Close()
data, _ := json.Marshal(a.Auth)
f.Write(data)
}
func (App) GetVersions() ([]string, error) {

153
fclauncher/auth.go Normal file
View File

@ -0,0 +1,153 @@
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
wruntime "github.com/wailsapp/wails/v2/pkg/runtime"
)
type LauncherAuth struct {
Id string
Name string
token string
}
type McProfile struct {
Id string
Name string
}
type devcodeResp struct {
User_code string
Device_code string
Verification_url string
Expires_in string
Interval int
Message string
}
type authenticationResp struct {
Access_token string
Token_type string
Refresh_token string
Expires_in string
Error string
Error_description string
}
type xboxAuthProperties struct {
AuthMethod string
SiteName string
RpsTicket string
}
type xboxAuthRequest struct {
Properties xboxAuthProperties
RelyingParty string
TokenType string
}
type xboxDisplayClaim struct {
Uhs string
Gtg string
Xid string
Agg string
Usr string
Utr string
Prv string
}
type xboxDisplayClaims struct {
Xui []xboxDisplayClaim
}
type xboxAuthResponse struct {
IssueInstant time.Time
NotAfter time.Time
Token string
DisplayClaims xboxDisplayClaims
}
type XSTSProperties struct {
SandboxId string
UserTokens []string
}
type XSTSRequest struct {
Properties XSTSProperties
RelyingParty string
TokenType string
}
type McAuthRequest struct {
Xtoken string `json:"xtoken"`
Platform string `json:"platform"`
}
type McAuthResponse struct {
Username string
Access_token string
Expires_in string
Token_type string
}
func AuthCode(a App) (authenticationResp, error) {
authentication := authenticationResp{}
resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode", url.Values{
"client_id": {client_id},
"scope": {"XboxLive.SignIn XboxLive.offline_access"},
})
if err != nil {
return authentication, fmt.Errorf("Unable to request device code: %e\n", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return authentication, fmt.Errorf("Unable to request device code: %s\n", resp.Status)
}
data, _ := io.ReadAll(resp.Body)
codeResp := devcodeResp{}
json.Unmarshal(data, &codeResp)
//display message
wruntime.MessageDialog(a.Ctx, wruntime.MessageDialogOptions{Type: wruntime.InfoDialog, Title: "Authentication", Message: codeResp.Message})
ticker := time.NewTicker(time.Second * time.Duration(codeResp.Interval))
for range ticker.C {
resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/token", url.Values{
"client_id": {client_id},
"grant_type": {"urn:ietf:params:oauth:grant-type:device_code"},
"device_code": {codeResp.Device_code},
})
if err != nil {
return authentication, fmt.Errorf("Authentication request error %e\n", err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
json.Unmarshal(data, &authentication)
if authentication.Error == "" {
return authentication, nil
}
}
return authentication, fmt.Errorf("Unknown error")
}
func TokenRefresh(app App, auth authenticationResp) (authenticationResp, error) {
resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/token", url.Values{
"client_id": {client_id},
"grant_type": {"refresh_token"},
"refresh_token": {auth.Refresh_token},
"scope": {"XboxLive.SignIn XboxLive.offline_access"},
})
if err != nil {
return authenticationResp{}, fmt.Errorf("unable to request refresh token: %e\n", err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
authResp := authenticationResp{}
json.Unmarshal(data, &authResp)
return authResp, nil
}