Skip to content

Commit

Permalink
Merge pull request thomiceli#13 from thomiceli/feature/oauth
Browse files Browse the repository at this point in the history
Adding Github & Gitea OAuth provider
  • Loading branch information
thomiceli committed Apr 17, 2023
2 parents 149f5fd + 3b5fbcd commit 8df3be7
Show file tree
Hide file tree
Showing 14 changed files with 762 additions and 21 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ A self-hosted pastebin **powered by Git**. [Try it here](https://opengist.thomic
* [Administration](#administration)
* [Use Nginx as a reverse proxy](#use-nginx-as-a-reverse-proxy)
* [Use Fail2ban](#use-fail2ban)
* [Configure OAuth](#configure-oauth)
* [License](#license)

## Features
Expand Down Expand Up @@ -170,6 +171,37 @@ Then run
```shell
service fail2ban restart
```

## Configure OAuth

Opengist can be configured to use OAuth to authenticate users, with GitHub or Gitea.

<details>
<summary>Integrate Github</summary>

* Add a new OAuth app in your [Github account settings](https://github.com/settings/applications/new)
* Set 'Authorization callback URL' to `http:https://opengist.domain/oauth/github/callback`
* Copy the 'Client ID' and 'Client Secret' and add them to the `config.yml` file :
```yaml
github.client-key: <key>
github.secret: <secret>
```
</details>

<details>
<summary>Integrate Gitea</summary>

* Add a new OAuth app in Application settings from the [Gitea instance](https://gitea.com/user/settings/applications)
* Set 'Redirect URI' to `http:https://opengist.domain/oauth/gitea/callback`
* Copy the 'Client ID' and 'Client Secret' and add them to the `config.yml` file :
```yaml
gitea.client-key: <key>
gitea.secret: <secret>
# URL of the Gitea instance. Default: https://gitea.com/
gitea.url: http:https://localhost:3000
```
</details>

## License

Opengist is licensed under the [AGPL-3.0 license](LICENSE).
14 changes: 14 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,17 @@ ssh.external-domain:

# Path or alias to ssh-keygen executable. Default: ssh-keygen
ssh.keygen-executable: ssh-keygen


# OAuth2 configuration
# The callback/redirect URL must be http:https://opengist.domain/oauth/<github|gitea>/callback

# To create a new OAuth2 application using GitHub : https://github.com/settings/applications/new
github.client-key:
github.secret:

# To create a new OAuth2 application using Gitea : https://gitea.domain/user/settings/applications
gitea.client-key:
gitea.secret:
# URL of the Gitea instance. Default: https://gitea.com/
gitea.url: https://gitea.com/
9 changes: 8 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ require (
github.com/google/uuid v1.3.0
github.com/gorilla/sessions v1.2.1
github.com/labstack/echo/v4 v4.10.0
github.com/markbates/goth v1.77.0
github.com/mattn/go-sqlite3 v1.14.13
github.com/rs/zerolog v1.29.0
golang.org/x/crypto v0.2.0
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -18,18 +20,23 @@ require (
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/protobuf v1.4.2 // indirect
github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/mux v1.6.2 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-sqlite3 v1.14.13 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/time v0.2.0 // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.25.0 // indirect
)
388 changes: 388 additions & 0 deletions go.sum

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ type config struct {
SshPort string `yaml:"ssh.port"`
SshExternalDomain string `yaml:"ssh.external-domain"`
SshKeygen string `yaml:"ssh.keygen-executable"`

GithubClientKey string `yaml:"github.client-key"`
GithubSecret string `yaml:"github.secret"`

GiteaClientKey string `yaml:"gitea.client-key"`
GiteaSecret string `yaml:"gitea.secret"`
GiteaUrl string `yaml:"gitea.url"`
}

func configWithDefaults() (*config, error) {
Expand All @@ -58,6 +65,8 @@ func configWithDefaults() (*config, error) {
c.SshPort = "2222"
c.SshKeygen = "ssh-keygen"

c.GiteaUrl = "http:https://gitea.com"

return c, nil
}

Expand Down
12 changes: 1 addition & 11 deletions internal/models/admin_setting.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package models

import (
"errors"
"github.com/mattn/go-sqlite3"
"gorm.io/gorm/clause"
)

Expand Down Expand Up @@ -38,19 +36,11 @@ func setSetting(key string, value string) error {
func initAdminSettings(settings map[string]string) error {
for key, value := range settings {
if err := setSetting(key, value); err != nil {
if !isUniqueConstraintViolation(err) {
if !IsUniqueConstraintViolation(err) {
return err
}
}
}

return nil
}

func isUniqueConstraintViolation(err error) bool {
var sqliteErr sqlite3.Error
if errors.As(err, &sqliteErr) && sqliteErr.ExtendedCode == sqlite3.ErrConstraintUnique {
return true
}
return false
}
10 changes: 10 additions & 0 deletions internal/models/db.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package models

import (
"errors"
"github.com/mattn/go-sqlite3"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
Expand Down Expand Up @@ -32,3 +34,11 @@ func CountAll(table interface{}) (int64, error) {
err := db.Model(table).Count(&count).Error
return count, err
}

func IsUniqueConstraintViolation(err error) bool {
var sqliteErr sqlite3.Error
if errors.As(err, &sqliteErr) && sqliteErr.ExtendedCode == sqlite3.ErrConstraintUnique {
return true
}
return false
}
18 changes: 17 additions & 1 deletion internal/models/sshkey.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package models

import "time"
import (
"crypto/sha256"
"encoding/base64"
"golang.org/x/crypto/ssh"
"gorm.io/gorm"
"time"
)

type SSHKey struct {
ID uint `gorm:"primaryKey"`
Expand All @@ -13,6 +19,16 @@ type SSHKey struct {
User User `validate:"-" `
}

func (sshKey *SSHKey) BeforeCreate(tx *gorm.DB) error {
pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey.Content))
if err != nil {
return err
}
sha := sha256.Sum256(pubKey.Marshal())
sshKey.SHA = base64.StdEncoding.EncodeToString(sha[:])
return nil
}

func GetSSHKeysByUserID(userId uint) ([]*SSHKey, error) {
var sshKeys []*SSHKey
err := db.
Expand Down
26 changes: 26 additions & 0 deletions internal/models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ type User struct {
CreatedAt int64
Email string
MD5Hash string // for gravatar, if no Email is specified, the value is random
GithubID string
GiteaID string

Gists []Gist `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;foreignKey:UserID"`
SSHKeys []SSHKey `gorm:"foreignKey:UserID"`
Expand Down Expand Up @@ -90,6 +92,19 @@ func GetUserBySSHKeyID(sshKeyId uint) (*User, error) {
return user, err
}

func GetUserByProvider(id string, provider string) (*User, error) {
user := new(User)
var err error
switch provider {
case "github":
err = db.Where("github_id = ?", id).First(&user).Error
case "gitea":
err = db.Where("gitea_id = ?", id).First(&user).Error
}

return user, err
}

func (user *User) Create() error {
return db.Create(&user).Error
}
Expand Down Expand Up @@ -118,6 +133,17 @@ func (user *User) HasLiked(gist *Gist) (bool, error) {
return true, nil
}

func (user *User) DeleteProviderID(provider string) error {
switch provider {
case "github":
return db.Model(&user).Update("github_id", nil).Error
case "gitea":
return db.Model(&user).Update("gitea_id", nil).Error
}

return nil
}

// -- DTO -- //

type UserDTO struct {
Expand Down
Loading

0 comments on commit 8df3be7

Please sign in to comment.