mirror of
https://gitea.phreedom.club/localhost_frssoft/bloat.git
synced 2024-11-25 06:09:22 +02:00
Added sign up support. Tested on mastodon
But required test on GoToSocial. Confirmation inside bloat-fe not supported
This commit is contained in:
parent
f9702f81a9
commit
0f060f09c9
|
@ -3,10 +3,13 @@ package mastodon
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
"strings"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AccountPleroma struct {
|
type AccountPleroma struct {
|
||||||
|
@ -59,6 +62,71 @@ type AccountSource struct {
|
||||||
Fields *[]Field `json:"fields"`
|
Fields *[]Field `json:"fields"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RegisterCredintals struct {
|
||||||
|
http.Client
|
||||||
|
Server string
|
||||||
|
App *Application
|
||||||
|
Reason string
|
||||||
|
Username string
|
||||||
|
Email string
|
||||||
|
Password string
|
||||||
|
Agreement bool
|
||||||
|
Locale string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use for register account on GoToSocial
|
||||||
|
type Registred struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
Scope string `json:"scope"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// RegisterAccount create new account
|
||||||
|
func RegisterAccount(ctx context.Context, instance string, reason string, username string, email string, password string, agreement bool, locale string, registerCrendintals RegisterCredintals, bearer string) (*string, error) {
|
||||||
|
var registred Registred
|
||||||
|
params := url.Values{}
|
||||||
|
params.Set("reason", reason)
|
||||||
|
params.Set("username", username)
|
||||||
|
params.Set("email", email)
|
||||||
|
params.Set("password", password)
|
||||||
|
params.Set("agreement", strconv.FormatBool(agreement))
|
||||||
|
params.Set("locale", locale)
|
||||||
|
u, err := url.Parse("https://" + instance)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.Path = path.Join(u.Path, "/api/v1/accounts")
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(params.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
req.Header.Set("Authorization", "Bearer "+bearer)
|
||||||
|
resp, err := registerCrendintals.Do(req)
|
||||||
|
fmt.Println(req)
|
||||||
|
fmt.Println(resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, parseAPIError("bad request", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(®istred)
|
||||||
|
fmt.Println(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ®istred.AccessToken, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// GetAccount return Account.
|
// GetAccount return Account.
|
||||||
func (c *Client) GetAccount(ctx context.Context, id string) (*Account, error) {
|
func (c *Client) GetAccount(ctx context.Context, id string) (*Account, error) {
|
||||||
var account Account
|
var account Account
|
||||||
|
|
|
@ -48,7 +48,6 @@ func RegisterApp(ctx context.Context, appConfig *AppConfig) (*Application, error
|
||||||
params.Set("redirect_uris", appConfig.RedirectURIs)
|
params.Set("redirect_uris", appConfig.RedirectURIs)
|
||||||
}
|
}
|
||||||
params.Set("scopes", appConfig.Scopes)
|
params.Set("scopes", appConfig.Scopes)
|
||||||
params.Set("website", "https://gitea.phreedom.club/localhost_frssoft/bloat/src/branch/localhost_custom")
|
|
||||||
|
|
||||||
u, err := url.Parse(appConfig.Server)
|
u, err := url.Parse(appConfig.Server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -94,3 +93,50 @@ func RegisterApp(ctx context.Context, appConfig *AppConfig) (*Application, error
|
||||||
|
|
||||||
return &app, nil
|
return &app, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppAuth struct {
|
||||||
|
http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterApp make auth application and return app token.
|
||||||
|
func AuthApp(ctx context.Context, appConfig *Application, instance string) (*string, error) {
|
||||||
|
var appAuth AppAuth
|
||||||
|
params := url.Values{}
|
||||||
|
params.Set("client_id", appConfig.ClientID)
|
||||||
|
params.Set("client_secret", appConfig.ClientSecret)
|
||||||
|
params.Set("redirect_uris", "urn:ietf:wg:oauth:2.0:oob")
|
||||||
|
params.Set("grant_type", "client_credentials")
|
||||||
|
params.Set("scope", "read write follow")
|
||||||
|
|
||||||
|
u, err := url.Parse("https://" + instance)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.Path = path.Join(u.Path, "/oauth/token")
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(params.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
resp, err := appAuth.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, parseAPIError("bad request", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var res struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
}
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &res.AccessToken, nil
|
||||||
|
}
|
||||||
|
|
|
@ -202,6 +202,8 @@ func (c *Client) Authenticate(ctx context.Context, username, password string) er
|
||||||
return c.authenticate(ctx, params)
|
return c.authenticate(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// AuthenticateToken logs in using a grant token returned by Application.AuthURI.
|
// AuthenticateToken logs in using a grant token returned by Application.AuthURI.
|
||||||
//
|
//
|
||||||
// redirectURI should be the same as Application.RedirectURI.
|
// redirectURI should be the same as Application.RedirectURI.
|
||||||
|
|
|
@ -920,6 +920,72 @@ func (s *service) Signin(c *client, code string) (err error) {
|
||||||
return c.setSession(c.s)
|
return c.setSession(c.s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *service) NewSessionRegister(c *client, instance string, reason string, username string, email string, password string, agreement bool, locale string, registerCredintals mastodon.RegisterCredintals) (rurl string, sess *model.Session, err error) {
|
||||||
|
var instanceURL string
|
||||||
|
if strings.HasPrefix(instance, "https://") {
|
||||||
|
instanceURL = instance
|
||||||
|
instance = strings.TrimPrefix(instance, "https://")
|
||||||
|
} else {
|
||||||
|
instanceURL = "https://" + instance
|
||||||
|
}
|
||||||
|
|
||||||
|
sid, err := util.NewSessionID()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
csrf, err := util.NewCSRFToken()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app, err := mastodon.RegisterApp(c.ctx, &mastodon.AppConfig{
|
||||||
|
Server: instanceURL,
|
||||||
|
ClientName: s.cname,
|
||||||
|
Scopes: s.cscope,
|
||||||
|
Website: s.cwebsite,
|
||||||
|
RedirectURIs: s.cwebsite + "/oauth_callback",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
registerCredintals.App = app
|
||||||
|
bearer, err := mastodon.AuthApp(c.ctx, app, instance)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
token, err := mastodon.RegisterAccount(c.ctx, instance, reason, username, email, password, agreement, locale, registerCredintals, *bearer)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sess = &model.Session{
|
||||||
|
ID: sid,
|
||||||
|
Instance: instance,
|
||||||
|
UserID: "1",
|
||||||
|
ClientID: app.ClientID,
|
||||||
|
ClientSecret: app.ClientSecret,
|
||||||
|
AccessToken: *token,
|
||||||
|
CSRFToken: csrf,
|
||||||
|
Settings: *model.NewSettings(),
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse("/oauth/authorize")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
q := make(url.Values)
|
||||||
|
q.Set("scope", "read write follow")
|
||||||
|
q.Set("client_id", app.ClientID)
|
||||||
|
q.Set("response_type", "code")
|
||||||
|
q.Set("redirect_uri", s.cwebsite+"/oauth_callback")
|
||||||
|
u.RawQuery = q.Encode()
|
||||||
|
|
||||||
|
rurl = instanceURL + u.String()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func (s *service) Post(c *client, content string, replyToID string,
|
func (s *service) Post(c *client, content string, replyToID string,
|
||||||
format string, visibility string, isNSFW bool, spoilerText string,
|
format string, visibility string, isNSFW bool, spoilerText string,
|
||||||
files []*multipart.FileHeader, edit string) (id string, err error) {
|
files []*multipart.FileHeader, edit string) (id string, err error) {
|
||||||
|
|
|
@ -254,6 +254,32 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
|
||||||
return nil
|
return nil
|
||||||
}, NOAUTH, HTML)
|
}, NOAUTH, HTML)
|
||||||
|
|
||||||
|
signup := handle(func(c *client) error {
|
||||||
|
instance := c.r.FormValue("instanceup")
|
||||||
|
reason := c.r.FormValue("reason")
|
||||||
|
username := c.r.FormValue("username")
|
||||||
|
email := c.r.FormValue("email")
|
||||||
|
password := c.r.FormValue("password")
|
||||||
|
agreement := c.r.FormValue("agreement") == "true"
|
||||||
|
locale := c.r.FormValue("locale")
|
||||||
|
url, sess, err := s.NewSessionRegister(c, instance, reason, username, email, password, agreement, locale, mastodon.RegisterCredintals{
|
||||||
|
Server: "https://"+instance,
|
||||||
|
Reason: reason,
|
||||||
|
Username: username,
|
||||||
|
Email: email,
|
||||||
|
Password: password,
|
||||||
|
Agreement: agreement,
|
||||||
|
Locale: locale,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.setSession(sess)
|
||||||
|
url = "/confirmation"
|
||||||
|
c.redirect(url)
|
||||||
|
return nil
|
||||||
|
}, NOAUTH, HTML)
|
||||||
|
|
||||||
oauthCallback := handle(func(c *client) error {
|
oauthCallback := handle(func(c *client) error {
|
||||||
q := c.r.URL.Query()
|
q := c.r.URL.Query()
|
||||||
token := q.Get("code")
|
token := q.Get("code")
|
||||||
|
@ -786,6 +812,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
|
||||||
r.HandleFunc("/settings", settingsPage).Methods(http.MethodGet)
|
r.HandleFunc("/settings", settingsPage).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/filters", filtersPage).Methods(http.MethodGet)
|
r.HandleFunc("/filters", filtersPage).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/signin", signin).Methods(http.MethodPost)
|
r.HandleFunc("/signin", signin).Methods(http.MethodPost)
|
||||||
|
r.HandleFunc("/signup", signup).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/oauth_callback", oauthCallback).Methods(http.MethodGet)
|
r.HandleFunc("/oauth_callback", oauthCallback).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/post", post).Methods(http.MethodPost)
|
r.HandleFunc("/post", post).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/like/{id}", like).Methods(http.MethodPost)
|
r.HandleFunc("/like/{id}", like).Methods(http.MethodPost)
|
||||||
|
|
|
@ -18,6 +18,39 @@
|
||||||
<a href="https://git.freesoftwareextremist.com/bloat" target="_blank">git.freesoftwareextremist.com/bloat</a>
|
<a href="https://git.freesoftwareextremist.com/bloat" target="_blank">git.freesoftwareextremist.com/bloat</a>
|
||||||
for more details.
|
for more details.
|
||||||
</P>
|
</P>
|
||||||
|
<details>
|
||||||
|
<summary>Sign up</summary>
|
||||||
|
<p>
|
||||||
|
<form class="signup-form" action="/signup" method="post">
|
||||||
|
Enter the domain name of your instance to continue
|
||||||
|
<br/>
|
||||||
|
<input type="text" name="instanceup" placeholder="example.com" required>
|
||||||
|
<br/>
|
||||||
|
Enter the reason why you want register
|
||||||
|
<br/>
|
||||||
|
<textarea type="text" name="reason" cols="80" rows="3" required></textarea>
|
||||||
|
<br/>
|
||||||
|
The desired username for the account
|
||||||
|
<br/>
|
||||||
|
<input type="text" name="username" placeholder="exampleusernick" required>
|
||||||
|
<br/>
|
||||||
|
The email address to be used for login
|
||||||
|
<br/>
|
||||||
|
<input type="text" name="email" placeholder="example@example.com" required>
|
||||||
|
<br/>
|
||||||
|
The password to be used for login (Please use strong password!)
|
||||||
|
<br/>
|
||||||
|
<input type="password" name="password" required>
|
||||||
|
<br/>
|
||||||
|
You agrees to the terms, conditions, and policies of the instance
|
||||||
|
<br/>
|
||||||
|
<input type="checkbox" value="true" name="agreement" required>
|
||||||
|
<input type="hidden" name="locale" value="en">
|
||||||
|
<br/>
|
||||||
|
<button type="submit"> Signup </button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
{{template "footer.tmpl"}}
|
{{template "footer.tmpl"}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
Loading…
Reference in New Issue