mirror of
https://github.com/ProtonMail/go-proton-api.git
synced 2026-02-23 10:16:03 -05:00
121 lines
3.3 KiB
Go
121 lines
3.3 KiB
Go
package backend
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
|
|
"github.com/ProtonMail/go-proton-api"
|
|
"github.com/ProtonMail/go-srp"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func (b *Backend) NewAuthInfo(username string) (proton.AuthInfo, error) {
|
|
return writeBackendRetErr(b, func(b *unsafeBackend) (proton.AuthInfo, error) {
|
|
return withAccName(b, username, func(acc *account) (proton.AuthInfo, error) {
|
|
server, err := srp.NewServerFromSigned(modulus, acc.verifier, 2048)
|
|
if err != nil {
|
|
log.WithError(err).Errorf("Failed to create SRP Server")
|
|
return proton.AuthInfo{}, fmt.Errorf("failed to create new srp server %w", err)
|
|
}
|
|
|
|
challenge, err := server.GenerateChallenge()
|
|
if err != nil {
|
|
log.WithError(err).Errorf("Failed to generate srp challeng")
|
|
return proton.AuthInfo{}, fmt.Errorf("failed to generate srp challend %w", err)
|
|
}
|
|
|
|
session := uuid.NewString()
|
|
|
|
b.srp[session] = server
|
|
|
|
return proton.AuthInfo{
|
|
Version: 4,
|
|
Modulus: modulus,
|
|
ServerEphemeral: base64.StdEncoding.EncodeToString(challenge),
|
|
Salt: base64.StdEncoding.EncodeToString(acc.salt),
|
|
SRPSession: session,
|
|
}, nil
|
|
})
|
|
})
|
|
}
|
|
|
|
func (b *Backend) NewAuth(username string, ephemeral, proof []byte, session string) (proton.Auth, error) {
|
|
return writeBackendRetErr(b, func(b *unsafeBackend) (proton.Auth, error) {
|
|
return withAccName(b, username, func(acc *account) (proton.Auth, error) {
|
|
server, ok := b.srp[session]
|
|
if !ok {
|
|
log.Errorf("Session '%v' not found for user='%v'", session, username)
|
|
return proton.Auth{}, fmt.Errorf("invalid session")
|
|
}
|
|
|
|
delete(b.srp, session)
|
|
|
|
serverProof, err := server.VerifyProofs(ephemeral, proof)
|
|
if err != nil {
|
|
return proton.Auth{}, fmt.Errorf("invalid proof: %w", err)
|
|
}
|
|
|
|
authUID, auth := uuid.NewString(), newAuth(b.authLife)
|
|
|
|
acc.auth[authUID] = auth
|
|
|
|
return auth.toAuth(acc.userID, authUID, serverProof), nil
|
|
})
|
|
})
|
|
}
|
|
|
|
func (b *Backend) NewAuthRef(authUID, authRef string) (proton.Auth, error) {
|
|
return writeBackendRetErr(b, func(b *unsafeBackend) (proton.Auth, error) {
|
|
for _, acc := range b.accounts {
|
|
auth, ok := acc.auth[authUID]
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
if auth.ref != authRef {
|
|
return proton.Auth{}, fmt.Errorf("invalid auth ref")
|
|
}
|
|
|
|
newAuth := newAuth(b.authLife)
|
|
|
|
acc.auth[authUID] = newAuth
|
|
|
|
return newAuth.toAuth(acc.userID, authUID, nil), nil
|
|
}
|
|
|
|
return proton.Auth{}, fmt.Errorf("invalid auth")
|
|
})
|
|
}
|
|
|
|
func (b *Backend) VerifyAuth(authUID, authAcc string) (string, error) {
|
|
return writeBackendRetErr(b, func(b *unsafeBackend) (string, error) {
|
|
return withAccAuth(b, authUID, authAcc, func(acc *account) (string, error) {
|
|
return acc.userID, nil
|
|
})
|
|
})
|
|
}
|
|
|
|
func (b *Backend) GetSessions(userID string) ([]proton.AuthSession, error) {
|
|
return readBackendRetErr(b, func(b *unsafeBackend) ([]proton.AuthSession, error) {
|
|
return withAcc(b, userID, func(acc *account) ([]proton.AuthSession, error) {
|
|
var sessions []proton.AuthSession
|
|
|
|
for authUID, auth := range acc.auth {
|
|
sessions = append(sessions, auth.toAuthSession(authUID))
|
|
}
|
|
|
|
return sessions, nil
|
|
})
|
|
})
|
|
}
|
|
|
|
func (b *Backend) DeleteSession(userID, authUID string) error {
|
|
return writeBackendRet(b, func(b *unsafeBackend) error {
|
|
return b.withAcc(userID, func(acc *account) error {
|
|
delete(acc.auth, authUID)
|
|
|
|
return nil
|
|
})
|
|
})
|
|
}
|