diff --git a/data/data.go b/data/data.go index 973a5c5..3a71709 100644 --- a/data/data.go +++ b/data/data.go @@ -6,8 +6,9 @@ import ( "os" "time" ) -import _ "github.com/go-sql-driver/mysql" +// mysql driver for sql database +import _ "github.com/go-sql-driver/mysql" var Db *sql.DB @@ -17,11 +18,10 @@ func init() { // To avoid client timeout Db.SetConnMaxLifetime(time.Second) - if err!= nil { + if err != nil { log.Print(err) return - } else - { + } else { log.Print("Successfully connected to datasource: " + getDatasource()) } return @@ -32,4 +32,3 @@ func getDatasource() (dataSource string) { ")/" + os.Getenv("DB_NAME") + "?parseTime=true" return } - diff --git a/google_oauth.go b/google_oauth.go index 7bf9e5e..f454910 100644 --- a/google_oauth.go +++ b/google_oauth.go @@ -3,11 +3,6 @@ package main import ( "context" "encoding/json" - "github.com/anuragdhingra/lets-chat/data" - "github.com/julienschmidt/httprouter" - "github.com/nu7hatch/gouuid" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" "io/ioutil" "log" "net/http" @@ -15,39 +10,45 @@ import ( "os" "strings" "time" + + "github.com/anuragdhingra/lets-chat/data" + "github.com/julienschmidt/httprouter" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" ) var googleOauthConfig = &oauth2.Config{ - RedirectURL: os.Getenv("OAUTH_REDIRECT_URI"), - ClientID: os.Getenv("CLIENT_ID"), + RedirectURL: os.Getenv("OAUTH_REDIRECT_URI"), + ClientID: os.Getenv("CLIENT_ID"), ClientSecret: os.Getenv("CLIENT_SECRET"), - Scopes: []string{"https://www.googleapis.com/auth/userinfo.email"}, - Endpoint: google.Endpoint, + Scopes: []string{"https://www.googleapis.com/auth/userinfo.email"}, + Endpoint: google.Endpoint, } +// GoogleUserInfo struct provides the info of the user type GoogleUserInfo struct { - Id int `json:"id"` - Email string `json:"email"` - VerifiedEmail bool `json:"verified_email"` - Name string `json:"name"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Link url.URL `json:"link"` - Picture url.URL `json:"picture"` + ID int `json:"id"` + Email string `json:"email"` + VerifiedEmail bool `json:"verified_email"` + Name string `json:"name"` + GivenName string `json:"given_name"` + FamilyName string `json:"family_name"` + Link url.URL `json:"link"` + Picture url.URL `json:"picture"` } +const oauthGoogleURLAPI = "https://www.googleapis.com/oauth2/v2/userinfo?access_token=" -const oauthGoogleUrlAPI = "https://www.googleapis.com/oauth2/v2/userinfo?access_token=" - +// GoogleSignUp registers the user func GoogleSignUp(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { u4, _ := uuid.NewV4() oauthState := u4.String() cookie := http.Cookie{ - Name:"oauthState", - Value:oauthState, + Name: "oauthState", + Value: oauthState, HttpOnly: true, - Expires: time.Now().Add(365 * 24 * time.Hour), - Path:"/oauth/google", + Expires: time.Now().Add(365 * 24 * time.Hour), + Path: "/oauth/google", } http.SetCookie(w, &cookie) @@ -56,6 +57,7 @@ func GoogleSignUp(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { http.Redirect(w, r, url, http.StatusTemporaryRedirect) } +// GoogleSignUpCallback returns the data from API and authenticates the user func GoogleSignUpCallback(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { oauthStateCookie, _ := r.Cookie("oauthState") oauthState := oauthStateCookie.Value @@ -101,11 +103,11 @@ func GoogleSignUpCallback(w http.ResponseWriter, r *http.Request, _ httprouter.P throwError(err) session, err := loggedInUser.CreateSession() cookie := http.Cookie{ - Name:"_cookie", - Value: session.Uuid, + Name: "_cookie", + Value: session.Uuid, HttpOnly: true, - Path:"/", + Path: "/", } http.SetCookie(w, &cookie) http.Redirect(w, r, "/", 302) -} \ No newline at end of file +} diff --git a/route_auth.go b/route_auth.go index 0f80a00..52dd741 100644 --- a/route_auth.go +++ b/route_auth.go @@ -1,27 +1,30 @@ package main import ( + "log" + "net/http" + "github.com/anuragdhingra/lets-chat/data" "github.com/julienschmidt/httprouter" "golang.org/x/crypto/bcrypt" - "log" - "net/http" ) +// Signup is the handler which validates url func Signup(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { checkInvalidRequests(w, r) generateHTML(w, nil, "layout", "public.navbar", "signup") } +// SignupAccount creates the user from the form data func SignupAccount(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { err := r.ParseForm() throwError(err) user := data.User{ - Username:r.PostFormValue("username"), - Email:r.PostFormValue("email"), - Password: encryptPassword(r.PostFormValue("password")), - HasPassword:true, + Username: r.PostFormValue("username"), + Email: r.PostFormValue("email"), + Password: encryptPassword(r.PostFormValue("password")), + HasPassword: true, } err = user.Create() @@ -29,11 +32,13 @@ func SignupAccount(w http.ResponseWriter, r *http.Request, _ httprouter.Params) http.Redirect(w, r, "/login", http.StatusFound) } +// Login function handles the login url func Login(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - checkInvalidRequests(w,r) + checkInvalidRequests(w, r) generateHTML(w, nil, "layout", "public.navbar", "login") } +// Authenticate handler authenticates the input form data func Authenticate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { err := r.ParseForm() throwError(err) @@ -49,40 +54,39 @@ func Authenticate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { log.Print(err) http.Redirect(w, r, "/login", http.StatusFound) return - } else { - session, err := user.CreateSession() - throwError(err) + } + session, err := user.CreateSession() + throwError(err) - cookie := http.Cookie{ - Name: "_cookie", - Value: session.Uuid, - HttpOnly: true, - } - http.SetCookie(w,&cookie) - - log.Print("User successfully logged in") - http.Redirect(w, r, "/", http.StatusFound) + cookie := http.Cookie{ + Name: "_cookie", + Value: session.Uuid, + HttpOnly: true, } + http.SetCookie(w, &cookie) + + log.Print("User successfully logged in") + http.Redirect(w, r, "/", http.StatusFound) } +// Logout closes the current session of the user func Logout(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { cookie, err := r.Cookie("_cookie") if err != http.ErrNoCookie { - sess := data.Session{Uuid:cookie.Value} + sess := data.Session{Uuid: cookie.Value} err = sess.DeleteByUUID() if err != nil { log.Print(err) return - } else { - cookie := http.Cookie{ - Name: "_cookie", - MaxAge: -1, - } - http.SetCookie(w, &cookie) - http.Redirect(w, r, "/", http.StatusFound) } + cookie := http.Cookie{ + Name: "_cookie", + MaxAge: -1, + } + http.SetCookie(w, &cookie) + http.Redirect(w, r, "/", http.StatusFound) } else { log.Print("Invalid request") http.Redirect(w, r, "/", http.StatusFound) } -} \ No newline at end of file +} diff --git a/route_main.go b/route_main.go index bf856a1..245225a 100644 --- a/route_main.go +++ b/route_main.go @@ -1,35 +1,38 @@ package main import ( - "github.com/anuragdhingra/lets-chat/data" - "github.com/julienschmidt/httprouter" "log" "net/http" + + "github.com/anuragdhingra/lets-chat/data" + "github.com/julienschmidt/httprouter" ) +// ThreadsInfoPrivate represents a list of private threads type ThreadsInfoPrivate struct { ThreadList []ThreadInfoPublic - User data.User + User data.User } +// ThreadsInfoPublic represents a list of public threads type ThreadsInfoPublic struct { ThreadList []ThreadInfoPublic } +// Index function creates index of thread func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { threads, err := data.Threads() if err != nil { log.Print(err) return + } + sess, err := session(w, r) + loggedInUser, err := sess.User() + if err != nil { + data := ThreadsInfoPublic{CreateThreadList(threads)} + generateHTML(w, data, "layout", "public.navbar", "index") } else { - sess, err := session(w, r) - loggedInUser, err := sess.User() - if err != nil { - data := ThreadsInfoPublic{CreateThreadList(threads)} - generateHTML(w, data, "layout","public.navbar", "index") - } else { - data := ThreadsInfoPrivate{CreateThreadList(threads), loggedInUser} - generateHTML(w, data, "layout", "private.navbar","index") - } + data := ThreadsInfoPrivate{CreateThreadList(threads), loggedInUser} + generateHTML(w, data, "layout", "private.navbar", "index") } - } \ No newline at end of file +} diff --git a/route_post.go b/route_post.go index d17ed74..7787fe5 100644 --- a/route_post.go +++ b/route_post.go @@ -1,16 +1,21 @@ package main import ( - "github.com/anuragdhingra/lets-chat/data" - "github.com/julienschmidt/httprouter" "log" "net/http" "strconv" + + "github.com/anuragdhingra/lets-chat/data" + "github.com/julienschmidt/httprouter" ) + +// PostInfoPublic organises public post data type PostInfoPublic struct { - Post data.Post + Post data.Post CreatedBy data.User } + +// CreatePost functions creates post from form data func CreatePost(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { sess, err := session(w, r) if err != nil { @@ -22,24 +27,25 @@ func CreatePost(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { err = r.ParseForm() throwError(err) postBody := r.PostFormValue("body") - threadIdString := r.PostFormValue("id") - threadId, err := strconv.Atoi(threadIdString) + threadIDString := r.PostFormValue("id") + threadID, err := strconv.Atoi(threadIdString) throwError(err) postRequest := data.PostRequest{postBody, user.Id, threadId} _, err = postRequest.CreatePost() throwError(err) - http.Redirect(w, r, "/threads/" + threadIdString, http.StatusFound) + http.Redirect(w, r, "/threads/"+threadIdString, http.StatusFound) } } +// CreatePostList function creates a list of posts of User func CreatePostList(posts []data.Post) (postListPublic []PostInfoPublic) { for _, post := range posts { - postUserId := post.UserId + postUserID := post.UserId user, err := data.UserById(postUserId) throwError(err) - postInfoPublic := PostInfoPublic{post,user} + postInfoPublic := PostInfoPublic{post, user} postListPublic = append(postListPublic, postInfoPublic) } return -} \ No newline at end of file +} diff --git a/route_thread.go b/route_thread.go index 681669f..3dab5cb 100644 --- a/route_thread.go +++ b/route_thread.go @@ -1,26 +1,30 @@ package main import ( - "github.com/anuragdhingra/lets-chat/data" - "github.com/julienschmidt/httprouter" "log" "net/http" "strconv" + + "github.com/anuragdhingra/lets-chat/data" + "github.com/julienschmidt/httprouter" ) +// ThreadInfoPublic handles public data of User type ThreadInfoPublic struct { - Thread data.Thread + Thread data.Thread CreatedBy data.User - Posts []PostInfoPublic + Posts []PostInfoPublic } +// ThreadInfoPrivate handles private data of User type ThreadInfoPrivate struct { - Thread data.Thread + Thread data.Thread CreatedBy data.User - User data.User - Posts []PostInfoPublic + User data.User + Posts []PostInfoPublic } +// NewThread function creates a new thread func NewThread(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { sess, err := session(w, r) if err == nil { @@ -29,9 +33,8 @@ func NewThread(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { if err != nil { log.Print(err) return - } else { - generateHTML(w, data, "layout", "private.navbar", "new.thread") } + generateHTML(w, data, "layout", "private.navbar", "new.thread") } else { log.Print(err) http.Redirect(w, r, "/login", http.StatusFound) @@ -39,6 +42,7 @@ func NewThread(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { } } +// CreateThread function requests a new thread from NewThread function func CreateThread(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { err := r.ParseForm() throwError(err) @@ -50,48 +54,48 @@ func CreateThread(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { createThreadRequest := data.CreateThreadRequest{ r.PostFormValue("topic"), user.Id, - } - threadId, err := createThreadRequest.Create() + threadID, err := createThreadRequest.Create() log.Print(threadId) throwError(err) - url := "/threads/" + strconv.Itoa(threadId) + url := "/threads/" + strconv.Itoa(threadId) log.Print(url) http.Redirect(w, r, url, http.StatusFound) } +// FindThread finds the thread by Id func FindThread(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - threadId := p.ByName("id") + threadID := p.ByName("id") thread, err := data.ThreadByID(threadId) if err != nil { log.Print(err) return + } + user, err := data.UserById(thread.UserId) + throwError(err) + posts, err := data.PostsByThreadId(thread.Id) + throwError(err) + postList := CreatePostList(posts) + sess, err := session(w, r) + if err != nil { + data := ThreadInfoPublic{thread, user, postList} + generateHTML(w, data, "layout", "public.navbar", "public.thread") } else { - user, err := data.UserById(thread.UserId) - throwError(err) - posts, err := data.PostsByThreadId(thread.Id) + loggedInUser, err := sess.User() throwError(err) - postList := CreatePostList(posts) - sess, err := session(w, r) - if err != nil { - data := ThreadInfoPublic{thread, user, postList} - generateHTML(w, data, "layout","public.navbar", "public.thread") - } else { - loggedInUser, err := sess.User() - throwError(err) - data := ThreadInfoPrivate{thread, user, loggedInUser, postList} - generateHTML(w, data, "layout", "private.navbar","private.thread") - } + data := ThreadInfoPrivate{thread, user, loggedInUser, postList} + generateHTML(w, data, "layout", "private.navbar", "private.thread") } } +// CreateThreadList creates a list of threads func CreateThreadList(threads []data.Thread) (threadListPublic []ThreadInfoPublic) { for _, thread := range threads { - threadUserId := thread.UserId + threadUserID := thread.UserId user, err := data.UserById(threadUserId) throwError(err) - threadInfoPublic := ThreadInfoPublic{thread,user, nil} + threadInfoPublic := ThreadInfoPublic{thread, user, nil} threadListPublic = append(threadListPublic, threadInfoPublic) } return -} \ No newline at end of file +} diff --git a/utils.go b/utils.go index 63b29fd..b53614b 100644 --- a/utils.go +++ b/utils.go @@ -3,21 +3,22 @@ package main import ( "errors" "fmt" - "github.com/anuragdhingra/lets-chat/data" - "golang.org/x/crypto/bcrypt" "html/template" "log" "net/http" + + "github.com/anuragdhingra/lets-chat/data" + "golang.org/x/crypto/bcrypt" ) func generateHTML(writer http.ResponseWriter, data interface{}, filenames ...string) { - var files []string - for _, file := range filenames { - files = append(files, fmt.Sprintf("templates/%s.html", file)) - } + var files []string + for _, file := range filenames { + files = append(files, fmt.Sprintf("templates/%s.html", file)) + } - templates := template.Must(template.ParseFiles(files...)) - templates.ExecuteTemplate(writer,"layout", data) + templates := template.Must(template.ParseFiles(files...)) + templates.ExecuteTemplate(writer, "layout", data) } func throwError(err error) { @@ -41,12 +42,11 @@ func session(w http.ResponseWriter, r *http.Request) (session data.Session, err if err != nil { log.Print(err) return - } else { - session = data.Session{Uuid:cookie.Value} - ok,_ := session.Check() - if !ok { - err = errors.New("Invalid session") - } + } + session = data.Session{Uuid: cookie.Value} + ok, _ := session.Check() + if !ok { + err = errors.New("Invalid session") } return } @@ -57,4 +57,4 @@ func checkInvalidRequests(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, `/`, http.StatusFound) return } -} \ No newline at end of file +}