Format all source files.
This commit is contained in:
parent
f7ad8b9c5f
commit
fa89e0719f
7 changed files with 142 additions and 138 deletions
16
arcgis.go
16
arcgis.go
|
|
@ -15,9 +15,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/Gleipnir-Technology/arcgis-go"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/models"
|
||||
"github.com/aarondl/opt/omit"
|
||||
)
|
||||
|
||||
var CodeVerifier string = "random_secure_string_min_43_chars_long_should_be_stored_in_session"
|
||||
|
|
@ -65,8 +65,8 @@ func generateCodeVerifier() string {
|
|||
func getArcgisUserData(access_token string, expires time.Time, refresh_token string) {
|
||||
client := arcgis.NewArcGIS(
|
||||
arcgis.AuthenticatorOAuth{
|
||||
AccessToken: access_token,
|
||||
Expires: expires,
|
||||
AccessToken: access_token,
|
||||
Expires: expires,
|
||||
RefreshToken: refresh_token,
|
||||
},
|
||||
)
|
||||
|
|
@ -78,7 +78,7 @@ func getArcgisUserData(access_token string, expires time.Time, refresh_token str
|
|||
slog.Info("Got portals data",
|
||||
slog.String("Username", portal.User.Username),
|
||||
slog.String("ID", portal.ID))
|
||||
*/
|
||||
*/
|
||||
search, err := client.Search("Fieldseeker")
|
||||
if err != nil {
|
||||
slog.Error("Failed to get search FieldseekerGIS data", slog.String("err", err.Error()))
|
||||
|
|
@ -87,7 +87,7 @@ func getArcgisUserData(access_token string, expires time.Time, refresh_token str
|
|||
for _, result := range search.Results {
|
||||
slog.Info("Got result", slog.String("name", result.Name))
|
||||
//if result.Name == "FieldseekerGIS" {
|
||||
//slog.Info("Found Fieldseeker", slog.String("url", result.URL))
|
||||
//slog.Info("Found Fieldseeker", slog.String("url", result.URL))
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -142,10 +142,10 @@ func handleOauthAccessCode(ctx context.Context, user *models.User, code string)
|
|||
|
||||
expires := futureUTCTimestamp(tokenResponse.ExpiresIn)
|
||||
setter := models.OauthTokenSetter{
|
||||
AccessToken: omit.From(tokenResponse.AccessToken),
|
||||
Expires: omit.From(expires),
|
||||
AccessToken: omit.From(tokenResponse.AccessToken),
|
||||
Expires: omit.From(expires),
|
||||
RefreshToken: omit.From(tokenResponse.RefreshToken),
|
||||
Username: omit.From(tokenResponse.Username),
|
||||
Username: omit.From(tokenResponse.Username),
|
||||
}
|
||||
err = user.InsertUserOauthTokens(ctx, PGInstance.BobDB, &setter)
|
||||
if err != nil {
|
||||
|
|
|
|||
31
auth.go
31
auth.go
|
|
@ -8,20 +8,23 @@ import (
|
|||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/enums"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/sql"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type NoCredentialsError struct{}
|
||||
|
||||
func (e NoCredentialsError) Error() string { return "No credentials were present in the request" }
|
||||
|
||||
type InvalidCredentials struct{}
|
||||
|
||||
func (e InvalidCredentials) Error() string { return "No username with that password exists" }
|
||||
|
||||
type InvalidUsername struct{}
|
||||
|
||||
func (e InvalidUsername) Error() string { return "That username doesn't exist" }
|
||||
|
||||
func addUserSession(r *http.Request, user *models.User) {
|
||||
|
|
@ -85,10 +88,10 @@ func signupUser(username string, name string, password string) (*models.User, er
|
|||
return nil, fmt.Errorf("Cannot signup user: %v", err)
|
||||
}
|
||||
setter := models.UserSetter{
|
||||
DisplayName: omit.From(name),
|
||||
PasswordHash: omit.From(passwordHash),
|
||||
DisplayName: omit.From(name),
|
||||
PasswordHash: omit.From(passwordHash),
|
||||
PasswordHashType: omit.From(enums.HashtypeBcrypt14),
|
||||
Username: omit.From(username),
|
||||
Username: omit.From(username),
|
||||
}
|
||||
u, err := models.Users.Insert(&setter).One(context.TODO(), PGInstance.BobDB)
|
||||
if err != nil {
|
||||
|
|
@ -120,7 +123,7 @@ func validateUser(ctx context.Context, username string, password string) (*model
|
|||
return nil, fmt.Errorf("Failed to query for user: %v", err)
|
||||
}
|
||||
switch len(result) {
|
||||
case 0:
|
||||
case 0:
|
||||
return nil, InvalidUsername{}
|
||||
case 1:
|
||||
row := result[0]
|
||||
|
|
@ -128,16 +131,16 @@ func validateUser(ctx context.Context, username string, password string) (*model
|
|||
return nil, InvalidCredentials{}
|
||||
}
|
||||
user := models.User{
|
||||
ID: row.ID,
|
||||
ArcgisAccessToken: row.ArcgisAccessToken,
|
||||
ArcgisLicense: row.ArcgisLicense,
|
||||
ArcgisRefreshToken: row.ArcgisRefreshToken,
|
||||
ID: row.ID,
|
||||
ArcgisAccessToken: row.ArcgisAccessToken,
|
||||
ArcgisLicense: row.ArcgisLicense,
|
||||
ArcgisRefreshToken: row.ArcgisRefreshToken,
|
||||
ArcgisRefreshTokenExpires: row.ArcgisRefreshTokenExpires,
|
||||
ArcgisRole: row.ArcgisRole,
|
||||
DisplayName: row.DisplayName,
|
||||
Email: row.Email,
|
||||
OrganizationID: row.OrganizationID,
|
||||
Username: row.Username,
|
||||
ArcgisRole: row.ArcgisRole,
|
||||
DisplayName: row.DisplayName,
|
||||
Email: row.Email,
|
||||
OrganizationID: row.OrganizationID,
|
||||
Username: row.Username,
|
||||
}
|
||||
return &user, nil
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import (
|
|||
var embedMigrations embed.FS
|
||||
|
||||
type postgres struct {
|
||||
BobDB bob.DB
|
||||
BobDB bob.DB
|
||||
PGXPool *pgxpool.Pool
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ func postSignin(w http.ResponseWriter, r *http.Request) {
|
|||
slog.String("username", username),
|
||||
slog.String("password", strings.Repeat("*", len(password))))
|
||||
|
||||
|
||||
_, err := signinUser(r, username, password)
|
||||
if err != nil {
|
||||
if errors.Is(err, InvalidCredentials{}) {
|
||||
|
|
|
|||
126
fileserver.go
126
fileserver.go
|
|
@ -1,4 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
|
@ -18,99 +19,100 @@ var embeddedStaticFS embed.FS
|
|||
// FileServer conveniently sets up a http.FileServer handler to serve
|
||||
// static files from a http.FileSystem.
|
||||
func FileServer(r chi.Router, path string, root http.FileSystem, embeddedFS embed.FS, embeddedPath string) {
|
||||
if strings.ContainsAny(path, "{}*") {
|
||||
panic("FileServer does not permit any URL parameters.")
|
||||
}
|
||||
if strings.ContainsAny(path, "{}*") {
|
||||
panic("FileServer does not permit any URL parameters.")
|
||||
}
|
||||
|
||||
if path != "/" && path[len(path)-1] != '/' {
|
||||
r.Get(path, http.RedirectHandler(path+"/", 301).ServeHTTP)
|
||||
path += "/"
|
||||
}
|
||||
path += "*"
|
||||
if path != "/" && path[len(path)-1] != '/' {
|
||||
r.Get(path, http.RedirectHandler(path+"/", 301).ServeHTTP)
|
||||
path += "/"
|
||||
}
|
||||
path += "*"
|
||||
|
||||
r.Get(path, func(w http.ResponseWriter, r *http.Request) {
|
||||
rctx := chi.RouteContext(r.Context())
|
||||
pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*")
|
||||
r.Get(path, func(w http.ResponseWriter, r *http.Request) {
|
||||
rctx := chi.RouteContext(r.Context())
|
||||
pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*")
|
||||
|
||||
// Determine the actual file path
|
||||
requestedPath := strings.TrimPrefix(r.URL.Path, pathPrefix)
|
||||
// Determine the actual file path
|
||||
requestedPath := strings.TrimPrefix(r.URL.Path, pathPrefix)
|
||||
|
||||
// Try to open from local filesystem first for development
|
||||
localFile, localErr := root.Open(requestedPath)
|
||||
// Try to open from local filesystem first for development
|
||||
localFile, localErr := root.Open(requestedPath)
|
||||
|
||||
var fileToServe http.File
|
||||
var fileToServe http.File
|
||||
|
||||
if localErr == nil {
|
||||
// File found in local filesystem
|
||||
fileToServe = localFile
|
||||
} else {
|
||||
// If not found locall, try embedded filesystem
|
||||
embeddedFilePath := filepath.Join(embeddedPath, requestedPath)
|
||||
embeddedFile, err := embeddedFS.Open(embeddedFilePath)
|
||||
if localErr == nil {
|
||||
// File found in local filesystem
|
||||
fileToServe = localFile
|
||||
} else {
|
||||
// If not found locall, try embedded filesystem
|
||||
embeddedFilePath := filepath.Join(embeddedPath, requestedPath)
|
||||
embeddedFile, err := embeddedFS.Open(embeddedFilePath)
|
||||
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Wrap the embedded file to implement http.File interface
|
||||
fileToServe = &embeddedFileWrapper{embeddedFile}
|
||||
// Wrap the embedded file to implement http.File interface
|
||||
fileToServe = &embeddedFileWrapper{embeddedFile}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Create a custom ResponseWriter that allows us to modify headers
|
||||
crw := &customResponseWriter{ResponseWriter: w}
|
||||
// Create a custom ResponseWriter that allows us to modify headers
|
||||
crw := &customResponseWriter{ResponseWriter: w}
|
||||
|
||||
// Serve the file
|
||||
http.ServeContent(crw, r, requestedPath, time.Time{}, fileToServe)
|
||||
// Serve the file
|
||||
http.ServeContent(crw, r, requestedPath, time.Time{}, fileToServe)
|
||||
|
||||
// Close the file
|
||||
fileToServe.Close()
|
||||
})
|
||||
// Close the file
|
||||
fileToServe.Close()
|
||||
})
|
||||
}
|
||||
|
||||
type embeddedFileWrapper struct {
|
||||
file fs.File
|
||||
file fs.File
|
||||
}
|
||||
|
||||
func (e *embeddedFileWrapper) Close() error {
|
||||
return e.file.Close()
|
||||
return e.file.Close()
|
||||
}
|
||||
|
||||
func (e *embeddedFileWrapper) Read(p []byte) (n int, err error) {
|
||||
return e.file.Read(p)
|
||||
return e.file.Read(p)
|
||||
}
|
||||
|
||||
type Seeker interface {
|
||||
Seek(offset int64, whence int) (int64, error)
|
||||
Seek(offset int64, whence int) (int64, error)
|
||||
}
|
||||
|
||||
func (e *embeddedFileWrapper) Seek(offset int64, whence int) (int64, error) {
|
||||
if seeker, ok := e.file.(Seeker); ok {
|
||||
return seeker.Seek(offset, whence)
|
||||
}
|
||||
return 0, fmt.Errorf("Seek not supported")
|
||||
if seeker, ok := e.file.(Seeker); ok {
|
||||
return seeker.Seek(offset, whence)
|
||||
}
|
||||
return 0, fmt.Errorf("Seek not supported")
|
||||
}
|
||||
|
||||
func (e *embeddedFileWrapper) Readdir(count int) ([]os.FileInfo, error) {
|
||||
// This is a bit tricky with embedded files
|
||||
if dirFile, ok := e.file.(fs.ReadDirFile); ok {
|
||||
entries, err := dirFile.ReadDir(count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// This is a bit tricky with embedded files
|
||||
if dirFile, ok := e.file.(fs.ReadDirFile); ok {
|
||||
entries, err := dirFile.ReadDir(count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileInfos := make([]os.FileInfo, len(entries))
|
||||
for i, entry := range entries {
|
||||
fileInfos[i], err = entry.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return fileInfos, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Readdir not supported")
|
||||
fileInfos := make([]os.FileInfo, len(entries))
|
||||
for i, entry := range entries {
|
||||
fileInfos[i], err = entry.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return fileInfos, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Readdir not supported")
|
||||
}
|
||||
|
||||
func (e *embeddedFileWrapper) Stat() (os.FileInfo, error) {
|
||||
return e.file.Stat()
|
||||
return e.file.Stat()
|
||||
}
|
||||
|
|
|
|||
55
html.go
55
html.go
|
|
@ -9,23 +9,23 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/riverqueue/river/rivershared/util/slogutil"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/models"
|
||||
"github.com/riverqueue/river/rivershared/util/slogutil"
|
||||
)
|
||||
|
||||
var (
|
||||
dashboard = newBuiltTemplate("dashboard", "authenticated")
|
||||
report = newBuiltTemplate("report", "base")
|
||||
dashboard = newBuiltTemplate("dashboard", "authenticated")
|
||||
report = newBuiltTemplate("report", "base")
|
||||
reportConfirmation = newBuiltTemplate("report-confirmation", "base")
|
||||
reportContribute = newBuiltTemplate("report-contribute", "base")
|
||||
reportDetail = newBuiltTemplate("report-detail", "base")
|
||||
reportEvidence = newBuiltTemplate("report-evidence", "base")
|
||||
reportSchedule = newBuiltTemplate("report-schedule", "base")
|
||||
reportUpdate = newBuiltTemplate("report-update", "base")
|
||||
signin = newBuiltTemplate("signin", "base")
|
||||
signup = newBuiltTemplate("signup", "base")
|
||||
reportContribute = newBuiltTemplate("report-contribute", "base")
|
||||
reportDetail = newBuiltTemplate("report-detail", "base")
|
||||
reportEvidence = newBuiltTemplate("report-evidence", "base")
|
||||
reportSchedule = newBuiltTemplate("report-schedule", "base")
|
||||
reportUpdate = newBuiltTemplate("report-update", "base")
|
||||
signin = newBuiltTemplate("signin", "base")
|
||||
signup = newBuiltTemplate("signup", "base")
|
||||
)
|
||||
var components = [ ... ]string{"header"}
|
||||
var components = [...]string{"header"}
|
||||
|
||||
type BuiltTemplate struct {
|
||||
files []string
|
||||
|
|
@ -37,7 +37,7 @@ type Link struct {
|
|||
Title string
|
||||
}
|
||||
type ContentReportDetail struct {
|
||||
NextURL string
|
||||
NextURL string
|
||||
UpdateURL string
|
||||
}
|
||||
type ContentReportDiagnostic struct {
|
||||
|
|
@ -51,11 +51,11 @@ type ContentPlaceholder struct {
|
|||
type ContentSignin struct {
|
||||
InvalidCredentials bool
|
||||
}
|
||||
type ContentSignup struct { }
|
||||
type ContentSignup struct{}
|
||||
type User struct {
|
||||
DisplayName string
|
||||
Initials string
|
||||
Username string
|
||||
Initials string
|
||||
Username string
|
||||
}
|
||||
|
||||
func (bt *BuiltTemplate) ExecuteTemplate(w io.Writer, data any) error {
|
||||
|
|
@ -77,23 +77,23 @@ func (bt *BuiltTemplate) ExecuteTemplate(w io.Writer, data any) error {
|
|||
|
||||
func extractInitials(name string) string {
|
||||
parts := strings.Fields(name)
|
||||
var initials strings.Builder
|
||||
var initials strings.Builder
|
||||
|
||||
for _, part := range parts {
|
||||
if len(part) > 0 {
|
||||
initials.WriteString(strings.ToUpper(string(part[0])))
|
||||
}
|
||||
}
|
||||
for _, part := range parts {
|
||||
if len(part) > 0 {
|
||||
initials.WriteString(strings.ToUpper(string(part[0])))
|
||||
}
|
||||
}
|
||||
|
||||
return initials.String()
|
||||
return initials.String()
|
||||
}
|
||||
|
||||
func htmlDashboard(w io.Writer, user *models.User) error {
|
||||
data := ContentDashboard{
|
||||
User: User{
|
||||
User: User{
|
||||
DisplayName: user.DisplayName,
|
||||
Initials: extractInitials(user.DisplayName),
|
||||
Username: user.Username,
|
||||
Initials: extractInitials(user.DisplayName),
|
||||
Username: user.Username,
|
||||
},
|
||||
}
|
||||
return dashboard.ExecuteTemplate(w, data)
|
||||
|
|
@ -126,7 +126,7 @@ func htmlReportContribute(w io.Writer, code string) error {
|
|||
func htmlReportDetail(w io.Writer, code string) error {
|
||||
nextURL := BaseURL + "/report/" + code + "/evidence"
|
||||
data := ContentReportDetail{
|
||||
NextURL: nextURL,
|
||||
NextURL: nextURL,
|
||||
UpdateURL: BaseURL + "/report/" + code + "/update",
|
||||
}
|
||||
return reportDetail.ExecuteTemplate(w, data)
|
||||
|
|
@ -164,8 +164,7 @@ func htmlSignin(w io.Writer, errorCode string) error {
|
|||
}
|
||||
|
||||
func htmlSignup(w io.Writer, path string) error {
|
||||
data := ContentSignup{
|
||||
}
|
||||
data := ContentSignup{}
|
||||
return signup.ExecuteTemplate(w, data)
|
||||
}
|
||||
|
||||
|
|
|
|||
29
response.go
29
response.go
|
|
@ -1,31 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Custom ResponseWriter to track Content-Type
|
||||
type customResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
contentType string
|
||||
wroteHeader bool
|
||||
http.ResponseWriter
|
||||
contentType string
|
||||
wroteHeader bool
|
||||
}
|
||||
|
||||
func (crw *customResponseWriter) WriteHeader(code int) {
|
||||
crw.wroteHeader = true
|
||||
crw.ResponseWriter.WriteHeader(code)
|
||||
crw.wroteHeader = true
|
||||
crw.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
func (crw *customResponseWriter) Header() http.Header {
|
||||
return crw.ResponseWriter.Header()
|
||||
return crw.ResponseWriter.Header()
|
||||
}
|
||||
|
||||
func (crw *customResponseWriter) Write(b []byte) (int, error) {
|
||||
if !crw.wroteHeader {
|
||||
if crw.contentType == "" {
|
||||
crw.contentType = http.DetectContentType(b)
|
||||
crw.ResponseWriter.Header().Set("Content-Type", crw.contentType)
|
||||
}
|
||||
crw.WriteHeader(http.StatusOK)
|
||||
}
|
||||
return crw.ResponseWriter.Write(b)
|
||||
if !crw.wroteHeader {
|
||||
if crw.contentType == "" {
|
||||
crw.contentType = http.DetectContentType(b)
|
||||
crw.ResponseWriter.Header().Set("Content-Type", crw.contentType)
|
||||
}
|
||||
crw.WriteHeader(http.StatusOK)
|
||||
}
|
||||
return crw.ResponseWriter.Write(b)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue