func (dbc *DbDriver) CanLogin(username string, password string) bool { log.Printf("INFO: Authenticate user %s", username) if acl.Username(username) == acl.Anonymous { return true } var passwd string err := dbc.db.QueryRow("select token from t_users where name = ?", username).Scan(&passwd) switch { case err == sql.ErrNoRows: log.Printf("INFO: unknown user %s", username) return false case err != nil: log.Printf("ERROR: %v", err) return false default: if passwd == password { log.Printf("INFO: %s has correct passwod", username) return true } else { log.Printf("INFO: %s has wrong passwod", username) return false } } }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { username, password, ok := req.BasicAuth() if ok { if c.authReq.Account != "" && c.authReq.Account != username { http.Error(rw, "account is not same as login user", http.StatusForbidden) return } ok, err := runningContext.Acl.CanLogin(acl.Username(username), acl.Password(password)) if !ok { http.Error(rw, "", http.StatusForbidden) return } if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } // check actions for _, v := range c.authReq.Actions { p := accessMap[v] ok, err := runningContext.Acl.CanAccess(acl.Username(username), c.namespace, c.repo, p) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } } next(rw, req) return } http.Error(rw, "", http.StatusUnauthorized) }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { log.Printf("INFO: authAccess %s/%s, %v", c.namespace, c.repo, c.authReq.Actions) username, password, ok := req.BasicAuth() if c.authReq.Account != "" && c.authReq.Account != username { http.Error(rw, "account is not same as login user", http.StatusForbidden) return } var _username acl.Username if ok { _username = acl.Username(username) } else { _username = acl.Anonymous } ok, err := runningContext.Acl.CanLogin(_username, acl.Password(password)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { if _username == acl.Anonymous { http.Error(rw, "", http.StatusUnauthorized) } else { http.Error(rw, "", http.StatusForbidden) } return } // check actions for _, v := range c.permsWant { p := accessMap[v] ok, err := runningContext.Acl.CanAccess(_username, c.namespace, c.repo, p) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if ok { c.authReq.Actions = append(c.authReq.Actions, v) } } sort.Strings(c.authReq.Actions) next(rw, req) }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { // Authorization: Token signature=123,repository="library/test",access=write a, ok := req.Header["Authorization"] if ok { m := make(map[string]string) s := strings.TrimLeft(a[0], "Token ") for _, p := range strings.Split(s, ",") { kv := strings.Split(p, "=") k := kv[0] v := kv[1] m[k] = v } nr := strings.SplitN(strings.Trim(m["repository"], `"`), "/", 2) m["namespace"] = nr[0] m["repo"] = nr[1] if c.checkSignature(nr[0], nr[1], m["signature"], m["access"]) { next(rw, req) return } } // Authorization: Basic username, password, ok := req.BasicAuth() var _username acl.Username if ok { _username = acl.Username(username) } else { _username = acl.Anonymous } // TODO should move to a separate func // happens when login if c.namespace == "" || c.repo == "" { // Anonymous cant login if _username == acl.Anonymous { http.Error(rw, "", http.StatusUnauthorized) } return } ok, err := runningContext.Acl.CanLogin(_username, acl.Password(password)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { if _username == acl.Anonymous { http.Error(rw, "", http.StatusUnauthorized) } else { http.Error(rw, "", http.StatusForbidden) } return } // TODO remove this scope { a, ok := accessMap[req.Method] if !ok { http.Error(rw, "", http.StatusMethodNotAllowed) return } ok, err = runningContext.Acl.CanAccess(_username, c.namespace, c.repo, a.Permission) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } } next(rw, req) }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { username, password, ok := req.BasicAuth() if ok { a, ok := accessMap[req.Method] if !ok { http.Error(rw, "", http.StatusMethodNotAllowed) return } ok, err := runningContext.Acl.CanLogin(acl.Username(username), acl.Password(password)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } ok, err = runningContext.Acl.CanAccess(acl.Username(username), c.namespace, c.repo, a.Permission) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } next(rw, req) return } // Authorization: Token signature=123,repository="library/test",access=write a, ok := req.Header["Authorization"] if ok { m := make(map[string]string) s := strings.TrimLeft(a[0], "Token ") for _, p := range strings.Split(s, ",") { kv := strings.Split(p, "=") k := kv[0] v := kv[1] m[k] = v } nr := strings.SplitN(strings.Trim(m["repository"], `"`), "/", 2) m["namespace"] = nr[0] m["repo"] = nr[1] if c.checkSignature(nr[0], nr[1], m["signature"], m["access"]) { next(rw, req) return } } http.Error(rw, "", http.StatusUnauthorized) }