aboutsummaryrefslogblamecommitdiff
path: root/api.go
blob: 9f3ef7b1524d2be5c4b86d0da83348f4bd029754 (plain) (tree)
1
2
3
4
5
6
7



                   
                
             
                                                                     






                                    
                                                                                  



                                                                                               
                                                                                        












                                                                                      
                                                                        





                                                                                               
                                                                                                          

































                                                                                      
                                                                                                              




                                                                                      
                                                                                                                                     


















                                                                                                                   









                                                                                                        


                                                                    
                                                     



                                

                                 


              
package main

import (
	//"context"
	"errors"
	"fmt"
	garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
	"github.com/go-ldap/ldap/v3"
	//"github.com/gorilla/mux"
	"log"
	"net/http"
	"strings"
)

func checkLoginAPI(w http.ResponseWriter, r *http.Request) (*LoginStatus, error) {
	username, password, ok := r.BasicAuth()
	if !ok {
		w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return nil, errors.New("Missing or invalid 'Authenticate: Basic' field")
	}
	user_dn := buildUserDN(username)

	login_info := &LoginInfo{
		DN:       user_dn,
		Username: username,
		Password: password,
	}

	l := ldapOpen(w)
	if l == nil {
		log.Println(l)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return nil, errors.New("Unable to open LDAP connection")
	}

	err := l.Bind(login_info.DN, login_info.Password)
	if err != nil {
		w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return nil, errors.New("Unable to bind this user+password combination on the LDAP server")
	}

	loginStatus := &LoginStatus{
		Info: login_info,
		conn: l,
	}

	requestKind := "(objectClass=organizationalPerson)"

	if strings.EqualFold(login_info.DN, config.AdminAccount) {
		requestKind = "(objectclass=*)"
	}
	searchRequest := ldap.NewSearchRequest(
		login_info.DN,
		ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
		requestKind,
		[]string{
			"dn",
			"displayname",
			"givenname",
			"sn",
			"mail",
			"memberof",
			"description",
			"garage_s3_access_key",
			FIELD_NAME_DIRECTORY_VISIBILITY,
			FIELD_NAME_PROFILE_PICTURE,
		},
		nil)

	sr, err := l.Search(searchRequest)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return nil, errors.New("Unable to search essential information about the logged user on LDAP")
	}

	if len(sr.Entries) != 1 {
		log.Println(fmt.Sprintf("Unable to find entry for %s", login_info.DN))
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return nil, errors.New("Not enough or too many entries for this user in the LDAP directory (expect a unique result)")
	}

	loginStatus.UserEntry = sr.Entries[0]

	loginStatus.CanAdmin = strings.EqualFold(loginStatus.Info.DN, config.AdminAccount)
	loginStatus.CanInvite = false
	for _, attr := range loginStatus.UserEntry.Attributes {
		if strings.EqualFold(attr.Name, "memberof") {
			for _, group := range attr.Values {
				if config.GroupCanInvite != "" && strings.EqualFold(group, config.GroupCanInvite) {
					loginStatus.CanInvite = true
				}
				if config.GroupCanAdmin != "" && strings.EqualFold(group, config.GroupCanAdmin) {
					loginStatus.CanAdmin = true
				}
			}
		}
	}

	return loginStatus, nil
}

func checkLoginAndS3API(w http.ResponseWriter, r *http.Request) (*LoginStatus, *garage.KeyInfo, error) {
	login, err := checkLoginAPI(w, r)
	if err != nil {
		return nil, nil, err
	}
	keyPair, err := checkS3(login)
	return login, keyPair, err
}

func handleAPIGarageBucket(w http.ResponseWriter, r *http.Request) {
	login, s3key, err := checkLoginAndS3API(w, r)
	if err != nil {
		log.Println(err)
		return
	}

	log.Println(login, s3key)

	return
}