Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10494012
oauth_signup.go
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Subscribers
None
oauth_signup.go
View Options
/*
* Copyright © 2020-2021 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
* WriteFreely is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, included
* in the LICENSE file in this source code package.
*/
package
writefreely
import
(
"crypto/sha256"
"encoding/hex"
"fmt"
"github.com/writeas/impart"
"github.com/writeas/web-core/auth"
"github.com/writeas/web-core/log"
"github.com/writefreely/writefreely/page"
"html/template"
"net/http"
"strings"
"time"
)
type
viewOauthSignupVars
struct
{
page
.
StaticPage
To
string
Message
template
.
HTML
Flashes
[]
template
.
HTML
AccessToken
string
TokenUsername
string
TokenAlias
string
// TODO: rename this to match the data it represents: the collection title
TokenEmail
string
TokenRemoteUser
string
Provider
string
ClientID
string
TokenHash
string
InviteCode
string
LoginUsername
string
Alias
string
// TODO: rename this to match the data it represents: the collection title
Email
string
}
const
(
oauthParamAccessToken
=
"access_token"
oauthParamTokenUsername
=
"token_username"
oauthParamTokenAlias
=
"token_alias"
oauthParamTokenEmail
=
"token_email"
oauthParamTokenRemoteUserID
=
"token_remote_user"
oauthParamClientID
=
"client_id"
oauthParamProvider
=
"provider"
oauthParamHash
=
"signature"
oauthParamUsername
=
"username"
oauthParamAlias
=
"alias"
oauthParamEmail
=
"email"
oauthParamPassword
=
"password"
oauthParamInviteCode
=
"invite_code"
)
type
oauthSignupPageParams
struct
{
AccessToken
string
TokenUsername
string
TokenAlias
string
// TODO: rename this to match the data it represents: the collection title
TokenEmail
string
TokenRemoteUser
string
ClientID
string
Provider
string
TokenHash
string
InviteCode
string
}
func
(
p
oauthSignupPageParams
)
HashTokenParams
(
key
string
)
string
{
hasher
:=
sha256
.
New
()
hasher
.
Write
([]
byte
(
key
))
hasher
.
Write
([]
byte
(
p
.
AccessToken
))
hasher
.
Write
([]
byte
(
p
.
TokenUsername
))
hasher
.
Write
([]
byte
(
p
.
TokenAlias
))
hasher
.
Write
([]
byte
(
p
.
TokenEmail
))
hasher
.
Write
([]
byte
(
p
.
TokenRemoteUser
))
hasher
.
Write
([]
byte
(
p
.
ClientID
))
hasher
.
Write
([]
byte
(
p
.
Provider
))
return
hex
.
EncodeToString
(
hasher
.
Sum
(
nil
))
}
func
(
h
oauthHandler
)
viewOauthSignup
(
app
*
App
,
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
error
{
tp
:=
&
oauthSignupPageParams
{
AccessToken
:
r
.
FormValue
(
oauthParamAccessToken
),
TokenUsername
:
r
.
FormValue
(
oauthParamTokenUsername
),
TokenAlias
:
r
.
FormValue
(
oauthParamTokenAlias
),
TokenEmail
:
r
.
FormValue
(
oauthParamTokenEmail
),
TokenRemoteUser
:
r
.
FormValue
(
oauthParamTokenRemoteUserID
),
ClientID
:
r
.
FormValue
(
oauthParamClientID
),
Provider
:
r
.
FormValue
(
oauthParamProvider
),
InviteCode
:
r
.
FormValue
(
oauthParamInviteCode
),
}
if
tp
.
HashTokenParams
(
h
.
Config
.
Server
.
HashSeed
)
!=
r
.
FormValue
(
oauthParamHash
)
{
return
impart
.
HTTPError
{
Status
:
http
.
StatusBadRequest
,
Message
:
"Request has been tampered with."
}
}
tp
.
TokenHash
=
tp
.
HashTokenParams
(
h
.
Config
.
Server
.
HashSeed
)
if
err
:=
h
.
validateOauthSignup
(
r
);
err
!=
nil
{
return
h
.
showOauthSignupPage
(
app
,
w
,
r
,
tp
,
err
)
}
var
err
error
hashedPass
:=
[]
byte
{}
clearPass
:=
r
.
FormValue
(
oauthParamPassword
)
hasPass
:=
clearPass
!=
""
if
hasPass
{
hashedPass
,
err
=
auth
.
HashPass
([]
byte
(
clearPass
))
if
err
!=
nil
{
return
h
.
showOauthSignupPage
(
app
,
w
,
r
,
tp
,
fmt
.
Errorf
(
"unable to hash password"
))
}
}
newUser
:=
&
User
{
Username
:
r
.
FormValue
(
oauthParamUsername
),
HashedPass
:
hashedPass
,
HasPass
:
hasPass
,
Email
:
prepareUserEmail
(
r
.
FormValue
(
oauthParamEmail
),
h
.
EmailKey
),
Created
:
time
.
Now
().
Truncate
(
time
.
Second
).
UTC
(),
}
displayName
:=
r
.
FormValue
(
oauthParamAlias
)
if
len
(
displayName
)
==
0
{
displayName
=
r
.
FormValue
(
oauthParamUsername
)
}
err
=
h
.
DB
.
CreateUser
(
h
.
Config
,
newUser
,
displayName
)
if
err
!=
nil
{
return
h
.
showOauthSignupPage
(
app
,
w
,
r
,
tp
,
err
)
}
// Log invite if needed
if
tp
.
InviteCode
!=
""
{
err
=
app
.
db
.
CreateInvitedUser
(
tp
.
InviteCode
,
newUser
.
ID
)
if
err
!=
nil
{
return
err
}
}
err
=
h
.
DB
.
RecordRemoteUserID
(
r
.
Context
(),
newUser
.
ID
,
r
.
FormValue
(
oauthParamTokenRemoteUserID
),
r
.
FormValue
(
oauthParamProvider
),
r
.
FormValue
(
oauthParamClientID
),
r
.
FormValue
(
oauthParamAccessToken
))
if
err
!=
nil
{
return
h
.
showOauthSignupPage
(
app
,
w
,
r
,
tp
,
err
)
}
if
err
:=
loginOrFail
(
h
.
Store
,
w
,
r
,
newUser
);
err
!=
nil
{
return
h
.
showOauthSignupPage
(
app
,
w
,
r
,
tp
,
err
)
}
return
nil
}
func
(
h
oauthHandler
)
validateOauthSignup
(
r
*
http
.
Request
)
error
{
username
:=
r
.
FormValue
(
oauthParamUsername
)
if
len
(
username
)
<
h
.
Config
.
App
.
MinUsernameLen
{
return
impart
.
HTTPError
{
Status
:
http
.
StatusBadRequest
,
Message
:
"Username is too short."
}
}
if
len
(
username
)
>
100
{
return
impart
.
HTTPError
{
Status
:
http
.
StatusBadRequest
,
Message
:
"Username is too long."
}
}
collTitle
:=
r
.
FormValue
(
oauthParamAlias
)
if
len
(
collTitle
)
==
0
{
collTitle
=
username
}
email
:=
r
.
FormValue
(
oauthParamEmail
)
if
len
(
email
)
>
0
{
parts
:=
strings
.
Split
(
email
,
"@"
)
if
len
(
parts
)
!=
2
||
(
len
(
parts
[
0
])
<
1
||
len
(
parts
[
1
])
<
1
)
{
return
impart
.
HTTPError
{
Status
:
http
.
StatusBadRequest
,
Message
:
"Invalid email address"
}
}
}
return
nil
}
func
(
h
oauthHandler
)
showOauthSignupPage
(
app
*
App
,
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
tp
*
oauthSignupPageParams
,
errMsg
error
)
error
{
username
:=
tp
.
TokenUsername
collTitle
:=
tp
.
TokenAlias
email
:=
tp
.
TokenEmail
session
,
err
:=
app
.
sessionStore
.
Get
(
r
,
cookieName
)
if
err
!=
nil
{
// Ignore this
log
.
Error
(
"Unable to get session; ignoring: %v"
,
err
)
}
if
tmpValue
:=
r
.
FormValue
(
oauthParamUsername
);
len
(
tmpValue
)
>
0
{
username
=
tmpValue
}
if
tmpValue
:=
r
.
FormValue
(
oauthParamAlias
);
len
(
tmpValue
)
>
0
{
collTitle
=
tmpValue
}
if
tmpValue
:=
r
.
FormValue
(
oauthParamEmail
);
len
(
tmpValue
)
>
0
{
email
=
tmpValue
}
p
:=
&
viewOauthSignupVars
{
StaticPage
:
pageForReq
(
app
,
r
),
To
:
r
.
FormValue
(
"to"
),
Flashes
:
[]
template
.
HTML
{},
AccessToken
:
tp
.
AccessToken
,
TokenUsername
:
tp
.
TokenUsername
,
TokenAlias
:
tp
.
TokenAlias
,
TokenEmail
:
tp
.
TokenEmail
,
TokenRemoteUser
:
tp
.
TokenRemoteUser
,
Provider
:
tp
.
Provider
,
ClientID
:
tp
.
ClientID
,
TokenHash
:
tp
.
TokenHash
,
InviteCode
:
tp
.
InviteCode
,
LoginUsername
:
username
,
Alias
:
collTitle
,
Email
:
email
,
}
// Display any error messages
flashes
,
_
:=
getSessionFlashes
(
app
,
w
,
r
,
session
)
for
_
,
flash
:=
range
flashes
{
p
.
Flashes
=
append
(
p
.
Flashes
,
template
.
HTML
(
flash
))
}
if
errMsg
!=
nil
{
p
.
Flashes
=
append
(
p
.
Flashes
,
template
.
HTML
(
errMsg
.
Error
()))
}
err
=
pages
[
"signup-oauth.tmpl"
].
ExecuteTemplate
(
w
,
"base"
,
p
)
if
err
!=
nil
{
log
.
Error
(
"Unable to render signup-oauth: %v"
,
err
)
return
err
}
return
nil
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 6, 3:32 AM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3165286
Attached To
rWF WriteFreely
Event Timeline
Log In to Comment