diff --git a/README.md b/README.md index 5a8a52ed..0593a1f7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Remark42 ia a comment engine, self-hosted, lightweight, simple (but functional) what doesn't spy on users. -- Supports social login via google and github +- Supports social login via google, facebook and github - Moderation allowing admins to remove comments and block users - Voting and pinning system - Ability to sort comments @@ -55,7 +55,7 @@ type User struct { } ``` -_currently supported providers are `google` and `github`_ +_currently supported providers are `google`, `facebook` and `github`_ ### Commenting @@ -102,10 +102,12 @@ Sort can be `time` or `score`. Supported sort order with prefix -/+, i.e. `-time - `GET /api/v1/id/{id}?site=site-id` - get comment by `id` - `GET /api/v1/comments?site=site-id&user=id` - get comment by `user id` - `GET /api/v1/count?site=site-id&url=post-url` - get comment's count for `{url}` +- `GET /api/v1/user` - get user info, _auth required_ - `PUT /api/v1/vote/{id}?site=site-id&url=post-url&vote=1` - vote for comment. `vote`=1 will increase score, -1 decreases. _auth required_ + +### Admin + - `DELETE /api/v1/admin/comment/{id}?site=site-id&url=post-url` - delete comment by `id`. _auth and admin required_ - `PUT /api/v1/admin/user/{userid}?site=site-id&block=1` - block or unblock user. _auth and admin required_ - `GET /api/v1/admin/export?site=side-id&block=1` - export all comments. _auth and admin required_ - `PUT /api/v1/admin/pin/{id}?site=site-id&url=post-url&pin=1` - pin or unpin comment. _auth and admin required_ -- `GET /api/v1/user` - get user info, _auth required_ - diff --git a/app/main.go b/app/main.go index 1921bd46..95dbcaae 100644 --- a/app/main.go +++ b/app/main.go @@ -18,7 +18,7 @@ import ( var opts struct { BoltPath string `long:"bolt" env:"BOLTDB_PATH" default:"/tmp" description:"parent dir for bolt files"` Sites []string `long:"site" env:"SITE" default:"remark" description:"site names" env-delim:","` - RemarkURL string `long:"url" env:"REMARK_URL" default:"https://remark42.com" description:"url to remark"` + RemarkURL string `long:"url" env:"REMARK_URL" default:"http://remark42.com" description:"url to remark"` Admins []string `long:"admin" env:"ADMIN" default:"umputun@gmail.com" description:"admin(s) names" env-delim:","` DevMode bool `long:"dev" env:"DEV" description:"development mode, no auth enforced"` @@ -30,10 +30,12 @@ var opts struct { SessionStore string `long:"session" env:"SESSION_STORE" default:"/tmp" description:"path to session store directory"` StoreKey string `long:"store-key" env:"STORE_KEY" default:"secure-store-key" description:"store key"` - GoogleCID string `long:"google-cid" env:"REMARK_GOOGLE_CID" description:"Google OAuth client ID"` - GoogleCSEC string `long:"google-csec" env:"REMARK_GOOGLE_CSEC" description:"Google OAuth client secret"` - GithubCID string `long:"github-cid" env:"REMARK_GITHUB_CID" description:"Github OAuth client ID"` - GithubCSEC string `long:"github-csec" env:"REMARK_GITHUB_CSEC" description:"Github OAuth client secret"` + GoogleCID string `long:"google-cid" env:"REMARK_GOOGLE_CID" description:"Google OAuth client ID"` + GoogleCSEC string `long:"google-csec" env:"REMARK_GOOGLE_CSEC" description:"Google OAuth client secret"` + GithubCID string `long:"github-cid" env:"REMARK_GITHUB_CID" description:"Github OAuth client ID"` + GithubCSEC string `long:"github-csec" env:"REMARK_GITHUB_CSEC" description:"Github OAuth client secret"` + FacebookCID string `long:"facebook-cid" env:"REMARK_FACEBOOK_CID" description:"Facebook OAuth client ID"` + FacebookCSEC string `long:"facebook-csec" env:"REMARK_FACEBOOK_CSEC" description:"Facebook OAuth client secret"` } `command:"server" description:"run server"` ImportCommand struct { @@ -100,6 +102,12 @@ func main() { SessionStore: sessionStore, RemarkURL: opts.RemarkURL, }), + AuthFacebook: auth.NewFacebook(auth.Params{ + Cid: opts.ServerCommand.FacebookCID, + Csecret: opts.ServerCommand.FacebookCSEC, + SessionStore: sessionStore, + RemarkURL: opts.RemarkURL, + }), } if opts.DevMode { diff --git a/app/rest/auth/providers.go b/app/rest/auth/providers.go index b564a45d..8c62f3de 100644 --- a/app/rest/auth/providers.go +++ b/app/rest/auth/providers.go @@ -3,6 +3,7 @@ package auth import ( "strings" + "golang.org/x/oauth2/facebook" "golang.org/x/oauth2/github" "golang.org/x/oauth2/google" @@ -14,7 +15,7 @@ func NewGoogle(p Params) *Provider { return initProvider(p, Provider{ Name: "google", Endpoint: google.Endpoint, - RedirectURL: p.RemarkURL + "/auth/google", + RedirectURL: p.RemarkURL + "/auth/google/callback", Scopes: []string{"https://www.googleapis.com/auth/userinfo.email"}, InfoURL: "https://www.googleapis.com/oauth2/v3/userinfo", FilesystemStore: p.SessionStore, @@ -39,7 +40,7 @@ func NewGithub(p Params) *Provider { return initProvider(p, Provider{ Name: "github", Endpoint: github.Endpoint, - RedirectURL: p.RemarkURL + "/auth/github", + RedirectURL: p.RemarkURL + "/auth/github/callback", Scopes: []string{"user:email"}, InfoURL: "https://api.github.com/user", FilesystemStore: p.SessionStore, @@ -58,3 +59,28 @@ func NewGithub(p Params) *Provider { }, }) } + +// NewFacebook makes facebook oauth2 provider +func NewFacebook(p Params) *Provider { + return initProvider(p, Provider{ + Name: "facebook", + Endpoint: facebook.Endpoint, + RedirectURL: p.RemarkURL + "/auth/facebook/callback", + Scopes: []string{"public_profile"}, + InfoURL: "https://graph.facebook.com/me", + FilesystemStore: p.SessionStore, + MapUser: func(data map[string]interface{}) store.User { + userInfo := store.User{ + ID: data["id"].(string), + Name: data["name"].(string), + // Picture: data["avatar_url"].(string), + // Profile: data["html_url"].(string), + } + if userInfo.Name == "" { + userInfo.Name = userInfo.ID + } + userInfo.ID = "facebook_" + userInfo.ID + return userInfo + }, + }) +} diff --git a/app/rest/server.go b/app/rest/server.go index 2feac2c8..df57f47a 100644 --- a/app/rest/server.go +++ b/app/rest/server.go @@ -31,6 +31,7 @@ type Server struct { Admins []string AuthGoogle *auth.Provider AuthGithub *auth.Provider + AuthFacebook *auth.Provider SessionStore *sessions.FilesystemStore Exporter migrator.Exporter DevMode bool @@ -64,6 +65,7 @@ func (s *Server) Run() { router.Mount("/auth/google", s.AuthGoogle.Routes()) router.Mount("/auth/github", s.AuthGithub.Routes()) + router.Mount("/auth/facebook", s.AuthFacebook.Routes()) router.Route("/api/v1", func(rapi chi.Router) { rapi.Get("/find", s.findCommentsCtrl) diff --git a/vendor/golang.org/x/oauth2/facebook/facebook.go b/vendor/golang.org/x/oauth2/facebook/facebook.go new file mode 100644 index 00000000..14c801a2 --- /dev/null +++ b/vendor/golang.org/x/oauth2/facebook/facebook.go @@ -0,0 +1,16 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package facebook provides constants for using OAuth2 to access Facebook. +package facebook // import "golang.org/x/oauth2/facebook" + +import ( + "golang.org/x/oauth2" +) + +// Endpoint is Facebook's OAuth 2.0 endpoint. +var Endpoint = oauth2.Endpoint{ + AuthURL: "https://www.facebook.com/dialog/oauth", + TokenURL: "https://graph.facebook.com/oauth/access_token", +} diff --git a/vendor/vendor.json b/vendor/vendor.json index f322946e..1241db27 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -160,6 +160,12 @@ "revision": "0448841f0cbe9d174c6c1cedd177f583337b8e2c", "revisionTime": "2017-12-14T23:38:05Z" }, + { + "checksumSHA1": "9fgYIPOCIRhAuQBg65mFoZ2vpMY=", + "path": "golang.org/x/oauth2/facebook", + "revision": "0448841f0cbe9d174c6c1cedd177f583337b8e2c", + "revisionTime": "2017-12-14T23:38:05Z" + }, { "checksumSHA1": "Yokz/Wl4zeuOZG2ev8LuaLtMotE=", "path": "golang.org/x/oauth2/github", diff --git a/web/oauth-policy.html b/web/oauth-policy.html new file mode 100644 index 00000000..1ed0d17c --- /dev/null +++ b/web/oauth-policy.html @@ -0,0 +1,84 @@ + +
+ Umputun operates the website remark42.com, which provides the SERVICE. This page is used to inform website visitors regarding + our policies with the collection, use, and disclosure of Personal Information if anyone decided to use our Service. + If you choose to use our Service, then you agree to the collection and use of information in relation with this policy. + The Personal Information that we collect are used for providing and improving the Service. We will not use or share + your information with anyone except as described in this Privacy Policy. +
++ The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at https://remark42.com, + unless otherwise defined in this Privacy Policy. +
++ For a better experience while using our Service, we may require you to provide us with certain personally identifiable information, + including but not limited to your name and email addres. The information that we collect will be used to contact + or identify you. +
+ +We want to inform you that whenever you visit our Service, we collect information that your browser sends to us that + is called Log Data. This Log Data may include information such as your computer’s Internet Protocol (“IP”) address, + browser version, pages of our Service that you visit, the time and date of your visit, the time spent on those pages, + and other statistics. +
+ +Cookies are files with small amount of data that is commonly used an anonymous unique identifier. These are sent to your + browser from the website that you visit and are stored on your computer’s hard drive. Our website uses these “cookies” + to comnfirm user identity. You have the option to either accept or refuse these cookies, and know when a cookie is + being sent to your computer. If you choose to refuse our cookies, you may not be able to use some portions of our + Service. +
+ ++ We may employ third-party companies and individuals due to the following reasons: +
+ We want to inform our Service users that these third parties have access to your Personal Information. The reason is to perform + the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for + any other purpose. +
+ ++ We value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means + of protecting it. But remember that no method of transmission over the internet, or method of electronic storage + is 100% secure and reliable, and we cannot guarantee its absolute security. Links to Other Sites Our Service may + contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these + external sites are not operated by us. Therefore, we strongly advise you to review the Privacy Policy of these websites, + read more. We have no control over, and assume no responsibility for the content, privacy policies, or practices + of any third-party sites or services. +
+ ++ Our Services do not address anyone under the age of 13. We do not knowingly collect personal identifiable information from + children under 13. In the case we discover that a child under 13 has provided us with personal information, we immediately + delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with + personal information, please contact us so that we will be able to do necessary actions. +
+ ++ We may update our Privacy Policy from time to time. Thus, we advise you to review this page periodically for any changes. + We will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately, + after they are posted on this page. +
+ +If you have any questions or suggestions about our Privacy Policy, do not hesitate to contact us.
+ + + \ No newline at end of file