groundwork for other account routes
This commit is contained in:
parent
0ea69345b9
commit
26c482cd86
|
@ -111,10 +111,18 @@ func main() {
|
||||||
// TEMPLATE FLAGS
|
// TEMPLATE FLAGS
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: flagNames.TemplateBaseDir,
|
Name: flagNames.TemplateBaseDir,
|
||||||
Usage: "Basedir for html templating files for rendering pages and composing emails",
|
Usage: "Basedir for html templating files for rendering pages and composing emails.",
|
||||||
Value: "./web/template/",
|
Value: "./web/template/",
|
||||||
EnvVars: []string{envNames.TemplateBaseDir},
|
EnvVars: []string{envNames.TemplateBaseDir},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ACCOUNTS FLAGS
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: flagNames.AccountsOpenRegistration,
|
||||||
|
Usage: "Allow anyone to submit an account signup request. If false, server will be invite-only.",
|
||||||
|
Value: false,
|
||||||
|
EnvVars: []string{envNames.AccountsOpenRegistration},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
{
|
{
|
||||||
|
|
24
internal/config/accounts.go
Normal file
24
internal/config/accounts.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
GoToSocial
|
||||||
|
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package config
|
||||||
|
|
||||||
|
type AccountsConfig struct {
|
||||||
|
// Do we want people to be able to just submit sign up requests, or do we want invite only?
|
||||||
|
OpenRegistration bool
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ type Config struct {
|
||||||
Protocol string `yaml:"protocol"`
|
Protocol string `yaml:"protocol"`
|
||||||
DBConfig *DBConfig `yaml:"db"`
|
DBConfig *DBConfig `yaml:"db"`
|
||||||
TemplateConfig *TemplateConfig `yaml:"template"`
|
TemplateConfig *TemplateConfig `yaml:"template"`
|
||||||
|
AccountsConfig *AccountsConfig `yaml:"accounts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromFile returns a new config from a file, or an error if something goes amiss.
|
// FromFile returns a new config from a file, or an error if something goes amiss.
|
||||||
|
@ -136,11 +137,17 @@ func (c *Config) ParseCLIFlags(f KeyedFlags) {
|
||||||
if c.TemplateConfig.BaseDir == "" || f.IsSet(fn.TemplateBaseDir) {
|
if c.TemplateConfig.BaseDir == "" || f.IsSet(fn.TemplateBaseDir) {
|
||||||
c.TemplateConfig.BaseDir = f.String(fn.TemplateBaseDir)
|
c.TemplateConfig.BaseDir = f.String(fn.TemplateBaseDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// accounts flags
|
||||||
|
if f.IsSet(fn.AccountsOpenRegistration) {
|
||||||
|
c.AccountsConfig.OpenRegistration = f.Bool(fn.AccountsOpenRegistration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyedFlags is a wrapper for any type that can store keyed flags and give them back.
|
// KeyedFlags is a wrapper for any type that can store keyed flags and give them back.
|
||||||
// HINT: This works with a urfave cli context struct ;)
|
// HINT: This works with a urfave cli context struct ;)
|
||||||
type KeyedFlags interface {
|
type KeyedFlags interface {
|
||||||
|
Bool(k string) bool
|
||||||
String(k string) string
|
String(k string) string
|
||||||
Int(k string) int
|
Int(k string) int
|
||||||
IsSet(k string) bool
|
IsSet(k string) bool
|
||||||
|
@ -149,36 +156,38 @@ type KeyedFlags interface {
|
||||||
// Flags is used for storing the names of the various flags used for
|
// Flags is used for storing the names of the various flags used for
|
||||||
// initializing and storing urfavecli flag variables.
|
// initializing and storing urfavecli flag variables.
|
||||||
type Flags struct {
|
type Flags struct {
|
||||||
LogLevel string
|
LogLevel string
|
||||||
ApplicationName string
|
ApplicationName string
|
||||||
ConfigPath string
|
ConfigPath string
|
||||||
Host string
|
Host string
|
||||||
Protocol string
|
Protocol string
|
||||||
DbType string
|
DbType string
|
||||||
DbAddress string
|
DbAddress string
|
||||||
DbPort string
|
DbPort string
|
||||||
DbUser string
|
DbUser string
|
||||||
DbPassword string
|
DbPassword string
|
||||||
DbDatabase string
|
DbDatabase string
|
||||||
TemplateBaseDir string
|
TemplateBaseDir string
|
||||||
|
AccountsOpenRegistration string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFlagNames returns a struct containing the names of the various flags used for
|
// GetFlagNames returns a struct containing the names of the various flags used for
|
||||||
// initializing and storing urfavecli flag variables.
|
// initializing and storing urfavecli flag variables.
|
||||||
func GetFlagNames() Flags {
|
func GetFlagNames() Flags {
|
||||||
return Flags{
|
return Flags{
|
||||||
LogLevel: "log-level",
|
LogLevel: "log-level",
|
||||||
ApplicationName: "application-name",
|
ApplicationName: "application-name",
|
||||||
ConfigPath: "config-path",
|
ConfigPath: "config-path",
|
||||||
Host: "host",
|
Host: "host",
|
||||||
Protocol: "protocol",
|
Protocol: "protocol",
|
||||||
DbType: "db-type",
|
DbType: "db-type",
|
||||||
DbAddress: "db-address",
|
DbAddress: "db-address",
|
||||||
DbPort: "db-port",
|
DbPort: "db-port",
|
||||||
DbUser: "db-user",
|
DbUser: "db-user",
|
||||||
DbPassword: "db-password",
|
DbPassword: "db-password",
|
||||||
DbDatabase: "db-database",
|
DbDatabase: "db-database",
|
||||||
TemplateBaseDir: "template-basedir",
|
TemplateBaseDir: "template-basedir",
|
||||||
|
AccountsOpenRegistration: "accounts-open-registration",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,17 +195,18 @@ func GetFlagNames() Flags {
|
||||||
// initializing and storing urfavecli flag variables.
|
// initializing and storing urfavecli flag variables.
|
||||||
func GetEnvNames() Flags {
|
func GetEnvNames() Flags {
|
||||||
return Flags{
|
return Flags{
|
||||||
LogLevel: "GTS_LOG_LEVEL",
|
LogLevel: "GTS_LOG_LEVEL",
|
||||||
ApplicationName: "GTS_APPLICATION_NAME",
|
ApplicationName: "GTS_APPLICATION_NAME",
|
||||||
ConfigPath: "GTS_CONFIG_PATH",
|
ConfigPath: "GTS_CONFIG_PATH",
|
||||||
Host: "GTS_HOST",
|
Host: "GTS_HOST",
|
||||||
Protocol: "GTS_PROTOCOL",
|
Protocol: "GTS_PROTOCOL",
|
||||||
DbType: "GTS_DB_TYPE",
|
DbType: "GTS_DB_TYPE",
|
||||||
DbAddress: "GTS_DB_ADDRESS",
|
DbAddress: "GTS_DB_ADDRESS",
|
||||||
DbPort: "GTS_DB_PORT",
|
DbPort: "GTS_DB_PORT",
|
||||||
DbUser: "GTS_DB_USER",
|
DbUser: "GTS_DB_USER",
|
||||||
DbPassword: "GTS_DB_PASSWORD",
|
DbPassword: "GTS_DB_PASSWORD",
|
||||||
DbDatabase: "GTS_DB_DATABASE",
|
DbDatabase: "GTS_DB_DATABASE",
|
||||||
TemplateBaseDir: "GTS_TEMPLATE_BASEDIR",
|
TemplateBaseDir: "GTS_TEMPLATE_BASEDIR",
|
||||||
|
AccountsOpenRegistration: "GTS_ACCOUNTS_OPEN_REGISTRATION",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,6 +304,7 @@ func (ps *postgresService) GetAccountByUserID(userID string, account *model.Acco
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := ps.conn.Model(account).Where("id = ?", user.AccountID).Select(); err != nil {
|
if err := ps.conn.Model(account).Where("id = ?", user.AccountID).Select(); err != nil {
|
||||||
|
fmt.Println(account)
|
||||||
if err == pg.ErrNoRows {
|
if err == pg.ErrNoRows {
|
||||||
return ErrNoEntries{}
|
return ErrNoEntries{}
|
||||||
}
|
}
|
||||||
|
@ -394,7 +395,7 @@ func (ps *postgresService) AccountToMastoSensitive(a *model.Account) (*mastotype
|
||||||
fmt.Printf("fields: %+v", fields)
|
fmt.Printf("fields: %+v", fields)
|
||||||
|
|
||||||
// count followers
|
// count followers
|
||||||
var followers []model.Follow
|
followers := []model.Follow{}
|
||||||
if err := ps.GetFollowersByAccountID(a.ID, &followers); err != nil {
|
if err := ps.GetFollowersByAccountID(a.ID, &followers); err != nil {
|
||||||
if _, ok := err.(ErrNoEntries); !ok {
|
if _, ok := err.(ErrNoEntries); !ok {
|
||||||
return nil, fmt.Errorf("error getting followers: %s", err)
|
return nil, fmt.Errorf("error getting followers: %s", err)
|
||||||
|
@ -406,7 +407,7 @@ func (ps *postgresService) AccountToMastoSensitive(a *model.Account) (*mastotype
|
||||||
}
|
}
|
||||||
|
|
||||||
// count following
|
// count following
|
||||||
var following []model.Follow
|
following := []model.Follow{}
|
||||||
if err := ps.GetFollowingByAccountID(a.ID, &following); err != nil {
|
if err := ps.GetFollowingByAccountID(a.ID, &following); err != nil {
|
||||||
if _, ok := err.(ErrNoEntries); !ok {
|
if _, ok := err.(ErrNoEntries); !ok {
|
||||||
return nil, fmt.Errorf("error getting following: %s", err)
|
return nil, fmt.Errorf("error getting following: %s", err)
|
||||||
|
@ -418,7 +419,7 @@ func (ps *postgresService) AccountToMastoSensitive(a *model.Account) (*mastotype
|
||||||
}
|
}
|
||||||
|
|
||||||
// count statuses
|
// count statuses
|
||||||
var statuses []model.Status
|
statuses := []model.Status{}
|
||||||
if err := ps.GetStatusesByAccountID(a.ID, &statuses); err != nil {
|
if err := ps.GetStatusesByAccountID(a.ID, &statuses); err != nil {
|
||||||
if _, ok := err.(ErrNoEntries); !ok {
|
if _, ok := err.(ErrNoEntries); !ok {
|
||||||
return nil, fmt.Errorf("error getting last statuses: %s", err)
|
return nil, fmt.Errorf("error getting last statuses: %s", err)
|
||||||
|
@ -430,7 +431,7 @@ func (ps *postgresService) AccountToMastoSensitive(a *model.Account) (*mastotype
|
||||||
}
|
}
|
||||||
|
|
||||||
// check when the last status was
|
// check when the last status was
|
||||||
var lastStatus *model.Status
|
lastStatus := &model.Status{}
|
||||||
if err := ps.GetLastStatusForAccountID(a.ID, lastStatus); err != nil {
|
if err := ps.GetLastStatusForAccountID(a.ID, lastStatus); err != nil {
|
||||||
if _, ok := err.(ErrNoEntries); !ok {
|
if _, ok := err.(ErrNoEntries); !ok {
|
||||||
return nil, fmt.Errorf("error getting last status: %s", err)
|
return nil, fmt.Errorf("error getting last status: %s", err)
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
package account
|
package account
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -29,6 +28,7 @@ import (
|
||||||
"github.com/gotosocial/gotosocial/internal/module"
|
"github.com/gotosocial/gotosocial/internal/module"
|
||||||
"github.com/gotosocial/gotosocial/internal/module/oauth"
|
"github.com/gotosocial/gotosocial/internal/module/oauth"
|
||||||
"github.com/gotosocial/gotosocial/internal/router"
|
"github.com/gotosocial/gotosocial/internal/router"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -40,49 +40,62 @@ const (
|
||||||
type accountModule struct {
|
type accountModule struct {
|
||||||
config *config.Config
|
config *config.Config
|
||||||
db db.DB
|
db db.DB
|
||||||
|
log *logrus.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new account module
|
// New returns a new account module
|
||||||
func New(config *config.Config, db db.DB) module.ClientAPIModule {
|
func New(config *config.Config, db db.DB, log *logrus.Logger) module.ClientAPIModule {
|
||||||
return &accountModule{
|
return &accountModule{
|
||||||
config: config,
|
config: config,
|
||||||
db: db,
|
db: db,
|
||||||
|
log: log,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route attaches all routes from this module to the given router
|
// Route attaches all routes from this module to the given router
|
||||||
func (m *accountModule) Route(r router.Router) error {
|
func (m *accountModule) Route(r router.Router) error {
|
||||||
|
r.AttachHandler(http.MethodPost, basePath, m.AccountCreatePOSTHandler)
|
||||||
r.AttachHandler(http.MethodGet, verifyPath, m.AccountVerifyGETHandler)
|
r.AttachHandler(http.MethodGet, verifyPath, m.AccountVerifyGETHandler)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *accountModule) AccountCreatePOSTHandler(c *gin.Context) {
|
||||||
|
l := m.log.WithField("func", "AccountCreatePOSTHandler")
|
||||||
|
l.Trace("checking if registration is open")
|
||||||
|
if !m.config.AccountsConfig.OpenRegistration {
|
||||||
|
l.Trace("account registration is closed, returning error to client")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AccountVerifyGETHandler serves a user's account details to them IF they reached this
|
// AccountVerifyGETHandler serves a user's account details to them IF they reached this
|
||||||
// handler while in possession of a valid token, according to the oauth middleware.
|
// handler while in possession of a valid token, according to the oauth middleware.
|
||||||
func (m *accountModule) AccountVerifyGETHandler(c *gin.Context) {
|
func (m *accountModule) AccountVerifyGETHandler(c *gin.Context) {
|
||||||
i, ok := c.Get(oauth.SessionAuthorizedUser)
|
l := m.log.WithField("func", "AccountVerifyGETHandler")
|
||||||
fmt.Println(i)
|
|
||||||
|
l.Trace("getting account details from session")
|
||||||
|
i, ok := c.Get(oauth.SessionAuthorizedAccount)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
l.Trace("no account in session, returning error to client")
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "The access token is invalid"})
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "The access token is invalid"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, ok := (i).(string)
|
l.Trace("attempting to convert account interface into account struct...")
|
||||||
if !ok || userID == "" {
|
acct, ok := i.(*model.Account)
|
||||||
|
if !ok {
|
||||||
|
l.Tracef("could not convert %+v into account struct, returning error to client", i)
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "The access token is invalid"})
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "The access token is invalid"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
acct := &model.Account{}
|
l.Tracef("retrieved account %+v, converting to mastosensitive...", acct)
|
||||||
if err := m.db.GetAccountByUserID(userID, acct); err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
acctSensitive, err := m.db.AccountToMastoSensitive(acct)
|
acctSensitive, err := m.db.AccountToMastoSensitive(acct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
l.Tracef("could not convert account into mastosensitive account: %s", err)
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l.Tracef("conversion successful, returning OK and mastosensitive account %+v", acctSensitive)
|
||||||
c.JSON(http.StatusOK, acctSensitive)
|
c.JSON(http.StatusOK, acctSensitive)
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,10 +216,19 @@ func (suite *AccountTestSuite) TestAPIInitialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.AttachMiddleware(func(c *gin.Context) {
|
r.AttachMiddleware(func(c *gin.Context) {
|
||||||
|
account := &model.Account{}
|
||||||
|
if err := suite.db.GetAccountByUserID(suite.testUser.ID, account); err != nil || account == nil {
|
||||||
|
suite.T().Log(err)
|
||||||
|
suite.FailNowf("no account found for user %s, continuing with unauthenticated request: %+v", "", suite.testUser.ID, account)
|
||||||
|
fmt.Println(account)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Set(oauth.SessionAuthorizedAccount, account)
|
||||||
c.Set(oauth.SessionAuthorizedUser, suite.testUser.ID)
|
c.Set(oauth.SessionAuthorizedUser, suite.testUser.ID)
|
||||||
})
|
})
|
||||||
|
|
||||||
acct := New(suite.config, suite.db)
|
acct := New(suite.config, suite.db, log)
|
||||||
acct.Route(r)
|
acct.Route(r)
|
||||||
|
|
||||||
r.Start()
|
r.Start()
|
||||||
|
|
|
@ -47,11 +47,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
appsPath = "/api/v1/apps"
|
appsPath = "/api/v1/apps"
|
||||||
authSignInPath = "/auth/sign_in"
|
authSignInPath = "/auth/sign_in"
|
||||||
oauthTokenPath = "/oauth/token"
|
oauthTokenPath = "/oauth/token"
|
||||||
oauthAuthorizePath = "/oauth/authorize"
|
oauthAuthorizePath = "/oauth/authorize"
|
||||||
SessionAuthorizedUser = "authorized_user"
|
SessionAuthorizedUser = "authorized_user"
|
||||||
|
SessionAuthorizedAccount = "authorized_account"
|
||||||
)
|
)
|
||||||
|
|
||||||
// oauthModule is an oauth2 oauthModule that satisfies the ClientAPIModule interface
|
// oauthModule is an oauth2 oauthModule that satisfies the ClientAPIModule interface
|
||||||
|
@ -406,16 +407,30 @@ func (m *oauthModule) authorizePOSTHandler(c *gin.Context) {
|
||||||
MIDDLEWARE
|
MIDDLEWARE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// oauthTokenMiddleware
|
// oauthTokenMiddleware checks if the client has presented a valid oauth Bearer token.
|
||||||
|
// If so, it will check the User that the token belongs to, and set that in the context of
|
||||||
|
// the request. Then, it will look up the account for that user, and set that in the request too.
|
||||||
|
// If user or account can't be found, then the handler won't *fail*, in case the server wants to allow
|
||||||
|
// public requests that don't have a Bearer token set (eg., for public instance information and so on).
|
||||||
func (m *oauthModule) oauthTokenMiddleware(c *gin.Context) {
|
func (m *oauthModule) oauthTokenMiddleware(c *gin.Context) {
|
||||||
l := m.log.WithField("func", "ValidatePassword")
|
l := m.log.WithField("func", "ValidatePassword")
|
||||||
l.Trace("entering OauthTokenMiddleware")
|
l.Trace("entering OauthTokenMiddleware")
|
||||||
if ti, err := m.oauthServer.ValidationBearerToken(c.Request); err == nil {
|
|
||||||
l.Tracef("authenticated user %s with bearer token, scope is %s", ti.GetUserID(), ti.GetScope())
|
ti, err := m.oauthServer.ValidationBearerToken(c.Request)
|
||||||
c.Set(SessionAuthorizedUser, ti.GetUserID())
|
if err != nil {
|
||||||
} else {
|
l.Trace("no valid token presented: continuing with unauthenticated request")
|
||||||
l.Trace("continuing with unauthenticated request")
|
return
|
||||||
}
|
}
|
||||||
|
l.Tracef("authenticated user %s with bearer token, scope is %s", ti.GetUserID(), ti.GetScope())
|
||||||
|
|
||||||
|
acct := &model.Account{}
|
||||||
|
if err := m.db.GetAccountByUserID(ti.GetUserID(), acct); err != nil || acct == nil {
|
||||||
|
l.Tracef("no account found for user %s, continuing with unauthenticated request", ti.GetUserID())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Set(SessionAuthorizedAccount, acct)
|
||||||
|
c.Set(SessionAuthorizedUser, ti.GetUserID())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
23
internal/util/validation.go
Normal file
23
internal/util/validation.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
GoToSocial
|
||||||
|
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
func CheckPasswordStrength(password string) bool {
|
||||||
|
return true
|
||||||
|
}
|
|
@ -67,3 +67,21 @@ type Account struct {
|
||||||
// An extra entity to be used with API methods to verify credentials and update credentials.
|
// An extra entity to be used with API methods to verify credentials and update credentials.
|
||||||
Source *Source `json:"source"`
|
Source *Source `json:"source"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AccountCreateRequest represents the form submitted during a POST request to /api/v1/accounts.
|
||||||
|
// See https://docs.joinmastodon.org/methods/accounts/
|
||||||
|
type AccountCreateRequest struct {
|
||||||
|
// Text that will be reviewed by moderators if registrations require manual approval.
|
||||||
|
Reason string `form:"reason"`
|
||||||
|
// The desired username for the account
|
||||||
|
Username string `form:"username"`
|
||||||
|
// The email address to be used for login
|
||||||
|
Email string `form:"email"`
|
||||||
|
// The password to be used for login
|
||||||
|
Password string `form:"password"`
|
||||||
|
// Whether the user agrees to the local rules, terms, and policies.
|
||||||
|
// These should be presented to the user in order to allow them to consent before setting this parameter to TRUE.
|
||||||
|
Agreement bool `form:"agreement"`
|
||||||
|
// The language of the confirmation email that will be sent
|
||||||
|
Locale string `form:"locale"`
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user