Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,51 @@ A list of changes can be seen in the [CHANGELOG](CHANGELOG.md).

![Sign In Page](https://cloud.githubusercontent.com/assets/45028/4970624/7feb7dd8-6886-11e4-93e0-c9904af44ea8.png)

## Epitech Fork

This fork adds support for an Epitech provider, based on AzureAD and Epitech Intranet groups.

Enjoy ;)

### Build

```
docker build -t samber/epitech-oauth2-proxy:4.0.0 .
```

### Setup

1- Register a new webapp here => https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app

2- Copy Tenant ID + Client ID

3- Navigate to the "Certificates & secrets" page and create a new "client secret".

4- Navigate to "Authentication" page and set the redirect url to `http://localhost:80/oauth2/callback`

5- Navigate to "Manifest" page and set `groupMembershipClaims` to `All`.

```
docker run -d -p 80:80 -p 443:443 \
samber/epitech-oauth2-proxy \
-upstream=http://very-private-webapp:80 \
-http-address=0.0.0.0:80 \
-redirect-url=http://localhost:80/oauth2/callback \
-scope='profile User.Read' \
-email-domain=* \
-cookie-domain=localhost \
-cookie-secure=false \
-cookie-secret=somerandomstring1234567890 \
-provider=epitech \
-azure-tenant ******************************** \
-client-id ****************************** \
-client-secret '****************************' \
-epitech-group adm -epitech-group dpr -epitech-group dpra -epitech-group ape \
-epitech-auth-token auth-***********************
```

⚠️ For prod environment, remove the `-cookie-secure=false` argument ;)

## Installation

1. Choose how to deploy:
Expand Down
22 changes: 14 additions & 8 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
coffee-script (2.4.1)
coffee-script-source
execjs
Expand All @@ -16,8 +16,8 @@ GEM
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.4)
dnsruby (1.61.2)
addressable (~> 2.5)
dnsruby (1.61.9)
simpleidn (~> 0.1)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
Expand Down Expand Up @@ -210,7 +210,8 @@ GEM
multipart-post (2.0.0)
nokogiri (1.10.4)
mini_portile2 (~> 2.4.0)
octokit (4.13.0)
octokit (4.22.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
Expand All @@ -230,16 +231,21 @@ GEM
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sawyer (0.8.1)
addressable (>= 2.3.5, < 2.6)
faraday (~> 0.8, < 1.0)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
simpleidn (0.2.1)
unf (~> 0.1.4)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
typhoeus (1.3.1)
ethon (>= 0.9.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (1.4.1)

PLATFORMS
Expand Down
7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func main() {
skipAuthRegex := StringArray{}
jwtIssuers := StringArray{}
googleGroups := StringArray{}
epitechGroups := StringArray{} // CUSTOM EPITECH
redisSentinelConnectionURLs := StringArray{}

config := flagSet.String("config", "", "path to config file")
Expand Down Expand Up @@ -129,6 +130,12 @@ func main() {
flagSet.String("pubjwk-url", "", "JWK pubkey access endpoint: required by login.gov")
flagSet.Bool("gcp-healthchecks", false, "Enable GCP/GKE healthcheck endpoints")

/*
* CUSTOM EPITECH
*/
flagSet.String("epitech-auth-token", "", "Auto-login token (format: auth-*****************).")
flagSet.Var(&epitechGroups, "epitech-group", "restrict logins to members of this Epitech Intranet group (may be given multiple times).")

flagSet.Parse(os.Args[1:])

if *showVersion {
Expand Down
8 changes: 8 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ type Options struct {
signatureData *SignatureData
oidcVerifier *oidc.IDTokenVerifier
jwtBearerVerifiers []*oidc.IDTokenVerifier

/*
* CUSTOM EPITECH
*/
EpitechAuthToken string `flag:"epitech-auth-token" cfg:"epitech_auth_token" env:"OAUTH2_PROXY_EPITECH_AUTH_TOKEN"`
EpitechGroups []string `flag:"epitech-group" cfg:"epitech_group" env:"OAUTH2_PROXY_EPITECH_GROUPS"`
}

// SignatureData holds hmacauth signature hash and key
Expand Down Expand Up @@ -394,6 +400,8 @@ func parseProviderInfo(o *Options, msgs []string) []string {

o.provider = providers.New(o.Provider, p)
switch p := o.provider.(type) {
case *providers.EpitechProvider:
p.Configure(o.AzureTenant, o.EpitechAuthToken, o.EpitechGroups)
case *providers.AzureProvider:
p.Configure(o.AzureTenant)
case *providers.GitHubProvider:
Expand Down
109 changes: 109 additions & 0 deletions pkg/http_cache/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package http_cache

import (
"bufio"
"bytes"
"errors"
"net/http"
"net/http/httputil"
"sync"
"time"
)

func NewCacheTransport(originalTransport http.RoundTripper, seconds int) *CacheTransport {
transport := &CacheTransport{
data: make(map[string]string),
originalTransport: originalTransport,
}

cacheClearJob(seconds, transport)

return transport
}

func cacheClearJob(seconds int, transport *CacheTransport) {

interval := time.Duration(seconds) * time.Second
ticker := time.NewTicker(interval)

go func() {
for {

select {
case <-ticker.C:
transport.Clear()
}
}
}()
}

func cacheKey(r *http.Request) string {
return r.URL.String()
}

type CacheTransport struct {
data map[string]string
mu sync.RWMutex
originalTransport http.RoundTripper
}

func (c *CacheTransport) Set(r *http.Request, value string) {
c.mu.Lock()
defer c.mu.Unlock()
c.data[cacheKey(r)] = value
}

func (c *CacheTransport) Get(r *http.Request) (string, error) {
c.mu.RLock()
defer c.mu.RUnlock()

if val, ok := c.data[cacheKey(r)]; ok {
return val, nil
}

return "", errors.New("key not found in cache")
}

// Here is the main functionality
func (c *CacheTransport) RoundTrip(r *http.Request) (*http.Response, error) {

// Check if we have the response cached..
// If yes, we don't have to hit the server
// We just return it as is from the cache store.
if val, err := c.Get(r); err == nil {
return cachedResponse([]byte(val), r)
}

// Ok, we don't have the response cached, the store was probably cleared.
// Make the request to the server.
resp, err := c.originalTransport.RoundTrip(r)

if err != nil {
return nil, err
}

// Get the body of the response so we can save it in the cache for the next request.
buf, err := httputil.DumpResponse(resp, true)

if err != nil {
return nil, err
}

// Saving it to the cache store
c.Set(r, string(buf))

return resp, nil
}

func (c *CacheTransport) Clear() error {
c.mu.Lock()
defer c.mu.Unlock()

c.data = make(map[string]string)
return nil
}

func cachedResponse(b []byte, r *http.Request) (*http.Response, error) {
buf := bytes.NewBuffer(b)
return http.ReadResponse(bufio.NewReader(buf), r)
}
Loading